summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/Cargo.lock136
-rw-r--r--src/bootstrap/Cargo.toml7
-rw-r--r--src/bootstrap/bin/main.rs2
-rw-r--r--src/bootstrap/bin/rustc.rs8
-rw-r--r--src/bootstrap/bin/rustdoc.rs8
-rw-r--r--src/bootstrap/bootstrap.py1
-rw-r--r--src/bootstrap/builder.rs301
-rw-r--r--src/bootstrap/builder/tests.rs4
-rw-r--r--src/bootstrap/cache.rs8
-rw-r--r--src/bootstrap/cc_detect.rs21
-rw-r--r--src/bootstrap/channel.rs3
-rw-r--r--src/bootstrap/check.rs8
-rw-r--r--src/bootstrap/compile.rs61
-rw-r--r--src/bootstrap/config.rs418
-rw-r--r--src/bootstrap/dist.rs93
-rw-r--r--src/bootstrap/doc.rs194
-rw-r--r--src/bootstrap/download.rs520
-rw-r--r--src/bootstrap/flags.rs34
-rw-r--r--src/bootstrap/format.rs2
-rw-r--r--src/bootstrap/install.rs12
-rw-r--r--src/bootstrap/lib.rs215
-rw-r--r--src/bootstrap/metrics.rs2
-rw-r--r--src/bootstrap/native.rs102
-rw-r--r--src/bootstrap/run.rs131
-rw-r--r--src/bootstrap/sanity.rs29
-rw-r--r--src/bootstrap/setup.rs91
-rw-r--r--src/bootstrap/tarball.rs4
-rw-r--r--src/bootstrap/test.rs168
-rw-r--r--src/bootstrap/tool.rs34
-rw-r--r--src/bootstrap/toolstate.rs4
-rw-r--r--src/bootstrap/util.rs26
-rw-r--r--src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/armhf-gnu/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile11
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh8
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile9
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh26
-rw-r--r--src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/i686-gnu/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile8
-rw-r--r--src/ci/docker/host-x86_64/test-various/Dockerfile26
-rw-r--r--src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml9
-rw-r--r--src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py142
-rw-r--r--src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs45
-rw-r--r--src/ci/docker/host-x86_64/wasm32/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile11
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile3
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile8
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh5
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile3
-rwxr-xr-xsrc/ci/docker/scripts/freebsd-toolchain.sh2
-rwxr-xr-xsrc/ci/docker/scripts/fuchsia-test-runner.py1041
-rwxr-xr-xsrc/ci/run.sh9
-rwxr-xr-xsrc/ci/scripts/checkout-submodules.sh15
-rw-r--r--src/doc/book/.github/ISSUE_TEMPLATE/bug_report.md8
-rw-r--r--src/doc/book/.github/workflows/main.yml8
-rw-r--r--src/doc/book/README.md2
-rw-r--r--src/doc/book/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt5
-rw-r--r--src/doc/book/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt10
-rw-r--r--src/doc/book/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt7
-rw-r--r--src/doc/book/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt4
-rw-r--r--src/doc/book/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt2
-rw-r--r--src/doc/book/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt2
-rw-r--r--src/doc/book/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt2
-rw-r--r--src/doc/book/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt4
-rw-r--r--src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs4
-rw-r--r--src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs4
-rw-r--r--src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs4
-rw-r--r--src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs4
-rw-r--r--src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt2
-rw-r--r--src/doc/book/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt2
-rw-r--r--src/doc/book/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt20
-rw-r--r--src/doc/book/listings/ch08-common-collections/listing-08-06/output.txt8
-rw-r--r--src/doc/book/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt2
-rw-r--r--src/doc/book/listings/ch09-error-handling/listing-09-10/output.txt9
-rw-r--r--src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt2
-rw-r--r--src/doc/book/listings/ch11-writing-automated-tests/listing-11-03/output.txt2
-rw-r--r--src/doc/book/listings/ch11-writing-automated-tests/listing-11-10/output.txt2
-rw-r--r--src/doc/book/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt2
-rw-r--r--src/doc/book/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt2
-rw-r--r--src/doc/book/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt2
-rw-r--r--src/doc/book/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt2
-rw-r--r--src/doc/book/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt2
-rw-r--r--src/doc/book/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt2
-rw-r--r--src/doc/book/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt2
-rw-r--r--src/doc/book/listings/ch12-an-io-project/listing-12-16/output.txt2
-rw-r--r--src/doc/book/listings/ch13-functional-features/listing-13-03/output.txt13
-rw-r--r--src/doc/book/listings/ch13-functional-features/listing-13-08/output.txt17
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt14
-rw-r--r--src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt2
-rw-r--r--src/doc/book/listings/ch16-fearless-concurrency/listing-16-09/output.txt2
-rw-r--r--src/doc/book/listings/ch16-fearless-concurrency/listing-16-14/output.txt34
-rw-r--r--src/doc/book/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt2
-rw-r--r--src/doc/book/listings/ch17-oop/listing-17-10/output.txt2
-rw-r--r--src/doc/book/listings/ch18-patterns-and-matching/listing-18-08/output.txt22
-rw-r--r--src/doc/book/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs10
-rw-r--r--src/doc/book/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs6
-rw-r--r--src/doc/book/listings/ch19-advanced-features/listing-19-20/output.txt14
-rw-r--r--src/doc/book/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt2
-rw-r--r--src/doc/book/listings/ch20-web-server/listing-20-22/output.txt14
-rw-r--r--src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt6
-rw-r--r--src/doc/book/rust-toolchain2
-rw-r--r--src/doc/book/src/ch05-00-structs.md2
-rw-r--r--src/doc/book/src/ch05-01-defining-structs.md76
-rw-r--r--src/doc/book/src/ch05-02-example-structs.md34
-rw-r--r--src/doc/book/src/ch05-03-method-syntax.md102
-rw-r--r--src/doc/book/src/ch06-00-enums.md4
-rw-r--r--src/doc/book/src/ch06-01-defining-an-enum.md58
-rw-r--r--src/doc/book/src/ch06-02-match.md80
-rw-r--r--src/doc/book/src/ch06-03-if-let.md14
-rw-r--r--src/doc/book/src/title-page.md2
-rw-r--r--src/doc/embedded-book/src/intro/install/linux.md5
-rw-r--r--src/doc/embedded-book/src/intro/no-std.md4
-rw-r--r--src/doc/embedded-book/src/peripherals/singletons.md2
-rw-r--r--src/doc/embedded-book/src/start/hardware.md2
-rw-r--r--src/doc/nomicon/src/lifetime-mismatch.md2
-rw-r--r--src/doc/nomicon/src/unchecked-uninit.md13
-rw-r--r--src/doc/nomicon/src/vec/vec-alloc.md1
-rw-r--r--src/doc/nomicon/src/vec/vec-final.md2
-rw-r--r--src/doc/nomicon/src/vec/vec-insert-remove.md16
-rw-r--r--src/doc/nomicon/src/vec/vec-into-iter.md14
-rw-r--r--src/doc/nomicon/src/vec/vec-layout.md19
-rw-r--r--src/doc/nomicon/src/vec/vec-raw.md2
-rw-r--r--src/doc/nomicon/src/vec/vec-zsts.md5
-rw-r--r--src/doc/reference/src/attributes.md2
-rw-r--r--src/doc/reference/src/attributes/codegen.md23
-rw-r--r--src/doc/reference/src/behavior-considered-undefined.md18
-rw-r--r--src/doc/reference/src/comments.md2
-rw-r--r--src/doc/reference/src/expressions/literal-expr.md18
-rw-r--r--src/doc/reference/src/items/extern-crates.md7
-rw-r--r--src/doc/reference/src/items/external-blocks.md17
-rw-r--r--src/doc/reference/src/items/generics.md2
-rw-r--r--src/doc/reference/src/macros-by-example.md2
-rw-r--r--src/doc/reference/src/special-types-and-traits.md2
-rw-r--r--src/doc/reference/src/tokens.md147
-rw-r--r--src/doc/reference/src/trait-bounds.md2
-rw-r--r--src/doc/rust-by-example/.github/workflows/rbe.yml2
-rw-r--r--src/doc/rust-by-example/src/crates/using_lib.md2
-rw-r--r--src/doc/rust-by-example/src/fn/closures.md22
-rw-r--r--src/doc/rust-by-example/src/fn/closures/input_parameters.md2
-rw-r--r--src/doc/rust-by-example/src/hello/print.md2
-rw-r--r--src/doc/rust-by-example/src/scope/lifetime.md2
-rw-r--r--src/doc/rust-by-example/src/std_misc/file/read_lines.md34
-rw-r--r--src/doc/rust-by-example/src/types/cast.md20
-rw-r--r--src/doc/rust-by-example/triagebot.toml3
-rw-r--r--src/doc/rustc-dev-guide/src/asm.md44
-rw-r--r--src/doc/rustc-dev-guide/src/backend/monomorph.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/updating-llvm.md188
-rw-r--r--src/doc/rustc-dev-guide/src/bug-fix-procedure.md8
-rw-r--r--src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md4
-rw-r--r--src/doc/rustc-dev-guide/src/building/suggested.md11
-rw-r--r--src/doc/rustc-dev-guide/src/closure.md4
-rw-r--r--src/doc/rustc-dev-guide/src/compiler-team.md14
-rw-r--r--src/doc/rustc-dev-guide/src/constants.md2
-rw-r--r--src/doc/rustc-dev-guide/src/contributing.md18
-rw-r--r--src/doc/rustc-dev-guide/src/conventions.md2
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md20
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/lintstore.md5
-rw-r--r--src/doc/rustc-dev-guide/src/getting-started.md2
-rw-r--r--src/doc/rustc-dev-guide/src/macro-expansion.md84
-rw-r--r--src/doc/rustc-dev-guide/src/mir/dataflow.md2
-rw-r--r--src/doc/rustc-dev-guide/src/mir/drop-elaboration.md2
-rw-r--r--src/doc/rustc-dev-guide/src/overview.md2
-rw-r--r--src/doc/rustc-dev-guide/src/parallel-rustc.md4
-rw-r--r--src/doc/rustc-dev-guide/src/part-5-intro.md6
-rw-r--r--src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md10
-rw-r--r--src/doc/rustc-dev-guide/src/query.md81
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals.md2
-rw-r--r--src/doc/rustc-dev-guide/src/salsa.md2
-rw-r--r--src/doc/rustc-dev-guide/src/stability.md10
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ui.md4
-rw-r--r--src/doc/rustc-dev-guide/src/traits/resolution.md2
-rw-r--r--src/doc/rustc-dev-guide/src/traits/specialization.md2
-rw-r--r--src/doc/rustc-dev-guide/src/ty-fold.md2
-rw-r--r--src/doc/rustc-dev-guide/src/type-inference.md30
-rw-r--r--src/doc/rustc/src/SUMMARY.md2
-rw-r--r--src/doc/rustc/src/codegen-options/index.md10
-rw-r--r--src/doc/rustc/src/command-line-arguments.md27
-rw-r--r--src/doc/rustc/src/linker-plugin-lto.md94
-rw-r--r--src/doc/rustc/src/platform-support.md11
-rw-r--r--src/doc/rustc/src/platform-support/fuchsia.md113
-rw-r--r--src/doc/rustc/src/platform-support/mipsel-sony-psx.md49
-rw-r--r--src/doc/rustc/src/platform-support/nto-qnx.md118
-rw-r--r--src/doc/rustc/src/platform-support/unknown-uefi.md38
-rw-r--r--src/doc/rustc/src/target-tier-policy.md27
-rw-r--r--src/doc/rustdoc/book.toml4
-rw-r--r--src/doc/rustdoc/src/lints.md2
-rw-r--r--src/doc/style-guide/src/principles.md4
-rw-r--r--src/doc/unstable-book/src/language-features/abi-efiapi.md23
-rw-r--r--src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md10
-rw-r--r--src/doc/unstable-book/src/language-features/native-link-modifiers-verbatim.md20
-rw-r--r--src/etc/gdb_providers.py8
-rw-r--r--src/etc/lldb_providers.py12
-rw-r--r--src/etc/natvis/intrinsic.natvis12
-rw-r--r--src/etc/natvis/liballoc.natvis23
-rw-r--r--src/librustdoc/Cargo.toml5
-rw-r--r--src/librustdoc/clean/auto_trait.rs28
-rw-r--r--src/librustdoc/clean/blanket_impl.rs12
-rw-r--r--src/librustdoc/clean/cfg.rs2
-rw-r--r--src/librustdoc/clean/inline.rs55
-rw-r--r--src/librustdoc/clean/mod.rs635
-rw-r--r--src/librustdoc/clean/simplify.rs17
-rw-r--r--src/librustdoc/clean/types.rs156
-rw-r--r--src/librustdoc/clean/utils.rs52
-rw-r--r--src/librustdoc/config.rs24
-rw-r--r--src/librustdoc/core.rs7
-rw-r--r--src/librustdoc/doctest.rs21
-rw-r--r--src/librustdoc/formats/cache.rs50
-rw-r--r--src/librustdoc/html/format.rs168
-rw-r--r--src/librustdoc/html/highlight.rs6
-rw-r--r--src/librustdoc/html/highlight/fixtures/sample.html8
-rw-r--r--src/librustdoc/html/highlight/tests.rs2
-rw-r--r--src/librustdoc/html/layout.rs25
-rw-r--r--src/librustdoc/html/render/context.rs33
-rw-r--r--src/librustdoc/html/render/mod.rs265
-rw-r--r--src/librustdoc/html/render/print_item.rs174
-rw-r--r--src/librustdoc/html/render/span_map.rs10
-rw-r--r--src/librustdoc/html/render/write_shared.rs290
-rw-r--r--src/librustdoc/html/sources.rs25
-rw-r--r--src/librustdoc/html/static/css/noscript.css6
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css526
-rw-r--r--src/librustdoc/html/static/css/settings.css57
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css126
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css122
-rw-r--r--src/librustdoc/html/static/css/themes/light.css116
-rw-r--r--src/librustdoc/html/static/fonts/README.txt12
-rw-r--r--src/librustdoc/html/static/js/main.js184
-rw-r--r--src/librustdoc/html/static/js/scrape-examples.js34
-rw-r--r--src/librustdoc/html/static/js/search.js21
-rw-r--r--src/librustdoc/html/static/js/settings.js74
-rw-r--r--src/librustdoc/html/static/js/source-script.js11
-rw-r--r--src/librustdoc/html/static/js/storage.js24
-rw-r--r--src/librustdoc/html/static/scrape-examples-help.md5
-rw-r--r--src/librustdoc/html/static_files.rs263
-rw-r--r--src/librustdoc/html/templates/page.html57
-rw-r--r--src/librustdoc/html/templates/print_item.html8
-rw-r--r--src/librustdoc/json/conversions.rs56
-rw-r--r--src/librustdoc/json/mod.rs58
-rw-r--r--src/librustdoc/lib.rs28
-rw-r--r--src/librustdoc/passes/bare_urls.rs110
-rw-r--r--src/librustdoc/passes/calculate_doc_coverage.rs4
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs209
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs4
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs5
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs6
-rw-r--r--src/librustdoc/passes/lint.rs33
-rw-r--r--src/librustdoc/passes/lint/bare_urls.rs89
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs170
-rw-r--r--src/librustdoc/passes/lint/html_tags.rs (renamed from src/librustdoc/passes/html_tags.rs)309
-rw-r--r--src/librustdoc/passes/mod.rs18
-rw-r--r--src/librustdoc/passes/strip_hidden.rs1
-rw-r--r--src/librustdoc/passes/strip_priv_imports.rs4
-rw-r--r--src/librustdoc/passes/strip_private.rs4
-rw-r--r--src/librustdoc/passes/stripper.rs49
-rw-r--r--src/librustdoc/scrape_examples.rs10
-rw-r--r--src/librustdoc/visit_ast.rs112
-rw-r--r--src/librustdoc/visit_lib.rs108
-rw-r--r--src/rustdoc-json-types/lib.rs20
-rw-r--r--src/stage0.json568
-rw-r--r--src/test/assembly/asm/aarch64-el2vmsa.rs37
-rw-r--r--src/test/assembly/is_aligned.rs58
-rw-r--r--src/test/assembly/sparc-struct-abi.rs5
-rw-r--r--src/test/assembly/strict_provenance.rs37
-rw-r--r--src/test/codegen/abi-efiapi.rs2
-rw-r--r--src/test/codegen/async-fn-debug-awaitee-field.rs8
-rw-r--r--src/test/codegen/auxiliary/extern_decl.rs11
-rw-r--r--src/test/codegen/auxiliary/static_dllimport_aux.rs13
-rw-r--r--src/test/codegen/avr/avr-func-addrspace.rs16
-rw-r--r--src/test/codegen/dllimports/main.rs13
-rw-r--r--src/test/codegen/enum-bounds-check-derived-idx.rs6
-rw-r--r--src/test/codegen/enum-bounds-check-issue-13926.rs3
-rw-r--r--src/test/codegen/enum-bounds-check.rs3
-rw-r--r--src/test/codegen/enum-match.rs109
-rw-r--r--src/test/codegen/ffi-const.rs3
-rw-r--r--src/test/codegen/ffi-pure.rs3
-rw-r--r--src/test/codegen/issue-103285-ptr-addr-overflow-check.rs16
-rw-r--r--src/test/codegen/issue-37945.rs4
-rw-r--r--src/test/codegen/issue-81408-dllimport-thinlto-windows.rs15
-rw-r--r--src/test/codegen/iter-repeat-n-trivial-drop.rs56
-rw-r--r--src/test/codegen/match-optimized.rs60
-rw-r--r--src/test/codegen/match-unoptimized.rs23
-rw-r--r--src/test/codegen/match.rs29
-rw-r--r--src/test/codegen/mem-replace-direct-memcpy.rs4
-rw-r--r--src/test/codegen/naked-nocoverage.rs19
-rw-r--r--src/test/codegen/option-nonzero-eq.rs34
-rw-r--r--src/test/codegen/panic-abort-windows.rs15
-rw-r--r--src/test/codegen/repeat-trusted-len.rs7
-rw-r--r--src/test/codegen/slice-iter-len-eq-zero.rs2
-rw-r--r--src/test/codegen/static-relocation-model-msvc.rs26
-rw-r--r--src/test/codegen/unchecked_shifts.rs66
-rw-r--r--src/test/debuginfo/basic-types.rs8
-rw-r--r--src/test/debuginfo/function-names.rs2
-rw-r--r--src/test/debuginfo/lexical-scope-in-if-let.rs8
-rw-r--r--src/test/debuginfo/msvc-pretty-enums.rs6
-rw-r--r--src/test/debuginfo/msvc-scalarpair-params.rs4
-rw-r--r--src/test/debuginfo/mutex.rs2
-rw-r--r--src/test/debuginfo/pretty-std.rs8
-rw-r--r--src/test/debuginfo/rc_arc.rs8
-rw-r--r--src/test/debuginfo/result-types.rs6
-rw-r--r--src/test/debuginfo/rwlock-read.rs2
-rw-r--r--src/test/debuginfo/type-names.rs10
-rw-r--r--src/test/debuginfo/unsized.rs12
-rw-r--r--src/test/incremental/hashes/extern_mods.rs4
-rw-r--r--src/test/incremental/issue-101518.rs31
-rw-r--r--src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir542
-rw-r--r--src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir68
-rw-r--r--src/test/mir-opt/address_of.rs (renamed from src/test/mir-opt/address-of.rs)0
-rw-r--r--src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir82
-rw-r--r--src/test/mir-opt/array_index_is_temporary.rs (renamed from src/test/mir-opt/array-index-is-temporary.rs)0
-rw-r--r--src/test/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir22
-rw-r--r--src/test/mir-opt/building/custom/arbitrary_let.rs28
-rw-r--r--src/test/mir-opt/building/custom/consts.consts.built.after.mir22
-rw-r--r--src/test/mir-opt/building/custom/consts.rs36
-rw-r--r--src/test/mir-opt/building/custom/consts.statics.built.after.mir27
-rw-r--r--src/test/mir-opt/building/custom/references.immut_ref.built.after.mir14
-rw-r--r--src/test/mir-opt/building/custom/references.mut_ref.built.after.mir14
-rw-r--r--src/test/mir-opt/building/custom/references.rs43
-rw-r--r--src/test/mir-opt/building/custom/simple_assign.rs37
-rw-r--r--src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir18
-rw-r--r--src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir10
-rw-r--r--src/test/mir-opt/building/enum_cast.bar.built.after.mir (renamed from src/test/mir-opt/enum_cast.bar.mir_map.0.mir)8
-rw-r--r--src/test/mir-opt/building/enum_cast.boo.built.after.mir (renamed from src/test/mir-opt/enum_cast.boo.mir_map.0.mir)8
-rw-r--r--src/test/mir-opt/building/enum_cast.droppy.built.after.mir (renamed from src/test/mir-opt/enum_cast.droppy.mir_map.0.mir)22
-rw-r--r--src/test/mir-opt/building/enum_cast.foo.built.after.mir (renamed from src/test/mir-opt/enum_cast.foo.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/enum_cast.rs (renamed from src/test/mir-opt/enum_cast.rs)8
-rw-r--r--src/test/mir-opt/building/issue_101867.main.built.after.mir (renamed from src/test/mir-opt/issue_101867.main.mir_map.0.mir)60
-rw-r--r--src/test/mir-opt/building/issue_101867.rs (renamed from src/test/mir-opt/issue-101867.rs)2
-rw-r--r--src/test/mir-opt/building/issue_49232.main.built.after.mir (renamed from src/test/mir-opt/issue_49232.main.mir_map.0.mir)78
-rw-r--r--src/test/mir-opt/building/issue_49232.rs (renamed from src/test/mir-opt/issue-49232.rs)2
-rw-r--r--src/test/mir-opt/building/match_false_edges.full_tested_match.built.after.mir (renamed from src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir)29
-rw-r--r--src/test/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir (renamed from src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir)22
-rw-r--r--src/test/mir-opt/building/match_false_edges.main.built.after.mir (renamed from src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir)73
-rw-r--r--src/test/mir-opt/building/match_false_edges.rs (renamed from src/test/mir-opt/match_false_edges.rs)6
-rw-r--r--src/test/mir-opt/building/receiver_ptr_mutability.main.built.after.mir (renamed from src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir)132
-rw-r--r--src/test/mir-opt/building/receiver_ptr_mutability.rs (renamed from src/test/mir-opt/receiver-ptr-mutability.rs)2
-rw-r--r--src/test/mir-opt/building/simple_match.match_bool.built.after.mir (renamed from src/test/mir-opt/simple_match.match_bool.mir_map.0.mir)22
-rw-r--r--src/test/mir-opt/building/simple_match.rs (renamed from src/test/mir-opt/simple-match.rs)2
-rw-r--r--src/test/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir (renamed from src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/storage_live_dead_in_statics.rs (renamed from src/test/mir-opt/storage_live_dead_in_statics.rs)2
-rw-r--r--src/test/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir (renamed from src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir (renamed from src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir)2
-rw-r--r--src/test/mir-opt/building/uniform_array_move_out.rs (renamed from src/test/mir-opt/uniform_array_move_out.rs)4
-rw-r--r--src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff40
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir20
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff60
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BOP.built.after.mir (renamed from src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir)22
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir20
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff60
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.rs (renamed from src/test/mir-opt/const-promotion-extern-static.rs)2
-rw-r--r--src/test/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir28
-rw-r--r--src/test/mir-opt/const_prop/aggregate.rs1
-rw-r--r--src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff18
-rw-r--r--src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir4
-rw-r--r--src/test/mir-opt/const_prop/control_flow_simplification.rs (renamed from src/test/mir-opt/const_prop/control-flow-simplification.rs)0
-rw-r--r--src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff38
-rw-r--r--src/test/mir-opt/const_prop/issue_66971.rs (renamed from src/test/mir-opt/const_prop/issue-66971.rs)0
-rw-r--r--src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff40
-rw-r--r--src/test/mir-opt/const_prop/issue_67019.rs (renamed from src/test/mir-opt/const_prop/issue-67019.rs)0
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff23
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff17
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff17
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir27
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir27
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff72
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff72
-rw-r--r--src/test/mir-opt/const_prop/optimizes_into_variable.rs2
-rw-r--r--src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot2
-rw-r--r--src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot8
-rw-r--r--src/test/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff37
-rw-r--r--src/test/mir-opt/dataflow-const-prop/cast.rs7
-rw-r--r--src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff80
-rw-r--r--src/test/mir-opt/dataflow-const-prop/checked.rs13
-rw-r--r--src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff61
-rw-r--r--src/test/mir-opt/dataflow-const-prop/enum.rs13
-rw-r--r--src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff112
-rw-r--r--src/test/mir-opt/dataflow-const-prop/if.rs11
-rw-r--r--src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff45
-rw-r--r--src/test/mir-opt/dataflow-const-prop/inherit_overflow.rs8
-rw-r--r--src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff35
-rw-r--r--src/test/mir-opt/dataflow-const-prop/issue_81605.rs10
-rw-r--r--src/test/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff55
-rw-r--r--src/test/mir-opt/dataflow-const-prop/ref_without_sb.rs17
-rw-r--r--src/test/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff44
-rw-r--r--src/test/mir-opt/dataflow-const-prop/repr_transparent.rs12
-rw-r--r--src/test/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff46
-rw-r--r--src/test/mir-opt/dataflow-const-prop/self_assign.rs12
-rw-r--r--src/test/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff23
-rw-r--r--src/test/mir-opt/dataflow-const-prop/self_assign_add.rs8
-rw-r--r--src/test/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff56
-rw-r--r--src/test/mir-opt/dataflow-const-prop/sibling_ptr.rs11
-rw-r--r--src/test/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff52
-rw-r--r--src/test/mir-opt/dataflow-const-prop/struct.rs11
-rw-r--r--src/test/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff40
-rw-r--r--src/test/mir-opt/dataflow-const-prop/terminator.rs10
-rw-r--r--src/test/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff75
-rw-r--r--src/test/mir-opt/dataflow-const-prop/tuple.rs9
-rw-r--r--src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff69
-rw-r--r--src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir74
-rw-r--r--src/test/mir-opt/deref-patterns/string.rs12
-rw-r--r--src/test/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff (renamed from src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff)40
-rw-r--r--src/test/mir-opt/dest-prop/branch.rs12
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff4
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff18
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff20
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff14
-rw-r--r--src/test/mir-opt/dest-prop/copy_propagation_arg.rs5
-rw-r--r--src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff68
-rw-r--r--src/test/mir-opt/dest-prop/cycle.rs2
-rw-r--r--src/test/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir34
-rw-r--r--src/test/mir-opt/dest-prop/dead_stores_79191.rs17
-rw-r--r--src/test/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir34
-rw-r--r--src/test/mir-opt/dest-prop/dead_stores_better.rs21
-rw-r--r--src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff12
-rw-r--r--src/test/mir-opt/dest-prop/simple.rs2
-rw-r--r--src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff11
-rw-r--r--src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir88
-rw-r--r--src/test/mir-opt/exponential_or.rs (renamed from src/test/mir-opt/exponential-or.rs)0
-rw-r--r--src/test/mir-opt/fn_ptr_shim.rs (renamed from src/test/mir-opt/fn-ptr-shim.rs)0
-rw-r--r--src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir58
-rw-r--r--src/test/mir-opt/generator_drop_cleanup.rs (renamed from src/test/mir-opt/generator-drop-cleanup.rs)0
-rw-r--r--src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir122
-rw-r--r--src/test/mir-opt/generator_storage_dead_unwind.rs (renamed from src/test/mir-opt/generator-storage-dead-unwind.rs)0
-rw-r--r--src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir84
-rw-r--r--src/test/mir-opt/generator_tiny.rs (renamed from src/test/mir-opt/generator-tiny.rs)0
-rw-r--r--src/test/mir-opt/graphviz.main.built.after.dot (renamed from src/test/mir-opt/graphviz.main.mir_map.0.dot)0
-rw-r--r--src/test/mir-opt/graphviz.rs2
-rw-r--r--src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff24
-rw-r--r--src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff32
-rw-r--r--src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff76
-rw-r--r--src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff42
-rw-r--r--src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff42
-rw-r--r--src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff76
-rw-r--r--src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff42
-rw-r--r--src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff42
-rw-r--r--src/test/mir-opt/if_condition_int.rs (renamed from src/test/mir-opt/if-condition-int.rs)0
-rw-r--r--src/test/mir-opt/inline/asm_unwind.main.Inline.diff34
-rw-r--r--src/test/mir-opt/inline/asm_unwind.rs (renamed from src/test/mir-opt/inline/asm-unwind.rs)0
-rw-r--r--src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff22
-rw-r--r--src/test/mir-opt/inline/caller_with_trivial_bound.rs (renamed from src/test/mir-opt/inline/caller-with-trivial-bound.rs)0
-rw-r--r--src/test/mir-opt/inline/cycle.g.Inline.diff23
-rw-r--r--src/test/mir-opt/inline/cycle.main.Inline.diff40
-rw-r--r--src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff66
-rw-r--r--src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff18
-rw-r--r--src/test/mir-opt/inline/dyn_trait.rs (renamed from src/test/mir-opt/inline/dyn-trait.rs)0
-rw-r--r--src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff38
-rw-r--r--src/test/mir-opt/inline/exponential_runtime.main.Inline.diff50
-rw-r--r--src/test/mir-opt/inline/exponential_runtime.rs87
-rw-r--r--src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir56
-rw-r--r--src/test/mir-opt/inline/inline_any_operand.rs (renamed from src/test/mir-opt/inline/inline-any-operand.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_async.rs (renamed from src/test/mir-opt/inline/inline-async.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir78
-rw-r--r--src/test/mir-opt/inline/inline_closure.rs (renamed from src/test/mir-opt/inline/inline-closure.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir84
-rw-r--r--src/test/mir-opt/inline/inline_closure_borrows_arg.rs (renamed from src/test/mir-opt/inline/inline-closure-borrows-arg.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir110
-rw-r--r--src/test/mir-opt/inline/inline_closure_captures.rs (renamed from src/test/mir-opt/inline/inline-closure-captures.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff18
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff18
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff18
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff16
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff16
-rw-r--r--src/test/mir-opt/inline/inline_compatibility.rs (renamed from src/test/mir-opt/inline/inline-compatibility.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_cycle.one.Inline.diff29
-rw-r--r--src/test/mir-opt/inline/inline_cycle.rs (renamed from src/test/mir-opt/inline/inline-cycle.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_cycle.two.Inline.diff67
-rw-r--r--src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff31
-rw-r--r--src/test/mir-opt/inline/inline_cycle_generic.rs (renamed from src/test/mir-opt/inline/inline-cycle-generic.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_diverging.f.Inline.diff18
-rw-r--r--src/test/mir-opt/inline/inline_diverging.g.Inline.diff46
-rw-r--r--src/test/mir-opt/inline/inline_diverging.h.Inline.diff102
-rw-r--r--src/test/mir-opt/inline/inline_diverging.rs (renamed from src/test/mir-opt/inline/inline-diverging.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_generator.main.Inline.diff152
-rw-r--r--src/test/mir-opt/inline/inline_generator.rs (renamed from src/test/mir-opt/inline/inline-generator.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff54
-rw-r--r--src/test/mir-opt/inline/inline_instruction_set.rs (renamed from src/test/mir-opt/inline/inline-instruction-set.rs)11
-rw-r--r--src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff56
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff68
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.rs (renamed from src/test/mir-opt/inline/inline-into-box-place.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_options.main.Inline.after.mir54
-rw-r--r--src/test/mir-opt/inline/inline_options.rs (renamed from src/test/mir-opt/inline/inline-options.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir108
-rw-r--r--src/test/mir-opt/inline/inline_retag.rs (renamed from src/test/mir-opt/inline/inline-retag.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_shims.clone.Inline.diff20
-rw-r--r--src/test/mir-opt/inline/inline_shims.drop.Inline.diff48
-rw-r--r--src/test/mir-opt/inline/inline_shims.rs (renamed from src/test/mir-opt/inline/inline-shims.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_specialization.main.Inline.diff22
-rw-r--r--src/test/mir-opt/inline/inline_specialization.rs (renamed from src/test/mir-opt/inline/inline-specialization.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_trait_method.rs (renamed from src/test/mir-opt/inline/inline-trait-method.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir18
-rw-r--r--src/test/mir-opt/inline/inline_trait_method_2.rs (renamed from src/test/mir-opt/inline/inline-trait-method_2.rs)0
-rw-r--r--src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir34
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir32
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir32
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir24
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir24
-rw-r--r--src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs (renamed from src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs)0
-rw-r--r--src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir60
-rw-r--r--src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.rs (renamed from src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs)0
-rw-r--r--src/test/mir-opt/inline/issue_78442.bar.Inline.diff72
-rw-r--r--src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff56
-rw-r--r--src/test/mir-opt/inline/issue_78442.rs (renamed from src/test/mir-opt/inline/issue-78442.rs)0
-rw-r--r--src/test/mir-opt/inline/polymorphic_recursion.rs (renamed from src/test/mir-opt/inline/polymorphic-recursion.rs)0
-rw-r--r--src/test/mir-opt/issue_101973.inner.ConstProp.diff129
-rw-r--r--src/test/mir-opt/issue_101973.rs (renamed from src/test/mir-opt/issue-101973.rs)0
-rw-r--r--src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir56
-rw-r--r--src/test/mir-opt/issue_38669.rs (renamed from src/test/mir-opt/issue-38669.rs)0
-rw-r--r--src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir66
-rw-r--r--src/test/mir-opt/issue_41110.rs (renamed from src/test/mir-opt/issue-41110.rs)0
-rw-r--r--src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir92
-rw-r--r--src/test/mir-opt/issue_41697.rs (renamed from src/test/mir-opt/issue-41697.rs)0
-rw-r--r--src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir18
-rw-r--r--src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir146
-rw-r--r--src/test/mir-opt/issue_41888.rs (renamed from src/test/mir-opt/issue-41888.rs)0
-rw-r--r--src/test/mir-opt/issue_62289.rs (renamed from src/test/mir-opt/issue-62289.rs)0
-rw-r--r--src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir120
-rw-r--r--src/test/mir-opt/issue_72181.bar.built.after.mir (renamed from src/test/mir-opt/issue_72181.bar.mir_map.0.mir)18
-rw-r--r--src/test/mir-opt/issue_72181.foo.built.after.mir (renamed from src/test/mir-opt/issue_72181.foo.mir_map.0.mir)30
-rw-r--r--src/test/mir-opt/issue_72181.main.built.after.mir (renamed from src/test/mir-opt/issue_72181.main.mir_map.0.mir)74
-rw-r--r--src/test/mir-opt/issue_72181.rs (renamed from src/test/mir-opt/issue-72181.rs)6
-rw-r--r--src/test/mir-opt/issue_72181_1.f.built.after.mir (renamed from src/test/mir-opt/issue_72181_1.f.mir_map.0.mir)28
-rw-r--r--src/test/mir-opt/issue_72181_1.main.built.after.mir (renamed from src/test/mir-opt/issue_72181_1.main.mir_map.0.mir)58
-rw-r--r--src/test/mir-opt/issue_72181_1.rs (renamed from src/test/mir-opt/issue-72181-1.rs)4
-rw-r--r--src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff99
-rw-r--r--src/test/mir-opt/issue_73223.rs (renamed from src/test/mir-opt/issue-73223.rs)0
-rw-r--r--src/test/mir-opt/issue_78192.f.InstCombine.diff36
-rw-r--r--src/test/mir-opt/issue_78192.rs (renamed from src/test/mir-opt/issue-78192.rs)0
-rw-r--r--src/test/mir-opt/issue_91633.bar.built.after.mir (renamed from src/test/mir-opt/issue_91633.bar.mir_map.0.mir)34
-rw-r--r--src/test/mir-opt/issue_91633.foo.built.after.mir (renamed from src/test/mir-opt/issue_91633.foo.mir_map.0.mir)58
-rw-r--r--src/test/mir-opt/issue_91633.fun.built.after.mir (renamed from src/test/mir-opt/issue_91633.fun.mir_map.0.mir)42
-rw-r--r--src/test/mir-opt/issue_91633.hey.built.after.mir (renamed from src/test/mir-opt/issue_91633.hey.mir_map.0.mir)38
-rw-r--r--src/test/mir-opt/issue_91633.rs (renamed from src/test/mir-opt/issue-91633.rs)8
-rw-r--r--src/test/mir-opt/issue_99325.main.built.after.mir (renamed from src/test/mir-opt/issue_99325.main.mir_map.0.mir)50
-rw-r--r--src/test/mir-opt/issue_99325.rs (renamed from src/test/mir-opt/issue-99325.rs)2
-rw-r--r--src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir93
-rw-r--r--src/test/mir-opt/issues/issue_59352.rs (renamed from src/test/mir-opt/issues/issue-59352.rs)0
-rw-r--r--src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff82
-rw-r--r--src/test/mir-opt/issues/issue_75439.rs (renamed from src/test/mir-opt/issues/issue-75439.rs)0
-rw-r--r--src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir16
-rw-r--r--src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir36
-rw-r--r--src/test/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir7
-rw-r--r--src/test/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir5
-rw-r--r--src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff290
-rw-r--r--src/test/mir-opt/match_arm_scopes.rs (renamed from src/test/mir-opt/match-arm-scopes.rs)0
-rw-r--r--src/test/mir-opt/nll/named_lifetimes_basic.rs (renamed from src/test/mir-opt/nll/named-lifetimes-basic.rs)0
-rw-r--r--src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir30
-rw-r--r--src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir110
-rw-r--r--src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir110
-rw-r--r--src/test/mir-opt/nll/region_subtyping_basic.rs (renamed from src/test/mir-opt/nll/region-subtyping-basic.rs)0
-rw-r--r--src/test/mir-opt/no_drop_for_inactive_variant.rs (renamed from src/test/mir-opt/no-drop-for-inactive-variant.rs)0
-rw-r--r--src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir38
-rw-r--r--src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir48
-rw-r--r--src/test/mir-opt/no_spurious_drop_after_call.rs (renamed from src/test/mir-opt/no-spurious-drop-after-call.rs)0
-rw-r--r--src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff58
-rw-r--r--src/test/mir-opt/nrvo_simple.rs (renamed from src/test/mir-opt/nrvo-simple.rs)0
-rw-r--r--src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir78
-rw-r--r--src/test/mir-opt/packed_struct_drop_aligned.rs (renamed from src/test/mir-opt/packed-struct-drop-aligned.rs)0
-rw-r--r--src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir4
-rw-r--r--src/test/mir-opt/remove_never_const.rs (renamed from src/test/mir-opt/remove-never-const.rs)0
-rw-r--r--src/test/mir-opt/remove_zsts.get_union.PreCodegen.after.mir10
-rw-r--r--src/test/mir-opt/remove_zsts.get_union.RemoveZsts.diff19
-rw-r--r--src/test/mir-opt/remove_zsts.rs14
-rw-r--r--src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir15
-rw-r--r--src/test/mir-opt/remove_zsts_dont_touch_unions.rs19
-rw-r--r--src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir10
-rw-r--r--src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir1
-rw-r--r--src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir1
-rw-r--r--src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir11
-rw-r--r--src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir2
-rw-r--r--src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff72
-rw-r--r--src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff35
-rw-r--r--src/test/mir-opt/simplify_arm.rs (renamed from src/test/mir-opt/simplify-arm.rs)0
-rw-r--r--src/test/mir-opt/simplify_arm_identity.rs (renamed from src/test/mir-opt/simplify-arm-identity.rs)0
-rw-r--r--src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff40
-rw-r--r--src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff16
-rw-r--r--src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff40
-rw-r--r--src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff24
-rw-r--r--src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff32
-rw-r--r--src/test/mir-opt/simplify_locals.rs (renamed from src/test/mir-opt/simplify-locals.rs)0
-rw-r--r--src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff22
-rw-r--r--src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff22
-rw-r--r--src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff30
-rw-r--r--src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff22
-rw-r--r--src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff78
-rw-r--r--src/test/mir-opt/simplify_locals_fixedpoint.rs (renamed from src/test/mir-opt/simplify-locals-fixedpoint.rs)0
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff176
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_consts.rs (renamed from src/test/mir-opt/simplify-locals-removes-unused-consts.rs)0
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff58
-rw-r--r--src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs (renamed from src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs)0
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff106
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff85
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir83
-rw-r--r--src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir58
-rw-r--r--src/test/mir-opt/slice_drop_shim.rs (renamed from src/test/mir-opt/slice-drop-shim.rs)0
-rw-r--r--src/test/mir-opt/spanview_block.main.built.after.html (renamed from src/test/mir-opt/spanview_block.main.mir_map.0.html)4
-rw-r--r--src/test/mir-opt/spanview_block.rs (renamed from src/test/mir-opt/spanview-block.rs)2
-rw-r--r--src/test/mir-opt/spanview_statement.main.built.after.html (renamed from src/test/mir-opt/spanview_statement.main.mir_map.0.html)6
-rw-r--r--src/test/mir-opt/spanview_statement.rs (renamed from src/test/mir-opt/spanview-statement.rs)2
-rw-r--r--src/test/mir-opt/spanview_terminator.main.built.after.html (renamed from src/test/mir-opt/spanview_terminator.main.mir_map.0.html)4
-rw-r--r--src/test/mir-opt/spanview_terminator.rs (renamed from src/test/mir-opt/spanview-terminator.rs)2
-rw-r--r--src/test/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff50
-rw-r--r--src/test/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff45
-rw-r--r--src/test/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff47
-rw-r--r--src/test/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff87
-rw-r--r--src/test/mir-opt/sroa.rs88
-rw-r--r--src/test/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff34
-rw-r--r--src/test/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff24
-rw-r--r--src/test/mir-opt/tls_access.main.PreCodegen.after.mir34
-rw-r--r--src/test/mir-opt/tls_access.rs (renamed from src/test/mir-opt/tls-access.rs)0
-rw-r--r--src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir89
-rw-r--r--src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir35
-rw-r--r--src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir10
-rw-r--r--src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir14
-rw-r--r--src/test/mir-opt/uninhabited_enum.rs (renamed from src/test/mir-opt/uninhabited-enum.rs)0
-rw-r--r--src/test/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir (renamed from src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir)8
-rw-r--r--src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir (renamed from src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir)12
-rw-r--r--src/test/mir-opt/unusual_item_types.rs (renamed from src/test/mir-opt/unusual-item-types.rs)6
-rw-r--r--src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir10
-rw-r--r--src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir10
-rw-r--r--src/test/mir-opt/while_storage.rs (renamed from src/test/mir-opt/while-storage.rs)0
-rw-r--r--src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir54
-rw-r--r--src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs2
-rw-r--r--src/test/run-make-fulldeps/issue-51671/Makefile2
-rw-r--r--src/test/run-make-fulldeps/issue-51671/app.rs4
-rw-r--r--src/test/run-make-fulldeps/libtest-json/output-default.json2
-rw-r--r--src/test/run-make-fulldeps/libtest-json/output-stdout-success.json4
-rw-r--r--src/test/run-make-fulldeps/link-dedup/Makefile2
-rw-r--r--src/test/run-make-fulldeps/link-dedup/depa.rs3
-rw-r--r--src/test/run-make-fulldeps/split-debuginfo/Makefile210
-rw-r--r--src/test/run-make-fulldeps/split-debuginfo/baz.rs1
-rw-r--r--src/test/run-make-fulldeps/tools.mk23
-rw-r--r--src/test/run-make/coverage-reports/Makefile2
-rw-r--r--src/test/run-make/coverage-reports/expected_show_coverage.async2.txt4
-rw-r--r--src/test/run-make/emit-shared-files/Makefile12
-rw-r--r--src/test/run-make/issue-36710/Makefile5
-rw-r--r--src/test/run-make/issue-88756-default-output/output-default.stdout4
-rw-r--r--src/test/run-make/macos-deployment-target/Makefile21
-rw-r--r--src/test/run-make/macos-deployment-target/with_deployment_target.rs4
-rw-r--r--src/test/run-make/native-link-modifier-verbatim-linker/Makefile4
-rw-r--r--src/test/run-make/native-link-modifier-verbatim-rustc/Makefile4
-rw-r--r--src/test/run-make/raw-dylib-c/lib.rs2
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/driver.rs8
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/extern.c5
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/extern.gnu.def1
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/extern.msvc.def1
-rw-r--r--src/test/run-make/raw-dylib-import-name-type/output.txt1
-rw-r--r--src/test/run-make/repr128-dwarf/Makefile16
-rw-r--r--src/test/run-make/repr128-dwarf/lib.rs23
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile22
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs5
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs4
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs10
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/Makefile34
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/main.rs4
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c1
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c1
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c1
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs13
-rw-r--r--src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs13
-rw-r--r--src/test/run-make/rustdoc-verify-output-files/Makefile36
-rw-r--r--src/test/run-make/rustdoc-verify-output-files/src/lib.rs1
-rw-r--r--src/test/run-make/test-benches/Makefile11
-rw-r--r--src/test/run-make/test-benches/smokebench.rs14
-rw-r--r--src/test/run-make/translation/broken.ftl2
-rw-r--r--src/test/run-make/translation/missing.ftl2
-rw-r--r--src/test/run-make/translation/working.ftl2
-rw-r--r--src/test/run-make/valid-print-requests/Makefile4
-rw-r--r--src/test/run-make/valid-print-requests/valid-print-requests.stderr2
-rw-r--r--src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs3
-rw-r--r--src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs3
-rw-r--r--src/test/rustdoc-gui/basic.goml4
-rw-r--r--src/test/rustdoc-gui/code-tags.goml4
-rw-r--r--src/test/rustdoc-gui/codeblock-tooltip.goml80
-rw-r--r--src/test/rustdoc-gui/cursor.goml24
-rw-r--r--src/test/rustdoc-gui/docblock-code-block-line-number.goml4
-rw-r--r--src/test/rustdoc-gui/docblock-table.goml47
-rw-r--r--src/test/rustdoc-gui/enum-variants.goml10
-rw-r--r--src/test/rustdoc-gui/help-page.goml40
-rw-r--r--src/test/rustdoc-gui/highlight-colors.goml10
-rw-r--r--src/test/rustdoc-gui/huge-logo.goml21
-rw-r--r--src/test/rustdoc-gui/item-decl-colors.goml7
-rw-r--r--src/test/rustdoc-gui/method-margins.goml18
-rw-r--r--src/test/rustdoc-gui/no-docblock.goml5
-rw-r--r--src/test/rustdoc-gui/notable-trait.goml210
-rw-r--r--src/test/rustdoc-gui/pocket-menu.goml21
-rw-r--r--src/test/rustdoc-gui/run-on-hover.goml55
-rw-r--r--src/test/rustdoc-gui/rust-logo.goml9
-rw-r--r--src/test/rustdoc-gui/scrape-examples-button-focus.goml29
-rw-r--r--src/test/rustdoc-gui/scrape-examples-fonts.goml8
-rw-r--r--src/test/rustdoc-gui/scrape-examples-toggle.goml14
-rw-r--r--src/test/rustdoc-gui/search-filter.goml2
-rw-r--r--src/test/rustdoc-gui/search-keyboard.goml28
-rw-r--r--src/test/rustdoc-gui/search-no-result.goml36
-rw-r--r--src/test/rustdoc-gui/search-result-color.goml79
-rw-r--r--src/test/rustdoc-gui/search-result-display.goml45
-rw-r--r--src/test/rustdoc-gui/settings.goml65
-rw-r--r--src/test/rustdoc-gui/sidebar-links-color.goml386
-rw-r--r--src/test/rustdoc-gui/sidebar-mobile.goml52
-rw-r--r--src/test/rustdoc-gui/sidebar-source-code-display.goml275
-rw-r--r--src/test/rustdoc-gui/sidebar-source-code.goml2
-rw-r--r--src/test/rustdoc-gui/source-code-page.goml46
-rw-r--r--src/test/rustdoc-gui/src-font-size.goml5
-rw-r--r--src/test/rustdoc-gui/src/huge_logo/Cargo.lock7
-rw-r--r--src/test/rustdoc-gui/src/huge_logo/Cargo.toml8
-rw-r--r--src/test/rustdoc-gui/src/huge_logo/src/lib.rs17
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/Cargo.lock7
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/Cargo.toml8
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/examples/check-many-1.rs3
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/examples/check-many-2.rs3
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/examples/check-many-3.rs3
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/examples/check-many-4.rs3
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/examples/check-many-5.rs3
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/examples/check-many-6.rs3
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/examples/check-many-7.rs3
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/examples/check.rs26
-rw-r--r--src/test/rustdoc-gui/src/scrape_examples/src/lib.rs9
-rw-r--r--src/test/rustdoc-gui/src/test_docs/lib.rs26
-rw-r--r--src/test/rustdoc-gui/struct-fields.goml5
-rw-r--r--src/test/rustdoc-gui/target.goml35
-rw-r--r--src/test/rustdoc-gui/theme-change.goml47
-rw-r--r--src/test/rustdoc-gui/theme-in-history.goml1
-rw-r--r--src/test/rustdoc-gui/toggle-docs.goml33
-rw-r--r--src/test/rustdoc-gui/trait-sidebar-item-order.goml5
-rw-r--r--src/test/rustdoc-gui/type-declation-overflow.goml23
-rw-r--r--src/test/rustdoc-gui/where-whitespace.goml4
-rw-r--r--src/test/rustdoc-js/reexport.js17
-rw-r--r--src/test/rustdoc-js/reexport.rs11
-rw-r--r--src/test/rustdoc-json/enums/auxiliary/color.rs5
-rw-r--r--src/test/rustdoc-json/enums/doc_link_to_foreign_variant.rs11
-rw-r--r--src/test/rustdoc-json/enums/use_glob.rs18
-rw-r--r--src/test/rustdoc-json/enums/use_variant.rs15
-rw-r--r--src/test/rustdoc-json/enums/use_variant_foreign.rs9
-rw-r--r--src/test/rustdoc-json/fns/pattern_arg.rs7
-rw-r--r--src/test/rustdoc-json/fns/return_type_alias.rs10
-rw-r--r--src/test/rustdoc-json/impls/import_from_private.rs2
-rw-r--r--src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs8
-rw-r--r--src/test/rustdoc-json/intra-doc-links/foreign_variant.rs13
-rw-r--r--src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs2
-rw-r--r--src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs10
-rw-r--r--src/test/rustdoc-json/traits/trait_alias.rs30
-rw-r--r--src/test/rustdoc-json/traits/uses_extern_trait.rs6
-rw-r--r--src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs5
-rw-r--r--src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr15
-rw-r--r--src/test/rustdoc-ui/const-evalutation-ice.rs (renamed from src/test/rustdoc/const-evalutation-ice.rs)3
-rw-r--r--src/test/rustdoc-ui/const-evalutation-ice.stderr9
-rw-r--r--src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr12
-rw-r--r--src/test/rustdoc-ui/issue-103997.rs6
-rw-r--r--src/test/rustdoc-ui/issue-103997.stderr10
-rw-r--r--src/test/rustdoc-ui/issue-91713.stdout8
-rw-r--r--src/test/rustdoc-ui/track-diagnostics.rs10
-rw-r--r--src/test/rustdoc-ui/track-diagnostics.stderr10
-rw-r--r--src/test/rustdoc-ui/z-help.stdout3
-rw-r--r--src/test/rustdoc/anchors.no_method_anchor.html2
-rw-r--r--src/test/rustdoc/anchors.no_trait_method_anchor.html2
-rw-r--r--src/test/rustdoc/anchors.no_tymethod_anchor.html2
-rw-r--r--src/test/rustdoc/assoc-consts.rs1
-rw-r--r--src/test/rustdoc/async-trait-sig.rs14
-rw-r--r--src/test/rustdoc/auxiliary/masked.rs4
-rw-r--r--src/test/rustdoc/bounds-in-multiple-parts.rs20
-rw-r--r--src/test/rustdoc/check-source-code-urls-to-def.rs32
-rw-r--r--src/test/rustdoc/decl-trailing-whitespace.declaration.html10
-rw-r--r--src/test/rustdoc/deref-to-primitive.rs15
-rw-r--r--src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html1
-rw-r--r--src/test/rustdoc/doc-notable_trait-slice.rs4
-rw-r--r--src/test/rustdoc/doc-notable_trait.bare-fn.html1
-rw-r--r--src/test/rustdoc/doc-notable_trait.rs10
-rw-r--r--src/test/rustdoc/doc-notable_trait.some-struct-new.html1
-rw-r--r--src/test/rustdoc/doc-notable_trait.wrap-me.html1
-rw-r--r--src/test/rustdoc/extern-default-method.no_href_on_anchor.html2
-rw-r--r--src/test/rustdoc/extern-default-method.rs6
-rw-r--r--src/test/rustdoc/foreigntype.rs2
-rw-r--r--src/test/rustdoc/impl-parts.rs4
-rw-r--r--src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs6
-rw-r--r--src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs2
-rw-r--r--src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs17
-rw-r--r--src/test/rustdoc/inline_cross/dyn_trait.rs31
-rw-r--r--src/test/rustdoc/inline_cross/impl_trait.rs2
-rw-r--r--src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html2
-rw-r--r--src/test/rustdoc/issue-102154.rs13
-rw-r--r--src/test/rustdoc/issue-20727.rs2
-rw-r--r--src/test/rustdoc/issue-41783.codeblock.html2
-rw-r--r--src/test/rustdoc/issue-41783.rs6
-rw-r--r--src/test/rustdoc/issue-88600.rs10
-rw-r--r--src/test/rustdoc/local-reexport-doc.rs16
-rw-r--r--src/test/rustdoc/masked.rs1
-rw-r--r--src/test/rustdoc/multiple-import-levels.rs34
-rw-r--r--src/test/rustdoc/no-unit-struct-field.rs18
-rw-r--r--src/test/rustdoc/rfc-2632-const-trait-impl.rs2
-rw-r--r--src/test/rustdoc/spotlight-from-dependency.odd.html1
-rw-r--r--src/test/rustdoc/spotlight-from-dependency.rs3
-rw-r--r--src/test/rustdoc/static-root-path.rs12
-rw-r--r--src/test/rustdoc/trait-impl-items-links-and-anchors.rs14
-rw-r--r--src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html4
-rw-r--r--src/test/rustdoc/whitespace-after-where-clause.enum.html2
-rw-r--r--src/test/rustdoc/whitespace-after-where-clause.struct.html2
-rw-r--r--src/test/rustdoc/whitespace-after-where-clause.trait.html4
-rw-r--r--src/test/rustdoc/whitespace-after-where-clause.trait2.html4
-rw-r--r--src/test/rustdoc/whitespace-after-where-clause.union.html2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr16
-rw-r--r--src/test/ui-fulldeps/lint-plugin-deny-attr.stderr16
-rw-r--r--src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr16
-rw-r--r--src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs1
-rw-r--r--src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr27
-rw-r--r--src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr26
-rw-r--r--src/test/ui-fulldeps/lint-plugin.stderr16
-rw-r--r--src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr22
-rw-r--r--src/test/ui-fulldeps/lint-tool-test.rs3
-rw-r--r--src/test/ui-fulldeps/lint-tool-test.stderr70
-rw-r--r--src/test/ui-fulldeps/pprust-expr-roundtrip.rs35
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs39
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr46
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs24
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr11
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs248
-rw-r--r--src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr122
-rw-r--r--src/test/ui-fulldeps/uninit_mask.rs28
-rw-r--r--src/test/ui/abi/homogenous-floats-target-feature-mixup.rs192
-rw-r--r--src/test/ui/abi/issues/issue-22565-rust-call.rs13
-rw-r--r--src/test/ui/abi/issues/issue-22565-rust-call.stderr33
-rw-r--r--src/test/ui/abi/rustcall-generic.rs4
-rw-r--r--src/test/ui/alloc-error/alloc-error-handler-bad-signature-1.rs4
-rw-r--r--src/test/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr52
-rw-r--r--src/test/ui/alloc-error/alloc-error-handler-bad-signature-2.rs4
-rw-r--r--src/test/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr61
-rw-r--r--src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.rs2
-rw-r--r--src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr21
-rw-r--r--src/test/ui/argument-suggestions/formal-and-expected-differ.rs25
-rw-r--r--src/test/ui/argument-suggestions/formal-and-expected-differ.stderr30
-rw-r--r--src/test/ui/array-slice-vec/array-break-length.stderr4
-rw-r--r--src/test/ui/array-slice-vec/slice_is_sorted_by_borrow.rs20
-rw-r--r--src/test/ui/array-slice-vec/vec-macro-with-comma-only.stderr2
-rw-r--r--src/test/ui/asm/aarch64/llvm-58384.rs16
-rw-r--r--src/test/ui/asm/issue-92378.rs2
-rw-r--r--src/test/ui/asm/naked-invalid-attr.stderr2
-rw-r--r--src/test/ui/assoc-inherent.rs20
-rw-r--r--src/test/ui/assoc-inherent.stderr17
-rw-r--r--src/test/ui/associated-consts/defaults-cyclic-fail.stderr8
-rw-r--r--src/test/ui/associated-consts/defaults-not-assumed-fail.rs3
-rw-r--r--src/test/ui/associated-consts/defaults-not-assumed-fail.stderr28
-rw-r--r--src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr4
-rw-r--r--src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr4
-rw-r--r--src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr4
-rw-r--r--src/test/ui/associated-consts/issue-47814.rs14
-rw-r--r--src/test/ui/associated-consts/issue-47814.stderr14
-rw-r--r--src/test/ui/associated-consts/issue-58022.rs (renamed from src/test/ui/issues/issue-58022.rs)0
-rw-r--r--src/test/ui/associated-consts/issue-58022.stderr (renamed from src/test/ui/issues/issue-58022.stderr)0
-rw-r--r--src/test/ui/associated-consts/issue-93835.rs8
-rw-r--r--src/test/ui/associated-consts/issue-93835.stderr65
-rw-r--r--src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs10
-rw-r--r--src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr10
-rw-r--r--src/test/ui/associated-inherent-types/assoc-inherent-private.rs23
-rw-r--r--src/test/ui/associated-inherent-types/assoc-inherent-private.stderr21
-rw-r--r--src/test/ui/associated-inherent-types/assoc-inherent-unstable.rs6
-rw-r--r--src/test/ui/associated-inherent-types/assoc-inherent-unstable.stderr11
-rw-r--r--src/test/ui/associated-inherent-types/assoc-inherent-use.rs14
-rw-r--r--src/test/ui/associated-inherent-types/auxiliary/assoc-inherent-unstable.rs11
-rw-r--r--src/test/ui/associated-inherent-types/issue-104260.rs14
-rw-r--r--src/test/ui/associated-inherent-types/normalize-projection-0.rs22
-rw-r--r--src/test/ui/associated-inherent-types/normalize-projection-1.rs22
-rw-r--r--src/test/ui/associated-inherent-types/struct-generics.rs15
-rw-r--r--src/test/ui/associated-type-bounds/duplicate.rs3
-rw-r--r--src/test/ui/associated-type-bounds/duplicate.stderr98
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.rs4
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.stderr14
-rw-r--r--src/test/ui/async-await/async-borrowck-escaping-block-error.stderr20
-rw-r--r--src/test/ui/async-await/auxiliary/issue-107036.rs12
-rw-r--r--src/test/ui/async-await/drop-track-bad-field-in-fru.rs10
-rw-r--r--src/test/ui/async-await/drop-track-bad-field-in-fru.stderr23
-rw-r--r--src/test/ui/async-await/drop-tracking-unresolved-typeck-results.rs106
-rw-r--r--src/test/ui/async-await/drop-tracking-unresolved-typeck-results.stderr62
-rw-r--r--src/test/ui/async-await/feature-self-return-type.rs28
-rw-r--r--src/test/ui/async-await/feature-self-return-type.stderr15
-rw-r--r--src/test/ui/async-await/generator-desc.stderr32
-rw-r--r--src/test/ui/async-await/generator-not-future.rs45
-rw-r--r--src/test/ui/async-await/generator-not-future.stderr81
-rw-r--r--src/test/ui/async-await/in-trait/async-associated-types.rs4
-rw-r--r--src/test/ui/async-await/in-trait/async-associated-types.stderr57
-rw-r--r--src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr8
-rw-r--r--src/test/ui/async-await/in-trait/async-generics.stderr8
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs3
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr23
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes.rs3
-rw-r--r--src/test/ui/async-await/in-trait/async-lifetimes.stderr23
-rw-r--r--src/test/ui/async-await/in-trait/early-bound-1.rs17
-rw-r--r--src/test/ui/async-await/in-trait/early-bound-2.rs15
-rw-r--r--src/test/ui/async-await/in-trait/implied-bounds.rs13
-rw-r--r--src/test/ui/async-await/in-trait/lifetime-mismatch.rs20
-rw-r--r--src/test/ui/async-await/in-trait/lifetime-mismatch.stderr21
-rw-r--r--src/test/ui/async-await/in-trait/nested-rpit.rs19
-rw-r--r--src/test/ui/async-await/in-trait/object-safety.rs13
-rw-r--r--src/test/ui/async-await/in-trait/object-safety.stderr27
-rw-r--r--src/test/ui/async-await/in-trait/return-type-suggestion.rs14
-rw-r--r--src/test/ui/async-await/in-trait/return-type-suggestion.stderr23
-rw-r--r--src/test/ui/async-await/issue-107036.rs14
-rw-r--r--src/test/ui/async-await/issue-61949-self-return-type.rs2
-rw-r--r--src/test/ui/async-await/issue-61949-self-return-type.stderr24
-rw-r--r--src/test/ui/async-await/issue-67252-unnamed-future.stderr2
-rw-r--r--src/test/ui/async-await/issue-68112.drop_tracking.stderr4
-rw-r--r--src/test/ui/async-await/issue-68112.no_drop_tracking.stderr4
-rw-r--r--src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr5
-rw-r--r--src/test/ui/async-await/issue-86507.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-65159.rs1
-rw-r--r--src/test/ui/async-await/issues/issue-65159.stderr16
-rw-r--r--src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-78600.stderr7
-rw-r--r--src/test/ui/async-await/issues/issue-78938-async-block.stderr4
-rw-r--r--src/test/ui/async-await/large_moves.attribute.stderr8
-rw-r--r--src/test/ui/async-await/large_moves.option.stderr8
-rw-r--r--src/test/ui/async-await/large_moves.rs1
-rw-r--r--src/test/ui/async-await/track-caller/async-closure-gate.rs9
-rw-r--r--src/test/ui/async-await/track-caller/async-closure-gate.stderr12
-rw-r--r--src/test/ui/async-await/track-caller/issue-105134.rs11
-rw-r--r--src/test/ui/async-await/track-caller/panic-track-caller.nofeat.stderr29
-rw-r--r--src/test/ui/async-await/track-caller/panic-track-caller.rs100
-rw-r--r--src/test/ui/async-await/try-on-option-in-async.stderr3
-rw-r--r--src/test/ui/attributes/key-value-non-ascii.rs2
-rw-r--r--src/test/ui/attributes/key-value-non-ascii.stderr4
-rw-r--r--src/test/ui/attributes/unused-item-in-attr.rs6
-rw-r--r--src/test/ui/attributes/unused-item-in-attr.stderr16
-rw-r--r--src/test/ui/auto-traits/bad-generics-on-dyn.rs11
-rw-r--r--src/test/ui/auto-traits/bad-generics-on-dyn.stderr11
-rw-r--r--src/test/ui/binding/issue-53114-borrow-checks.stderr16
-rw-r--r--src/test/ui/binop/binop-move-semantics.stderr4
-rw-r--r--src/test/ui/binop/binop-mul-i32-f32.stderr11
-rw-r--r--src/test/ui/borrowck/async-reference-generality.rs35
-rw-r--r--src/test/ui/borrowck/async-reference-generality.stderr27
-rw-r--r--src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr25
-rw-r--r--src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs6
-rw-r--r--src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr24
-rw-r--r--src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr2
-rw-r--r--src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr2
-rw-r--r--src/test/ui/borrowck/borrowck-consume-unsize-vec.stderr12
-rw-r--r--src/test/ui/borrowck/borrowck-consume-upcast-box.stderr8
-rw-r--r--src/test/ui/borrowck/borrowck-drop-from-guard.stderr5
-rw-r--r--src/test/ui/borrowck/borrowck-loan-in-overloaded-op.stderr5
-rw-r--r--src/test/ui/borrowck/borrowck-move-by-capture.rs6
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr40
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr36
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr56
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr36
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr56
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array.stderr40
-rw-r--r--src/test/ui/borrowck/borrowck-multiple-captures.stderr15
-rw-r--r--src/test/ui/borrowck/borrowck-overloaded-index-move-index.stderr5
-rw-r--r--src/test/ui/borrowck/borrowck-reinit.stderr5
-rw-r--r--src/test/ui/borrowck/issue-11493.stderr2
-rw-r--r--src/test/ui/borrowck/issue-17545.stderr2
-rw-r--r--src/test/ui/borrowck/issue-31287-drop-in-guard.stderr5
-rw-r--r--src/test/ui/borrowck/issue-36082.fixed2
-rw-r--r--src/test/ui/borrowck/issue-36082.rs2
-rw-r--r--src/test/ui/borrowck/issue-36082.stderr2
-rw-r--r--src/test/ui/borrowck/issue-41962.stderr2
-rw-r--r--src/test/ui/borrowck/issue-81899.rs5
-rw-r--r--src/test/ui/borrowck/issue-81899.stderr22
-rw-r--r--src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs1
-rw-r--r--src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr18
-rw-r--r--src/test/ui/borrowck/issue-83760.stderr4
-rw-r--r--src/test/ui/borrowck/issue-88434-minimal-example.rs3
-rw-r--r--src/test/ui/borrowck/issue-88434-minimal-example.stderr22
-rw-r--r--src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs3
-rw-r--r--src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr22
-rw-r--r--src/test/ui/borrowck/move-in-pattern-mut-in-loop.stderr2
-rw-r--r--src/test/ui/borrowck/move-in-pattern-mut.stderr4
-rw-r--r--src/test/ui/borrowck/move-in-pattern.stderr4
-rw-r--r--src/test/ui/borrowck/mut-borrow-in-loop-2.stderr8
-rw-r--r--src/test/ui/borrowck/or-patterns.stderr16
-rw-r--r--src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs19
-rw-r--r--src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr49
-rw-r--r--src/test/ui/c-variadic/issue-86053-1.stderr4
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-1.rs4
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-1.stderr28
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-2.rs15
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-2.stderr6
-rw-r--r--src/test/ui/cannot-mutate-captured-non-mut-var.rs4
-rw-r--r--src/test/ui/cast/cast-pointee-projection.rs17
-rw-r--r--src/test/ui/chalkify/bugs/async.stderr41
-rw-r--r--src/test/ui/chalkify/closure.rs1
-rw-r--r--src/test/ui/chalkify/closure.stderr4
-rw-r--r--src/test/ui/check-cfg/well-known-values.stderr2
-rw-r--r--src/test/ui/cleanup-rvalue-scopes-cf.stderr14
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr4
-rw-r--r--src/test/ui/closures/binder/late-bound-in-body.rs9
-rw-r--r--src/test/ui/closures/binder/nested-closures-regions.rs9
-rw-r--r--src/test/ui/closures/binder/nested-closures-regions.stderr38
-rw-r--r--src/test/ui/closures/binder/nested-closures.rs7
-rw-r--r--src/test/ui/closures/closure-array-break-length.stderr4
-rw-r--r--src/test/ui/closures/issue-23012-supertrait-signature-inference.rs29
-rw-r--r--src/test/ui/closures/issue-78720.stderr4
-rw-r--r--src/test/ui/closures/issue-90871.rs4
-rw-r--r--src/test/ui/closures/issue-90871.stderr23
-rw-r--r--src/test/ui/closures/supertrait-hint-references-assoc-ty.rs17
-rw-r--r--src/test/ui/codegen/issue-99551.rs1
-rw-r--r--src/test/ui/codemap_tests/tab_3.stderr4
-rw-r--r--src/test/ui/codemap_tests/unicode_2.stderr12
-rw-r--r--src/test/ui/coercion/coerce-block-tail-26978.rs11
-rw-r--r--src/test/ui/coercion/coerce-block-tail-26978.stderr16
-rw-r--r--src/test/ui/coercion/coerce-block-tail-57749.rs35
-rw-r--r--src/test/ui/coercion/coerce-block-tail-57749.stderr14
-rw-r--r--src/test/ui/coercion/coerce-block-tail-83783.rs13
-rw-r--r--src/test/ui/coercion/coerce-block-tail-83783.stderr12
-rw-r--r--src/test/ui/coercion/coerce-block-tail-83850.rs7
-rw-r--r--src/test/ui/coercion/coerce-block-tail-83850.stderr19
-rw-r--r--src/test/ui/coercion/coerce-block-tail.rs6
-rw-r--r--src/test/ui/coercion/coerce-block-tail.stderr16
-rw-r--r--src/test/ui/coercion/coerce-expect-unsized-ascribed.rs32
-rw-r--r--src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr90
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr2
-rw-r--r--src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr4
-rw-r--r--src/test/ui/coherence/coherence-impls-copy.stderr2
-rw-r--r--src/test/ui/coherence/coherence-overlap-issue-23516.stderr4
-rw-r--r--src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr4
-rw-r--r--src/test/ui/coherence/coherence-wasm-bindgen.stderr4
-rw-r--r--src/test/ui/coherence/coherence-with-closure.rs1
-rw-r--r--src/test/ui/coherence/coherence-with-closure.stderr17
-rw-r--r--src/test/ui/coherence/coherence-with-generator.rs1
-rw-r--r--src/test/ui/coherence/coherence-with-generator.stderr17
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr4
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_struct.stderr4
-rw-r--r--src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr2
-rw-r--r--src/test/ui/coherence/issue-100191-2.rs12
-rw-r--r--src/test/ui/coherence/issue-100191.rs21
-rw-r--r--src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs7
-rw-r--r--src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr10
-rw-r--r--src/test/ui/compiletest-self-test/compile-flags-last.rs7
-rw-r--r--src/test/ui/compiletest-self-test/compile-flags-last.stderr2
-rw-r--r--src/test/ui/compiletest-self-test/ui-testing-optout.rs (renamed from src/test/ui/ui-testing-optout.rs)0
-rw-r--r--src/test/ui/compiletest-self-test/ui-testing-optout.stderr (renamed from src/test/ui/ui-testing-optout.stderr)0
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr2
-rw-r--r--src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs2
-rw-r--r--src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr8
-rw-r--r--src/test/ui/const-generics/defaults/self-referential.rs4
-rw-r--r--src/test/ui/const-generics/defaults/self-referential.stderr11
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs27
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.rs15
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr10
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/dropck_unifies_assoc_consts.rs20
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/unifies_evaluatable.rs18
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs22
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr20
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-102768.stderr2
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr30
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-99705.rs33
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/normed_to_param_is_evaluatable.rs12
-rw-r--r--src/test/ui/const-generics/inhabited-assoc-ty-ice-1.rs (renamed from src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-1.rs)2
-rw-r--r--src/test/ui/const-generics/inhabited-assoc-ty-ice-2.rs (renamed from src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-2.rs)2
-rw-r--r--src/test/ui/const-generics/invariant.rs3
-rw-r--r--src/test/ui/const-generics/issues/issue-100313.stderr15
-rw-r--r--src/test/ui/const-generics/issues/issue-82956.stderr2
-rw-r--r--src/test/ui/const-generics/issues/issue-83765.stderr6
-rw-r--r--src/test/ui/const-generics/issues/issue-85031-2.rs (renamed from src/test/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-85031-2.rs)8
-rw-r--r--src/test/ui/const-generics/issues/issue-85031-2.stderr14
-rw-r--r--src/test/ui/const-generics/min_const_generics/macro-fail.rs5
-rw-r--r--src/test/ui/const-generics/min_const_generics/macro-fail.stderr32
-rw-r--r--src/test/ui/const-generics/projection-as-arg-const.rs20
-rw-r--r--src/test/ui/const-generics/projection-as-arg-const.stderr11
-rw-r--r--src/test/ui/const-ptr/forbidden_slices.32bit.stderr187
-rw-r--r--src/test/ui/const-ptr/forbidden_slices.64bit.stderr187
-rw-r--r--src/test/ui/const-ptr/out_of_bounds_read.stderr57
-rw-r--r--src/test/ui/constructor-lifetime-args.stderr8
-rw-r--r--src/test/ui/consts/const-err-late.rs4
-rw-r--r--src/test/ui/consts/const-err-late.stderr34
-rw-r--r--src/test/ui/consts/const-err-multi.rs6
-rw-r--r--src/test/ui/consts/const-err-multi.stderr14
-rw-r--r--src/test/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr2
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr11
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr11
-rw-r--r--src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr30
-rw-r--r--src/test/ui/consts/const-eval/const_panic_track_caller.stderr15
-rw-r--r--src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr6
-rw-r--r--src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr4
-rw-r--r--src/test/ui/consts/const-eval/erroneous-const.rs2
-rw-r--r--src/test/ui/consts/const-eval/erroneous-const.stderr10
-rw-r--r--src/test/ui/consts/const-eval/erroneous-const2.rs2
-rw-r--r--src/test/ui/consts/const-eval/erroneous-const2.stderr6
-rw-r--r--src/test/ui/consts/const-eval/format.rs4
-rw-r--r--src/test/ui/consts/const-eval/format.stderr63
-rw-r--r--src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr17
-rw-r--r--src/test/ui/consts/const-eval/issue-104390.rs10
-rw-r--r--src/test/ui/consts/const-eval/issue-104390.stderr65
-rw-r--r--src/test/ui/consts/const-eval/issue-44578.rs3
-rw-r--r--src/test/ui/consts/const-eval/issue-44578.stderr28
-rw-r--r--src/test/ui/consts/const-eval/issue-50814-2.rs2
-rw-r--r--src/test/ui/consts/const-eval/issue-50814-2.stderr6
-rw-r--r--src/test/ui/consts/const-eval/issue-50814.rs8
-rw-r--r--src/test/ui/consts/const-eval/issue-50814.stderr8
-rw-r--r--src/test/ui/consts/const-eval/panic-assoc-never-type.rs3
-rw-r--r--src/test/ui/consts/const-eval/panic-assoc-never-type.stderr12
-rw-r--r--src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr2
-rw-r--r--src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr2
-rw-r--r--src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr8
-rw-r--r--src/test/ui/consts/const-eval/transmute-const-promotion.stderr2
-rw-r--r--src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr13
-rw-r--r--src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr13
-rw-r--r--src/test/ui/consts/const-eval/ub-nonnull.rs9
-rw-r--r--src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr28
-rw-r--r--src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr28
-rw-r--r--src/test/ui/consts/const-eval/ub-ref-ptr.rs2
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr14
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr14
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.rs6
-rw-r--r--src/test/ui/consts/const-eval/union-const-eval-field.rs1
-rw-r--r--src/test/ui/consts/const-eval/union-const-eval-field.stderr12
-rw-r--r--src/test/ui/consts/const-eval/union_promotion.stderr2
-rw-r--r--src/test/ui/consts/const-eval/unwind-abort.stderr16
-rw-r--r--src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr20
-rw-r--r--src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr20
-rw-r--r--src/test/ui/consts/const-float-bits-reject-conv.rs30
-rw-r--r--src/test/ui/consts/const-float-bits-reject-conv.stderr146
-rw-r--r--src/test/ui/consts/const-int-conversion.stderr14
-rw-r--r--src/test/ui/consts/const-int-overflowing.stderr6
-rw-r--r--src/test/ui/consts/const-int-rotate.stderr4
-rw-r--r--src/test/ui/consts/const-int-sign.stderr4
-rw-r--r--src/test/ui/consts/const-int-wrapping.stderr10
-rw-r--r--src/test/ui/consts/const-integer-bool-ops.rs20
-rw-r--r--src/test/ui/consts/const-integer-bool-ops.stderr45
-rw-r--r--src/test/ui/consts/const-len-underflow-separate-spans.rs2
-rw-r--r--src/test/ui/consts/const-len-underflow-separate-spans.stderr6
-rw-r--r--src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr10
-rw-r--r--src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr10
-rw-r--r--src/test/ui/consts/const-mut-refs/issue-76510.rs2
-rw-r--r--src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr10
-rw-r--r--src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr15
-rw-r--r--src/test/ui/consts/const-ptr-nonnull.stderr4
-rw-r--r--src/test/ui/consts/const-ptr-unique.stderr2
-rw-r--r--src/test/ui/consts/const-tup-index-span.rs2
-rw-r--r--src/test/ui/consts/const-tup-index-span.stderr9
-rw-r--r--src/test/ui/consts/const_in_pattern/accept_structural.rs2
-rw-r--r--src/test/ui/consts/const_in_pattern/reject_non_structural.rs2
-rw-r--r--src/test/ui/consts/const_unsafe_unreachable_ub.stderr21
-rw-r--r--src/test/ui/consts/control-flow/interior-mutability.stderr6
-rw-r--r--src/test/ui/consts/extra-const-ub/detect-extra-ub.rs2
-rw-r--r--src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr27
-rw-r--r--src/test/ui/consts/fn_trait_refs.rs77
-rw-r--r--src/test/ui/consts/invalid-const-in-body.rs6
-rw-r--r--src/test/ui/consts/invalid-const-in-body.stderr8
-rw-r--r--src/test/ui/consts/invalid-inline-const-in-match-arm.rs9
-rw-r--r--src/test/ui/consts/invalid-inline-const-in-match-arm.stderr12
-rw-r--r--src/test/ui/consts/invalid-union.32bit.stderr20
-rw-r--r--src/test/ui/consts/invalid-union.64bit.stderr20
-rw-r--r--src/test/ui/consts/invalid-union.rs3
-rw-r--r--src/test/ui/consts/issue-102117.rs4
-rw-r--r--src/test/ui/consts/issue-102117.stderr24
-rw-r--r--src/test/ui/consts/issue-103790.rs10
-rw-r--r--src/test/ui/consts/issue-103790.stderr65
-rw-r--r--src/test/ui/consts/issue-104609.rs10
-rw-r--r--src/test/ui/consts/issue-104609.stderr9
-rw-r--r--src/test/ui/consts/issue-104768.rs4
-rw-r--r--src/test/ui/consts/issue-104768.stderr12
-rw-r--r--src/test/ui/consts/issue-36163.stderr4
-rw-r--r--src/test/ui/consts/issue-54224.stderr4
-rw-r--r--src/test/ui/consts/issue-54954.rs (renamed from src/test/ui/issues/issue-54954.rs)4
-rw-r--r--src/test/ui/consts/issue-54954.stderr (renamed from src/test/ui/issues/issue-54954.stderr)14
-rw-r--r--src/test/ui/consts/issue-56164.rs1
-rw-r--r--src/test/ui/consts/issue-56164.stderr17
-rw-r--r--src/test/ui/consts/issue-66693.rs1
-rw-r--r--src/test/ui/consts/issue-66693.stderr13
-rw-r--r--src/test/ui/consts/issue-miri-1910.stderr26
-rw-r--r--src/test/ui/consts/min_const_fn/promotion.stderr12
-rw-r--r--src/test/ui/consts/miri_unleashed/abi-mismatch.stderr15
-rw-r--r--src/test/ui/consts/miri_unleashed/assoc_const.rs2
-rw-r--r--src/test/ui/consts/miri_unleashed/assoc_const.stderr37
-rw-r--r--src/test/ui/consts/miri_unleashed/assoc_const_2.rs2
-rw-r--r--src/test/ui/consts/miri_unleashed/assoc_const_2.stderr18
-rw-r--r--src/test/ui/consts/miri_unleashed/drop.stderr15
-rw-r--r--src/test/ui/consts/miri_unleashed/tls.stderr4
-rw-r--r--src/test/ui/consts/missing_span_in_backtrace.rs27
-rw-r--r--src/test/ui/consts/missing_span_in_backtrace.stderr28
-rw-r--r--src/test/ui/consts/offset_from_ub.stderr45
-rw-r--r--src/test/ui/consts/offset_ub.stderr180
-rw-r--r--src/test/ui/consts/promote-not.stderr40
-rw-r--r--src/test/ui/consts/promote_const_let.stderr2
-rw-r--r--src/test/ui/consts/promoted-const-drop.stderr4
-rw-r--r--src/test/ui/consts/ptr_comparisons.stderr15
-rw-r--r--src/test/ui/consts/qualif-union.stderr10
-rw-r--r--src/test/ui/consts/recursive.stderr21
-rw-r--r--src/test/ui/consts/uninhabited-const-issue-61744.rs2
-rw-r--r--src/test/ui/consts/uninhabited-const-issue-61744.stderr793
-rw-r--r--src/test/ui/deref-patterns/basic.rs17
-rw-r--r--src/test/ui/deref-patterns/basic.run.stdout3
-rw-r--r--src/test/ui/deref-patterns/default-infer.rs9
-rw-r--r--src/test/ui/deref-patterns/gate.rs7
-rw-r--r--src/test/ui/deref-patterns/gate.stderr11
-rw-r--r--src/test/ui/deref-patterns/refs.rs18
-rw-r--r--src/test/ui/derived-errors/issue-31997-1.stderr2
-rw-r--r--src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs2
-rw-r--r--src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr2
-rw-r--r--src/test/ui/deriving/deriving-all-codegen.stdout23
-rw-r--r--src/test/ui/deriving/issue-105101.rs9
-rw-r--r--src/test/ui/deriving/issue-105101.stderr29
-rw-r--r--src/test/ui/diagnostic-width/long-E0308.rs86
-rw-r--r--src/test/ui/diagnostic-width/long-E0308.stderr80
-rw-r--r--src/test/ui/did_you_mean/issue-103909.rs9
-rw-r--r--src/test/ui/did_you_mean/issue-103909.stderr26
-rw-r--r--src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr9
-rw-r--r--src/test/ui/drop/drop_order.rs97
-rw-r--r--src/test/ui/drop/issue-103107.rs37
-rw-r--r--src/test/ui/drop/repeat-drop-2.stderr5
-rw-r--r--src/test/ui/dropck/issue-54943-1.rs (renamed from src/test/ui/issues/issue-54943-1.rs)0
-rw-r--r--src/test/ui/dropck/issue-54943-2.rs (renamed from src/test/ui/issues/issue-54943-2.rs)0
-rw-r--r--src/test/ui/duplicate/duplicate-type-parameter.stderr4
-rw-r--r--src/test/ui/dyn-star/align.normal.stderr11
-rw-r--r--src/test/ui/dyn-star/align.over_aligned.stderr20
-rw-r--r--src/test/ui/dyn-star/align.rs17
-rw-r--r--src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs15
-rw-r--r--src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr15
-rw-r--r--src/test/ui/dyn-star/check-size-at-cast-polymorphic.rs16
-rw-r--r--src/test/ui/dyn-star/check-size-at-cast.rs10
-rw-r--r--src/test/ui/dyn-star/check-size-at-cast.stderr11
-rw-r--r--src/test/ui/dyn-star/dispatch-on-pin-mut.rs52
-rw-r--r--src/test/ui/dyn-star/dispatch-on-pin-mut.run.stdout1
-rw-r--r--src/test/ui/dyn-star/dispatch-on-pin-mut.stderr11
-rw-r--r--src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs27
-rw-r--r--src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.run.stdout2
-rw-r--r--src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.stderr11
-rw-r--r--src/test/ui/dyn-star/dyn-async-trait.rs36
-rw-r--r--src/test/ui/dyn-star/issue-102430.rs32
-rw-r--r--src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.rs13
-rw-r--r--src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr23
-rw-r--r--src/test/ui/dyn-star/return.rs10
-rw-r--r--src/test/ui/dyn-star/return.stderr11
-rw-r--r--src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs9
-rw-r--r--src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr9
-rw-r--r--src/test/ui/dyn-star/upcast.rs3
-rw-r--r--src/test/ui/dyn-star/upcast.stderr20
-rw-r--r--src/test/ui/editions/edition-keywords-2015-2015-parsing.stderr12
-rw-r--r--src/test/ui/editions/edition-keywords-2015-2018-parsing.stderr12
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr12
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr12
-rw-r--r--src/test/ui/empty/empty-comment.stderr6
-rw-r--r--src/test/ui/empty/empty-struct-braces-expr.rs2
-rw-r--r--src/test/ui/empty/empty-struct-braces-expr.stderr32
-rw-r--r--src/test/ui/empty/empty-struct-braces-pat-1.stderr29
-rw-r--r--src/test/ui/empty/empty-struct-braces-pat-3.stderr58
-rw-r--r--src/test/ui/enum-discriminant/get_discr.rs114
-rw-r--r--src/test/ui/enum-discriminant/issue-104519.rs36
-rw-r--r--src/test/ui/enum-discriminant/issue-46519.rs (renamed from src/test/ui/issues/issue-46519.rs)0
-rw-r--r--src/test/ui/enum/issue-67945-2.rs2
-rw-r--r--src/test/ui/enum/issue-67945-2.stderr6
-rw-r--r--src/test/ui/error-codes/E0045.stderr4
-rw-r--r--src/test/ui/error-codes/E0059.stderr12
-rw-r--r--src/test/ui/error-codes/E0081.stderr6
-rw-r--r--src/test/ui/error-codes/E0164.stderr2
-rw-r--r--src/test/ui/error-codes/E0268.stderr4
-rw-r--r--src/test/ui/error-codes/E0275.rs1
-rw-r--r--src/test/ui/error-codes/E0275.stderr9
-rw-r--r--src/test/ui/error-codes/E0282.rs3
-rw-r--r--src/test/ui/error-codes/E0401.rs4
-rw-r--r--src/test/ui/error-codes/E0401.stderr27
-rw-r--r--src/test/ui/error-codes/E0767.rs3
-rw-r--r--src/test/ui/error-codes/E0767.stderr21
-rw-r--r--src/test/ui/error-codes/E0778.rs8
-rw-r--r--src/test/ui/error-codes/E0778.stderr2
-rw-r--r--src/test/ui/error-codes/E0779.rs6
-rw-r--r--src/test/ui/error-codes/E0779.stderr2
-rw-r--r--src/test/ui/error-codes/e0119/conflict-with-std.stderr6
-rw-r--r--src/test/ui/error-codes/e0119/issue-23563.stderr2
-rw-r--r--src/test/ui/error-codes/e0119/issue-27403.stderr2
-rw-r--r--src/test/ui/error-codes/e0119/so-37347311.stderr2
-rw-r--r--src/test/ui/errors/issue-104621-extern-bad-file.rs8
-rw-r--r--src/test/ui/errors/issue-104621-extern-bad-file.stderr21
-rw-r--r--src/test/ui/errors/issue-104621-extern-not-file.rs4
-rw-r--r--src/test/ui/errors/issue-104621-extern-not-file.stderr8
-rw-r--r--src/test/ui/fail-simple.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-efiapi.rs33
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-efiapi.stderr66
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi.rs11
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi.stderr117
-rw-r--r--src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs6
-rw-r--r--src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr6
-rw-r--r--src/test/ui/feature-gates/feature-gate-custom_mir.rs12
-rw-r--r--src/test/ui/feature-gates/feature-gate-custom_mir.stderr11
-rw-r--r--src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs6
-rw-r--r--src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr21
-rw-r--r--src/test/ui/feature-gates/feature-gate-isa_attribute.rs6
-rw-r--r--src/test/ui/feature-gates/feature-gate-isa_attribute.stderr25
-rw-r--r--src/test/ui/feature-gates/feature-gate-linkage.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-linkage.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.rs5
-rw-r--r--src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.stderr12
-rw-r--r--src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr6
-rw-r--r--src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs2
-rw-r--r--src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr8
-rw-r--r--src/test/ui/fmt/format-raw-string-error.rs3
-rw-r--r--src/test/ui/fmt/format-raw-string-error.stderr10
-rw-r--r--src/test/ui/fmt/issue-104142.rs6
-rw-r--r--src/test/ui/fmt/issue-104142.stderr10
-rw-r--r--src/test/ui/fmt/unicode-escape-spans.rs19
-rw-r--r--src/test/ui/fmt/unicode-escape-spans.stderr63
-rw-r--r--src/test/ui/fn/signature-error-reporting-under-verbose.rs15
-rw-r--r--src/test/ui/fn/signature-error-reporting-under-verbose.stderr19
-rw-r--r--src/test/ui/for-loop-while/break-outside-loop.stderr8
-rw-r--r--src/test/ui/function-pointer/unsized-ret.rs3
-rw-r--r--src/test/ui/function-pointer/unsized-ret.stderr12
-rw-r--r--src/test/ui/generator/auto-trait-regions.stderr4
-rw-r--r--src/test/ui/generator/clone-impl-async.rs27
-rw-r--r--src/test/ui/generator/clone-impl-async.stderr48
-rw-r--r--src/test/ui/generator/issue-52398.stderr4
-rw-r--r--src/test/ui/generator/issue-57084.stderr2
-rw-r--r--src/test/ui/generator/match-bindings.stderr2
-rw-r--r--src/test/ui/generator/print/generator-print-verbose-1.stderr8
-rw-r--r--src/test/ui/generator/reborrow-mut-upvar.stderr2
-rw-r--r--src/test/ui/generator/too-live-local-in-immovable-gen.stderr2
-rw-r--r--src/test/ui/generator/unresolved-ct-var.rs14
-rw-r--r--src/test/ui/generator/unresolved-ct-var.stderr78
-rw-r--r--src/test/ui/generator/yield-in-args-rev.stderr2
-rw-r--r--src/test/ui/generator/yield-in-box.stderr2
-rw-r--r--src/test/ui/generator/yield-in-initializer.stderr2
-rw-r--r--src/test/ui/generator/yield-subtype.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr2
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-100013.rs39
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-100013.stderr82
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-80626.rs7
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-80626.stderr15
-rw-r--r--src/test/ui/generic-associated-types/elided-in-expr-position.stderr4
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr4
-rw-r--r--src/test/ui/generic-associated-types/issue-81862.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-87750.rs8
-rw-r--r--src/test/ui/generic-associated-types/issue-87750.stderr9
-rw-r--r--src/test/ui/generic-associated-types/issue-91139.rs1
-rw-r--r--src/test/ui/generic-associated-types/issue-91139.stderr13
-rw-r--r--src/test/ui/generic-associated-types/missing_lifetime_args.stderr4
-rw-r--r--src/test/ui/generic-associated-types/own-bound-span.rs17
-rw-r--r--src/test/ui/generic-associated-types/own-bound-span.stderr15
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr2
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs2
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr14
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle.rs2
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle.stderr14
-rw-r--r--src/test/ui/generic-associated-types/self-outlives-lint.stderr22
-rw-r--r--src/test/ui/generics/wrong-number-of-args.stderr12
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-36139-normalize-closure-sig.rs (renamed from src/test/ui/issues/issue-36139-normalize-closure-sig.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-43623.rs (renamed from src/test/ui/issues/issue-43623.rs)0
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs53
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr21
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs23
-rw-r--r--src/test/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr18
-rw-r--r--src/test/ui/hygiene/no_implicit_prelude.stderr2
-rw-r--r--src/test/ui/hygiene/panic-location.run.stderr2
-rw-r--r--src/test/ui/impl-trait/auto-trait.rs1
-rw-r--r--src/test/ui/impl-trait/auto-trait.stderr14
-rw-r--r--src/test/ui/impl-trait/bound-normalization-fail.stderr15
-rw-r--r--src/test/ui/impl-trait/cross-return-site-inference.rs9
-rw-r--r--src/test/ui/impl-trait/cross-return-site-inference.stderr4
-rw-r--r--src/test/ui/impl-trait/deduce-signature-from-supertrait.rs15
-rw-r--r--src/test/ui/impl-trait/equality.stderr13
-rw-r--r--src/test/ui/impl-trait/feature-self-return-type.rs102
-rw-r--r--src/test/ui/impl-trait/feature-self-return-type.stderr39
-rw-r--r--src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr11
-rw-r--r--src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs4
-rw-r--r--src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.rs8
-rw-r--r--src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.stderr11
-rw-r--r--src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs24
-rw-r--r--src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr51
-rw-r--r--src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs15
-rw-r--r--src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr26
-rw-r--r--src/test/ui/impl-trait/impl-fn-predefined-lifetimes.rs15
-rw-r--r--src/test/ui/impl-trait/impl-fn-predefined-lifetimes.stderr21
-rw-r--r--src/test/ui/impl-trait/impl_fn_associativity.rs26
-rw-r--r--src/test/ui/impl-trait/in-trait/generics-mismatch.rs17
-rw-r--r--src/test/ui/impl-trait/in-trait/generics-mismatch.stderr12
-rw-r--r--src/test/ui/impl-trait/in-trait/method-signature-matches.rs51
-rw-r--r--src/test/ui/impl-trait/in-trait/method-signature-matches.stderr84
-rw-r--r--src/test/ui/impl-trait/in-trait/object-safety.stderr12
-rw-r--r--src/test/ui/impl-trait/in-trait/specialization-broken.rs26
-rw-r--r--src/test/ui/impl-trait/in-trait/specialization-broken.stderr23
-rw-r--r--src/test/ui/impl-trait/in-trait/specialization-substs-remap.rs24
-rw-r--r--src/test/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs17
-rw-r--r--src/test/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr12
-rw-r--r--src/test/ui/impl-trait/in-trait/where-clause.rs24
-rw-r--r--src/test/ui/impl-trait/issue-35668.rs (renamed from src/test/ui/issues/issue-35668.rs)0
-rw-r--r--src/test/ui/impl-trait/issue-35668.stderr (renamed from src/test/ui/issues/issue-35668.stderr)0
-rw-r--r--src/test/ui/impl-trait/issue-49556.rs (renamed from src/test/ui/issues/issue-49556.rs)0
-rw-r--r--src/test/ui/impl-trait/issue-55872-3.rs2
-rw-r--r--src/test/ui/impl-trait/issue-55872-3.stderr4
-rw-r--r--src/test/ui/impl-trait/issues/issue-104815.rs66
-rw-r--r--src/test/ui/impl-trait/issues/issue-105826.rs39
-rw-r--r--src/test/ui/impl-trait/issues/issue-78722.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-78722.stderr2
-rw-r--r--src/test/ui/impl-trait/issues/issue-92305.rs3
-rw-r--r--src/test/ui/impl-trait/issues/issue-92305.stderr22
-rw-r--r--src/test/ui/impl-trait/negative-reasoning.rs1
-rw-r--r--src/test/ui/impl-trait/negative-reasoning.stderr14
-rw-r--r--src/test/ui/impl-trait/nested-return-type4.rs8
-rw-r--r--src/test/ui/impl-trait/nested-return-type4.stderr20
-rw-r--r--src/test/ui/impl-trait/nested-rpit-hrtb.rs12
-rw-r--r--src/test/ui/impl-trait/nested_impl_trait.rs4
-rw-r--r--src/test/ui/impl-trait/nested_impl_trait.stderr22
-rw-r--r--src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs2
-rw-r--r--src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr19
-rw-r--r--src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs5
-rw-r--r--src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr49
-rw-r--r--src/test/ui/impl-trait/where-allowed.rs7
-rw-r--r--src/test/ui/impl-trait/where-allowed.stderr98
-rw-r--r--src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs10
-rw-r--r--src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr20
-rw-r--r--src/test/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs22
-rw-r--r--src/test/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr16
-rw-r--r--src/test/ui/implied-bounds/impl-implied-bounds-compatibility.rs21
-rw-r--r--src/test/ui/implied-bounds/impl-implied-bounds-compatibility.stderr16
-rw-r--r--src/test/ui/inference/cannot-infer-async.rs3
-rw-r--r--src/test/ui/inference/cannot-infer-closure.rs3
-rw-r--r--src/test/ui/inference/deref-suggestion.stderr12
-rw-r--r--src/test/ui/inference/issue-103587.rs12
-rw-r--r--src/test/ui/inference/issue-103587.stderr40
-rw-r--r--src/test/ui/inference/issue-104649.rs32
-rw-r--r--src/test/ui/inference/issue-104649.stderr14
-rw-r--r--src/test/ui/inference/issue-71732.rs3
-rw-r--r--src/test/ui/inference/issue-72616.rs5
-rw-r--r--src/test/ui/inference/issue-72616.stderr20
-rw-r--r--src/test/ui/inference/question-mark-type-infer.rs3
-rw-r--r--src/test/ui/infinite/infinite-instantiation.stderr2
-rw-r--r--src/test/ui/infinite/infinite-recursion-const-fn.stderr775
-rw-r--r--src/test/ui/inline-const/expr-with-block-err.rs6
-rw-r--r--src/test/ui/inline-const/expr-with-block-err.stderr9
-rw-r--r--src/test/ui/inline-const/expr-with-block.rs10
-rw-r--r--src/test/ui/issues/issue-105330.rs21
-rw-r--r--src/test/ui/issues/issue-105330.stderr109
-rw-r--r--src/test/ui/issues/issue-12127.rs4
-rw-r--r--src/test/ui/issues/issue-13497-2.stderr6
-rw-r--r--src/test/ui/issues/issue-1460.stderr2
-rw-r--r--src/test/ui/issues/issue-16256.stderr2
-rw-r--r--src/test/ui/issues/issue-17252.stderr4
-rw-r--r--src/test/ui/issues/issue-19086.rs2
-rw-r--r--src/test/ui/issues/issue-19086.stderr2
-rw-r--r--src/test/ui/issues/issue-20413.rs1
-rw-r--r--src/test/ui/issues/issue-20413.stderr39
-rw-r--r--src/test/ui/issues/issue-22638.stderr1
-rw-r--r--src/test/ui/issues/issue-23024.stderr2
-rw-r--r--src/test/ui/issues/issue-23122-2.stderr5
-rw-r--r--src/test/ui/issues/issue-23302-3.stderr8
-rw-r--r--src/test/ui/issues/issue-24352.stderr11
-rw-r--r--src/test/ui/issues/issue-28105.stderr4
-rw-r--r--src/test/ui/issues/issue-28568.stderr2
-rw-r--r--src/test/ui/issues/issue-28992-empty.stderr2
-rw-r--r--src/test/ui/issues/issue-29723.stderr5
-rw-r--r--src/test/ui/issues/issue-30490.rs2
-rw-r--r--src/test/ui/issues/issue-32655.stderr14
-rw-r--r--src/test/ui/issues/issue-35976.rs14
-rw-r--r--src/test/ui/issues/issue-35976.unimported.stderr (renamed from src/test/ui/issues/issue-35976.stderr)7
-rw-r--r--src/test/ui/issues/issue-3707.stderr4
-rw-r--r--src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr2
-rw-r--r--src/test/ui/issues/issue-41394.rs2
-rw-r--r--src/test/ui/issues/issue-41394.stderr9
-rw-r--r--src/test/ui/issues/issue-42796.stderr4
-rw-r--r--src/test/ui/issues/issue-43162.stderr8
-rw-r--r--src/test/ui/issues/issue-43355.stderr2
-rw-r--r--src/test/ui/issues/issue-47184.stderr2
-rw-r--r--src/test/ui/issues/issue-47511.stderr18
-rw-r--r--src/test/ui/issues/issue-48728.rs2
-rw-r--r--src/test/ui/issues/issue-48728.stderr2
-rw-r--r--src/test/ui/issues/issue-50576.stderr8
-rw-r--r--src/test/ui/issues/issue-50581.stderr4
-rw-r--r--src/test/ui/issues/issue-52049.stderr2
-rw-r--r--src/test/ui/issues/issue-52262.rs1
-rw-r--r--src/test/ui/issues/issue-52262.stderr2
-rw-r--r--src/test/ui/issues/issue-56835.stderr2
-rw-r--r--src/test/ui/issues/issue-63983.stderr10
-rw-r--r--src/test/ui/issues/issue-67552.stderr2
-rw-r--r--src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr5
-rw-r--r--src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs2
-rw-r--r--src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr8
-rw-r--r--src/test/ui/issues/issue-71584.rs3
-rw-r--r--src/test/ui/issues/issue-7607-1.stderr4
-rw-r--r--src/test/ui/issues/issue-7970a.stderr6
-rw-r--r--src/test/ui/issues/issue-83048.rs2
-rw-r--r--src/test/ui/issues/issue-83048.stderr4
-rw-r--r--src/test/ui/issues/issue-8727.stderr2
-rw-r--r--src/test/ui/iterators/collect-into-array.rs1
-rw-r--r--src/test/ui/iterators/collect-into-array.stderr2
-rw-r--r--src/test/ui/iterators/collect-into-slice.rs2
-rw-r--r--src/test/ui/iterators/collect-into-slice.stderr6
-rw-r--r--src/test/ui/kindck/kindck-copy.stderr22
-rw-r--r--src/test/ui/lang-items/lang-item-generic-requirements.rs2
-rw-r--r--src/test/ui/lang-items/lang-item-generic-requirements.stderr27
-rw-r--r--src/test/ui/lang-items/lang-item-missing-generator.rs6
-rw-r--r--src/test/ui/lang-items/lang-item-missing-generator.stderr11
-rw-r--r--src/test/ui/lang-items/missing-clone-for-suggestion.rs20
-rw-r--r--src/test/ui/lang-items/missing-clone-for-suggestion.stderr21
-rw-r--r--src/test/ui/late-bound-lifetimes/auxiliary/upstream_alias.rs5
-rw-r--r--src/test/ui/late-bound-lifetimes/cross_crate_alias.rs10
-rw-r--r--src/test/ui/late-bound-lifetimes/downgraded_to_early_through_alias.rs24
-rw-r--r--src/test/ui/late-bound-lifetimes/issue-47511.rs (renamed from src/test/ui/issues/issue-47511.rs)7
-rw-r--r--src/test/ui/late-bound-lifetimes/late_bound_through_alias.rs16
-rw-r--r--src/test/ui/late-bound-lifetimes/mismatched_arg_count.rs12
-rw-r--r--src/test/ui/late-bound-lifetimes/mismatched_arg_count.stderr17
-rw-r--r--src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr20
-rw-r--r--src/test/ui/layout/valid_range_oob.rs15
-rw-r--r--src/test/ui/layout/valid_range_oob.stderr6
-rw-r--r--src/test/ui/lazy-type-alias-impl-trait/freeze_cycle.rs2
-rw-r--r--src/test/ui/let-else/let-else-irrefutable.rs8
-rw-r--r--src/test/ui/let-else/let-else-irrefutable.stderr15
-rw-r--r--src/test/ui/lexer/error-stage.rs80
-rw-r--r--src/test/ui/lexer/error-stage.stderr54
-rw-r--r--src/test/ui/lexer/lex-bad-char-literals-6.stderr18
-rw-r--r--src/test/ui/lexical-scopes.stderr2
-rw-r--r--src/test/ui/lifetimes/borrowck-let-suggestion.stderr2
-rw-r--r--src/test/ui/limits/issue-55878.stderr36
-rw-r--r--src/test/ui/linkage-attr/auxiliary/def_external.rs (renamed from src/test/ui/linkage-attr/auxiliary/def_illtyped_external.rs)0
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-late.rs1
-rw-r--r--src/test/ui/linkage-attr/link-attr-validation-late.stderr48
-rw-r--r--src/test/ui/linkage-attr/linkage-import.rs8
-rw-r--r--src/test/ui/linkage-attr/linkage-requires-raw-ptr.rs11
-rw-r--r--src/test/ui/linkage-attr/linkage-requires-raw-ptr.stderr8
-rw-r--r--src/test/ui/linkage-attr/linkage2.rs9
-rw-r--r--src/test/ui/linkage-attr/linkage2.stderr5
-rw-r--r--src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs2
-rw-r--r--src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr2
-rw-r--r--src/test/ui/lint/dead-code/tuple-struct-field.rs2
-rw-r--r--src/test/ui/lint/dead-code/tuple-struct-field.stderr2
-rw-r--r--src/test/ui/lint/fn_must_use.stderr12
-rw-r--r--src/test/ui/lint/invalid_value.stderr69
-rw-r--r--src/test/ui/lint/issue-103317.fixed14
-rw-r--r--src/test/ui/lint/issue-103317.rs14
-rw-r--r--src/test/ui/lint/issue-103317.stderr17
-rw-r--r--src/test/ui/lint/issue-103435-extra-parentheses.fixed18
-rw-r--r--src/test/ui/lint/issue-103435-extra-parentheses.rs18
-rw-r--r--src/test/ui/lint/issue-103435-extra-parentheses.stderr61
-rw-r--r--src/test/ui/lint/issue-104392.rs11
-rw-r--r--src/test/ui/lint/issue-104392.stderr27
-rw-r--r--src/test/ui/lint/issue-104897.rs6
-rw-r--r--src/test/ui/lint/issue-104897.stderr43
-rw-r--r--src/test/ui/lint/issue-97094.interleaved.stderr53
-rw-r--r--src/test/ui/lint/issue-97094.rs9
-rw-r--r--src/test/ui/lint/issue-97094.stderr (renamed from src/test/ui/lint/issue-97094.nointerleaved.stderr)16
-rw-r--r--src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr24
-rw-r--r--src/test/ui/lint/opaque-ty-ffi-normalization-cycle.rs41
-rw-r--r--src/test/ui/lint/opaque-ty-ffi-normalization-cycle.stderr15
-rw-r--r--src/test/ui/lint/suggestions.stderr6
-rw-r--r--src/test/ui/lint/unused/issue-104397.rs18
-rw-r--r--src/test/ui/lint/unused/issue-88519-unused-paren.rs15
-rw-r--r--src/test/ui/lint/unused/must-use-box-from-raw.stderr2
-rw-r--r--src/test/ui/lint/unused/must-use-ops.rs20
-rw-r--r--src/test/ui/lint/unused/must-use-ops.stderr42
-rw-r--r--src/test/ui/lint/unused/must_use-array.rs7
-rw-r--r--src/test/ui/lint/unused/must_use-array.stderr28
-rw-r--r--src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr10
-rw-r--r--src/test/ui/lint/unused/must_use-trait.stderr6
-rw-r--r--src/test/ui/lint/unused/must_use-unit.stderr4
-rw-r--r--src/test/ui/lint/unused/unused-async.rs29
-rw-r--r--src/test/ui/lint/unused/unused-async.stderr79
-rw-r--r--src/test/ui/lint/unused/unused-closure.stderr14
-rw-r--r--src/test/ui/lint/unused/unused-result.stderr8
-rw-r--r--src/test/ui/lint/unused/unused-supertrait.stderr2
-rw-r--r--src/test/ui/lint/unused/unused_attributes-must_use.stderr14
-rw-r--r--src/test/ui/liveness/liveness-move-call-arg.stderr16
-rw-r--r--src/test/ui/liveness/liveness-move-in-loop.stderr14
-rw-r--r--src/test/ui/liveness/liveness-move-in-while.stderr12
-rw-r--r--src/test/ui/liveness/liveness-use-after-move.stderr4
-rw-r--r--src/test/ui/liveness/liveness-use-after-send.stderr9
-rw-r--r--src/test/ui/lto/auxiliary/thinlto-dylib.rs23
-rw-r--r--src/test/ui/lto/issue-105637.rs28
-rw-r--r--src/test/ui/lto/issue-105637.run.stderr1
-rw-r--r--src/test/ui/macros/assert-trailing-junk.with-generic-asset.stderr4
-rw-r--r--src/test/ui/macros/assert-trailing-junk.without-generic-asset.stderr4
-rw-r--r--src/test/ui/macros/attr-from-macro.rs (renamed from src/test/ui/attr-from-macro.rs)0
-rw-r--r--src/test/ui/macros/auxiliary/attr-from-macro.rs (renamed from src/test/ui/auxiliary/attr-from-macro.rs)0
-rw-r--r--src/test/ui/macros/issue-103529.rs13
-rw-r--r--src/test/ui/macros/issue-103529.stderr39
-rw-r--r--src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.rs8
-rw-r--r--src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.stderr16
-rw-r--r--src/test/ui/macros/issue-105011.rs3
-rw-r--r--src/test/ui/macros/issue-105011.stderr8
-rw-r--r--src/test/ui/macros/issue-38715.rs12
-rw-r--r--src/test/ui/macros/issue-38715.stderr15
-rw-r--r--src/test/ui/macros/issue-68060.rs4
-rw-r--r--src/test/ui/macros/issue-68060.stderr18
-rw-r--r--src/test/ui/macros/macro-at-most-once-rep-2015.stderr54
-rw-r--r--src/test/ui/macros/macro-at-most-once-rep-2018.stderr54
-rw-r--r--src/test/ui/macros/macro-non-lifetime.stderr6
-rw-r--r--src/test/ui/macros/missing-comma.stderr36
-rw-r--r--src/test/ui/macros/nonterminal-matching.stderr8
-rw-r--r--src/test/ui/macros/recovery-allowed.rs8
-rw-r--r--src/test/ui/macros/recovery-allowed.stderr10
-rw-r--r--src/test/ui/macros/recovery-forbidden.rs13
-rw-r--r--src/test/ui/macros/syntax-error-recovery.stderr1
-rw-r--r--src/test/ui/macros/trace_faulty_macros.stderr1
-rw-r--r--src/test/ui/match/issue-12552.rs (renamed from src/test/ui/issues/issue-12552.rs)0
-rw-r--r--src/test/ui/match/issue-12552.stderr (renamed from src/test/ui/issues/issue-12552.stderr)0
-rw-r--r--src/test/ui/maximal_mir_to_hir_coverage.rs10
-rw-r--r--src/test/ui/methods/method-call-lifetime-args-fail.stderr8
-rw-r--r--src/test/ui/methods/method-path-in-pattern.stderr12
-rw-r--r--src/test/ui/mir/important-higher-ranked-regions.rs26
-rw-r--r--src/test/ui/mir/mir_ascription_coercion.rs2
-rw-r--r--src/test/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs (renamed from src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs)0
-rw-r--r--src/test/ui/mir/validate/needs-reveal-all.rs52
-rw-r--r--src/test/ui/mismatched_types/binops.stderr13
-rw-r--r--src/test/ui/mismatched_types/overloaded-calls-bad.rs19
-rw-r--r--src/test/ui/mismatched_types/overloaded-calls-bad.stderr22
-rw-r--r--src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs4
-rw-r--r--src/test/ui/moves/borrow-closures-instead-of-move.stderr15
-rw-r--r--src/test/ui/moves/issue-46099-move-in-macro.stderr5
-rw-r--r--src/test/ui/moves/issue-72649-uninit-in-loop.rs6
-rw-r--r--src/test/ui/moves/issue-72649-uninit-in-loop.stderr10
-rw-r--r--src/test/ui/moves/move-fn-self-receiver.stderr10
-rw-r--r--src/test/ui/moves/move-guard-same-consts.stderr12
-rw-r--r--src/test/ui/moves/move-in-guard-1.stderr12
-rw-r--r--src/test/ui/moves/move-in-guard-2.stderr12
-rw-r--r--src/test/ui/moves/moves-based-on-type-access-to-field.stderr4
-rw-r--r--src/test/ui/moves/moves-based-on-type-cyclic-types-issue-4821.stderr2
-rw-r--r--src/test/ui/moves/moves-based-on-type-distribute-copy-over-paren.stderr10
-rw-r--r--src/test/ui/moves/moves-based-on-type-exprs.stderr60
-rw-r--r--src/test/ui/moves/moves-based-on-type-match-bindings.stderr4
-rw-r--r--src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs4
-rw-r--r--src/test/ui/moves/moves-based-on-type-tuple.stderr5
-rw-r--r--src/test/ui/moves/use_of_moved_value_clone_suggestions.stderr5
-rw-r--r--src/test/ui/namespace/namespace-mix.rs4
-rw-r--r--src/test/ui/namespace/namespace-mix.stderr20
-rw-r--r--src/test/ui/never_type/exhaustive_patterns.rs21
-rw-r--r--src/test/ui/never_type/exhaustive_patterns.stderr25
-rw-r--r--src/test/ui/never_type/issue-13352.stderr13
-rw-r--r--src/test/ui/nll/borrowed-temporary-error.stderr2
-rw-r--r--src/test/ui/nll/closure-access-spans.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs3
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr13
-rw-r--r--src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr2
-rw-r--r--src/test/ui/nll/issue-21232-partial-init-and-use.stderr24
-rw-r--r--src/test/ui/nll/issue-48623-generator.stderr2
-rw-r--r--src/test/ui/nll/issue-51512.stderr5
-rw-r--r--src/test/ui/nll/issue-53807.stderr2
-rw-r--r--src/test/ui/nll/issue-54943.rs (renamed from src/test/ui/issues/issue-54943.rs)0
-rw-r--r--src/test/ui/nll/issue-54943.stderr (renamed from src/test/ui/issues/issue-54943.stderr)0
-rw-r--r--src/test/ui/nll/issue-57265-return-type-wf-check.stderr2
-rw-r--r--src/test/ui/nll/issue-57843.rs (renamed from src/test/ui/issues/issue-57843.rs)0
-rw-r--r--src/test/ui/nll/issue-57843.stderr (renamed from src/test/ui/issues/issue-57843.stderr)0
-rw-r--r--src/test/ui/nll/issue-98589-closures-relate-named-regions.stderr8
-rw-r--r--src/test/ui/nll/issue-98693.rs2
-rw-r--r--src/test/ui/nll/issue-98693.stderr9
-rw-r--r--src/test/ui/nll/match-cfg-fake-edges.stderr5
-rw-r--r--src/test/ui/nll/ref-suggestion.stderr12
-rw-r--r--src/test/ui/nll/ty-outlives/impl-trait-captures.stderr2
-rw-r--r--src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr8
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr8
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr15
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr8
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs5
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr36
-rw-r--r--src/test/ui/nll/user-annotations/ascribed-type-wf.rs16
-rw-r--r--src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs6
-rw-r--r--src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr4
-rw-r--r--src/test/ui/nll/user-annotations/patterns.stderr6
-rw-r--r--src/test/ui/nll/user-annotations/type_ascription_static_lifetime.rs2
-rw-r--r--src/test/ui/nll/user-annotations/type_ascription_static_lifetime.stderr10
-rw-r--r--src/test/ui/numbers-arithmetic/not-suggest-float-literal.stderr141
-rw-r--r--src/test/ui/numbers-arithmetic/suggest-float-literal.stderr88
-rw-r--r--src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr6
-rw-r--r--src/test/ui/on-unimplemented/issue-104140.rs8
-rw-r--r--src/test/ui/on-unimplemented/issue-104140.stderr15
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr12
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-pass.rs10
-rw-r--r--src/test/ui/overloaded/overloaded-calls-nontuple.rs17
-rw-r--r--src/test/ui/overloaded/overloaded-calls-nontuple.stderr47
-rw-r--r--src/test/ui/panic-handler/panic-handler-std.stderr8
-rw-r--r--src/test/ui/parser/bad-lit-suffixes.rs18
-rw-r--r--src/test/ui/parser/bad-lit-suffixes.stderr60
-rw-r--r--src/test/ui/parser/byte-literals.rs2
-rw-r--r--src/test/ui/parser/byte-literals.stderr4
-rw-r--r--src/test/ui/parser/byte-string-literals.rs4
-rw-r--r--src/test/ui/parser/byte-string-literals.stderr6
-rw-r--r--src/test/ui/parser/expr-as-stmt.fixed12
-rw-r--r--src/test/ui/parser/expr-as-stmt.rs12
-rw-r--r--src/test/ui/parser/expr-as-stmt.stderr43
-rw-r--r--src/test/ui/parser/issue-101477-enum.stderr2
-rw-r--r--src/test/ui/parser/issue-102806.rs25
-rw-r--r--src/test/ui/parser/issue-102806.stderr45
-rw-r--r--src/test/ui/parser/issue-103381.fixed59
-rw-r--r--src/test/ui/parser/issue-103381.rs59
-rw-r--r--src/test/ui/parser/issue-103381.stderr50
-rw-r--r--src/test/ui/parser/issue-103451.rs5
-rw-r--r--src/test/ui/parser/issue-103451.stderr32
-rw-r--r--src/test/ui/parser/issue-103748-ICE-wrong-braces.rs8
-rw-r--r--src/test/ui/parser/issue-103748-ICE-wrong-braces.stderr51
-rw-r--r--src/test/ui/parser/issue-103869.rs9
-rw-r--r--src/test/ui/parser/issue-103869.stderr16
-rw-r--r--src/test/ui/parser/issue-104620.rs4
-rw-r--r--src/test/ui/parser/issue-104620.stderr8
-rw-r--r--src/test/ui/parser/issues/issue-104088.rs26
-rw-r--r--src/test/ui/parser/issues/issue-104088.stderr29
-rw-r--r--src/test/ui/parser/item-kw-case-mismatch.fixed34
-rw-r--r--src/test/ui/parser/item-kw-case-mismatch.rs34
-rw-r--r--src/test/ui/parser/item-kw-case-mismatch.stderr86
-rw-r--r--src/test/ui/parser/kw-in-trait-bounds.stderr16
-rw-r--r--src/test/ui/parser/macro/issue-37113.stderr1
-rw-r--r--src/test/ui/parser/macro/macro-doc-comments-1.stderr6
-rw-r--r--src/test/ui/parser/macro/macro-doc-comments-2.stderr6
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-literals.rs2
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-literals.stderr2
-rw-r--r--src/test/ui/parser/recover-fn-ptr-with-generics.rs31
-rw-r--r--src/test/ui/parser/recover-fn-ptr-with-generics.stderr111
-rw-r--r--src/test/ui/parser/recover-from-bad-variant.stderr11
-rw-r--r--src/test/ui/parser/slowparse-bstring.rs (renamed from src/test/ui/slowparse-bstring.rs)0
-rw-r--r--src/test/ui/parser/slowparse-string.rs (renamed from src/test/ui/slowparse-string.rs)0
-rw-r--r--src/test/ui/parser/struct-literal-variant-in-if.stderr9
-rw-r--r--src/test/ui/parser/underscore-suffix-for-string.rs17
-rw-r--r--src/test/ui/parser/underscore-suffix-for-string.stderr13
-rw-r--r--src/test/ui/parser/unicode-control-codepoints.rs16
-rw-r--r--src/test/ui/parser/unicode-control-codepoints.stderr24
-rw-r--r--src/test/ui/parser/use-colon-as-mod-sep.rs11
-rw-r--r--src/test/ui/parser/use-colon-as-mod-sep.stderr28
-rw-r--r--src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr14
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr31
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr4
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr5
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr148
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr25
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr20
-rw-r--r--src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr4
-rw-r--r--src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr10
-rw-r--r--src/test/ui/pattern/issue-52240.rs (renamed from src/test/ui/issues/issue-52240.rs)0
-rw-r--r--src/test/ui/pattern/issue-52240.stderr (renamed from src/test/ui/issues/issue-52240.stderr)0
-rw-r--r--src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr4
-rw-r--r--src/test/ui/pattern/non-structural-match-types.stderr2
-rw-r--r--src/test/ui/pattern/pattern-binding-disambiguation.rs4
-rw-r--r--src/test/ui/pattern/pattern-binding-disambiguation.stderr20
-rw-r--r--src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs18
-rw-r--r--src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr8
-rw-r--r--src/test/ui/pattern/usefulness/uninhabited.rs2
-rw-r--r--src/test/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr4
-rw-r--r--src/test/ui/privacy/auxiliary/issue-75907.rs (renamed from src/test/ui/issues/auxiliary/issue-75907.rs)0
-rw-r--r--src/test/ui/privacy/effective_visibilities.rs13
-rw-r--r--src/test/ui/privacy/effective_visibilities.stderr58
-rw-r--r--src/test/ui/privacy/effective_visibilities_glob.rs21
-rw-r--r--src/test/ui/privacy/effective_visibilities_glob.stderr26
-rw-r--r--src/test/ui/privacy/effective_visibilities_invariants.rs12
-rw-r--r--src/test/ui/privacy/effective_visibilities_invariants.stderr32
-rw-r--r--src/test/ui/privacy/issue-75906.rs (renamed from src/test/ui/issues/issue-75906.rs)0
-rw-r--r--src/test/ui/privacy/issue-75906.stderr (renamed from src/test/ui/issues/issue-75906.stderr)0
-rw-r--r--src/test/ui/privacy/issue-75907.rs (renamed from src/test/ui/issues/issue-75907.rs)0
-rw-r--r--src/test/ui/privacy/issue-75907.stderr (renamed from src/test/ui/issues/issue-75907.stderr)0
-rw-r--r--src/test/ui/privacy/issue-75907_b.rs (renamed from src/test/ui/issues/issue-75907_b.rs)0
-rw-r--r--src/test/ui/privacy/issue-75907_b.stderr (renamed from src/test/ui/issues/issue-75907_b.stderr)0
-rw-r--r--src/test/ui/proc-macro/amputate-span.stderr4
-rw-r--r--src/test/ui/proc-macro/auxiliary/issue-104884.rs23
-rw-r--r--src/test/ui/proc-macro/expand-expr.rs15
-rw-r--r--src/test/ui/proc-macro/expand-expr.stderr14
-rw-r--r--src/test/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs20
-rw-r--r--src/test/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr48
-rw-r--r--src/test/ui/qualified/qualified-path-params.stderr2
-rw-r--r--src/test/ui/query-system/fn-sig-cycle-arity.rs8
-rw-r--r--src/test/ui/query-system/fn-sig-cycle-arity.stderr9
-rw-r--r--src/test/ui/range/issue-54505-no-std.rs6
-rw-r--r--src/test/ui/range/issue-54505-no-std.stderr38
-rw-r--r--src/test/ui/raw-ref-op/raw-ref-temp-deref.rs6
-rw-r--r--src/test/ui/raw-ref-op/raw-ref-temp.rs40
-rw-r--r--src/test/ui/raw-ref-op/raw-ref-temp.stderr16
-rw-r--r--src/test/ui/reachable/expr_type.rs2
-rw-r--r--src/test/ui/reachable/expr_type.stderr8
-rw-r--r--src/test/ui/recursion/issue-83150.rs3
-rw-r--r--src/test/ui/recursion/issue-83150.stderr7
-rw-r--r--src/test/ui/recursion/recursion.stderr2
-rw-r--r--src/test/ui/regions/issue-102374.rs1
-rw-r--r--src/test/ui/regions/issue-102374.stderr5
-rw-r--r--src/test/ui/regions/issue-11612.rs (renamed from src/test/ui/issues/issue-11612.rs)0
-rw-r--r--src/test/ui/regions/regions-free-region-ordering-caller1.stderr2
-rw-r--r--src/test/ui/regions/regions-var-type-out-of-scope.stderr2
-rw-r--r--src/test/ui/repr/align-with-extern-c-fn.rs (renamed from src/test/ui/align-with-extern-c-fn.rs)0
-rw-r--r--src/test/ui/repr/aligned_enum_cast.rs (renamed from src/test/ui/aligned_enum_cast.rs)0
-rw-r--r--src/test/ui/repr/repr_c_int_align.rs (renamed from src/test/ui/repr_c_int_align.rs)0
-rw-r--r--src/test/ui/resolve/bad-module.stderr12
-rw-r--r--src/test/ui/resolve/blind-item-local-shadow.rs (renamed from src/test/ui/blind-item-local-shadow.rs)0
-rw-r--r--src/test/ui/resolve/issue-101749-2.rs16
-rw-r--r--src/test/ui/resolve/issue-101749-2.stderr9
-rw-r--r--src/test/ui/resolve/issue-101749.fixed19
-rw-r--r--src/test/ui/resolve/issue-101749.rs19
-rw-r--r--src/test/ui/resolve/issue-101749.stderr14
-rw-r--r--src/test/ui/resolve/issue-103474.rs28
-rw-r--r--src/test/ui/resolve/issue-103474.stderr35
-rw-r--r--src/test/ui/resolve/issue-105069.rs11
-rw-r--r--src/test/ui/resolve/issue-105069.stderr21
-rw-r--r--src/test/ui/resolve/issue-18252.rs2
-rw-r--r--src/test/ui/resolve/issue-18252.stderr9
-rw-r--r--src/test/ui/resolve/issue-19452.stderr18
-rw-r--r--src/test/ui/resolve/issue-2356.stderr4
-rw-r--r--src/test/ui/resolve/issue-24968.stderr24
-rw-r--r--src/test/ui/resolve/issue-35675.rs (renamed from src/test/ui/issues/issue-35675.rs)0
-rw-r--r--src/test/ui/resolve/issue-35675.stderr (renamed from src/test/ui/issues/issue-35675.stderr)0
-rw-r--r--src/test/ui/resolve/issue-50599.rs2
-rw-r--r--src/test/ui/resolve/issue-50599.stderr9
-rw-r--r--src/test/ui/resolve/issue-5927.rs (renamed from src/test/ui/issues/issue-5927.rs)0
-rw-r--r--src/test/ui/resolve/issue-5927.stderr (renamed from src/test/ui/issues/issue-5927.stderr)0
-rw-r--r--src/test/ui/resolve/issue-60057.rs (renamed from src/test/ui/issues/issue-60057.rs)0
-rw-r--r--src/test/ui/resolve/issue-60057.stderr (renamed from src/test/ui/issues/issue-60057.stderr)0
-rw-r--r--src/test/ui/resolve/issue-73427.stderr22
-rw-r--r--src/test/ui/resolve/missing-in-namespace.stderr4
-rw-r--r--src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr16
-rw-r--r--src/test/ui/resolve/privacy-enum-ctor.stderr90
-rw-r--r--src/test/ui/resolve/resolve-self-in-impl.stderr30
-rw-r--r--src/test/ui/resolve/typo-suggestion-mistyped-in-path.rs42
-rw-r--r--src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr54
-rw-r--r--src/test/ui/resolve/use_suggestion.stderr14
-rw-r--r--src/test/ui/return/issue-86188-return-not-in-fn-body.stderr12
-rw-r--r--src/test/ui/return/tail-expr-as-potential-return.rs17
-rw-r--r--src/test/ui/return/tail-expr-as-potential-return.stderr21
-rw-r--r--src/test/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs2
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr12
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr6
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/run-pass.rs7
-rw-r--r--src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr6
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr6
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/issue-99938.rs31
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs4
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr11
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs13
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr14
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs19
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-79450.rs20
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/issue-79450.stderr12
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs46
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr18
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs39
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs26
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr8
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs15
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs37
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs45
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs39
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs4
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr10
-rw-r--r--src/test/ui/rfcs/rfc1623-2.rs (renamed from src/test/ui/rfc1623.rs)0
-rw-r--r--src/test/ui/rfcs/rfc1623-2.stderr (renamed from src/test/ui/rfc1623.stderr)8
-rw-r--r--src/test/ui/rfcs/rfc1623-3.rs (renamed from src/test/ui/rfc1623-2.rs)0
-rw-r--r--src/test/ui/rfcs/rfc1623-3.stderr (renamed from src/test/ui/rfc1623-2.stderr)6
-rw-r--r--src/test/ui/sanitize/memory-passing.rs32
-rw-r--r--src/test/ui/self/class-missing-self.stderr4
-rw-r--r--src/test/ui/sized/coinductive-1-gat.rs14
-rw-r--r--src/test/ui/sized/coinductive-1.rs14
-rw-r--r--src/test/ui/sized/coinductive-2.rs28
-rw-r--r--src/test/ui/sized/recursive-type-1.rs10
-rw-r--r--src/test/ui/sized/recursive-type-2.rs13
-rw-r--r--src/test/ui/sized/recursive-type-2.stderr13
-rw-r--r--src/test/ui/span/borrowck-let-suggestion-suffixes.rs6
-rw-r--r--src/test/ui/span/borrowck-let-suggestion-suffixes.stderr6
-rw-r--r--src/test/ui/span/borrowck-ref-into-rvalue.stderr2
-rw-r--r--src/test/ui/span/issue-11925.rs4
-rw-r--r--src/test/ui/span/issue-15480.stderr2
-rw-r--r--src/test/ui/span/issue-35987.stderr3
-rw-r--r--src/test/ui/span/issue-71363.rs2
-rw-r--r--src/test/ui/span/issue-71363.stderr6
-rw-r--r--src/test/ui/span/macro-ty-params.rs4
-rw-r--r--src/test/ui/span/macro-ty-params.stderr8
-rw-r--r--src/test/ui/span/multiline-span-simple.stderr13
-rw-r--r--src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr2
-rw-r--r--src/test/ui/span/slice-borrow.stderr2
-rw-r--r--src/test/ui/specialization/issue-43037.current.stderr (renamed from src/test/ui/specialization/issue-43037.stderr)2
-rw-r--r--src/test/ui/specialization/issue-43037.negative.stderr (renamed from src/test/ui/coherence/issue-100191.stderr)2
-rw-r--r--src/test/ui/specialization/issue-43037.rs2
-rw-r--r--src/test/ui/specialization/issue-45814.current.stderr (renamed from src/test/ui/specialization/issue-45814.stderr)2
-rw-r--r--src/test/ui/specialization/issue-45814.negative.stderr (renamed from src/test/ui/coherence/issue-100191-2.stderr)4
-rw-r--r--src/test/ui/specialization/issue-45814.rs3
-rw-r--r--src/test/ui/specialization/specialization-overlap-negative.stderr2
-rw-r--r--src/test/ui/specialization/specialization-overlap.stderr4
-rw-r--r--src/test/ui/static/issue-5216.rs (renamed from src/test/ui/issues/issue-5216.rs)0
-rw-r--r--src/test/ui/static/issue-5216.stderr (renamed from src/test/ui/issues/issue-5216.stderr)0
-rw-r--r--src/test/ui/static/static-drop-scope.stderr4
-rw-r--r--src/test/ui/static/static-reference-to-fn-2.stderr6
-rw-r--r--src/test/ui/static/static-region-bound.stderr2
-rw-r--r--src/test/ui/statics/issue-44373.stderr2
-rw-r--r--src/test/ui/stats/hir-stats.rs1
-rw-r--r--src/test/ui/stats/hir-stats.stderr234
-rw-r--r--src/test/ui/structs-enums/type-sizes.rs21
-rw-r--r--src/test/ui/structs/multi-line-fru-suggestion.rs22
-rw-r--r--src/test/ui/structs/multi-line-fru-suggestion.stderr25
-rw-r--r--src/test/ui/structs/struct-fn-in-definition.rs1
-rw-r--r--src/test/ui/structs/struct-fn-in-definition.stderr1
-rw-r--r--src/test/ui/structs/struct-record-suggestion.fixed7
-rw-r--r--src/test/ui/structs/struct-record-suggestion.rs3
-rw-r--r--src/test/ui/structs/struct-record-suggestion.stderr27
-rw-r--r--src/test/ui/structs/unresolved-struct-with-fru.rs12
-rw-r--r--src/test/ui/structs/unresolved-struct-with-fru.stderr9
-rw-r--r--src/test/ui/suggestions/assoc-const-as-fn.rs18
-rw-r--r--src/test/ui/suggestions/assoc-const-as-fn.stderr16
-rw-r--r--src/test/ui/suggestions/assoc_fn_without_self.stderr9
-rw-r--r--src/test/ui/suggestions/borrow-for-loop-head.stderr1
-rw-r--r--src/test/ui/suggestions/core-std-import-order-issue-83564.stderr2
-rw-r--r--src/test/ui/suggestions/crate-or-module-typo.stderr12
-rw-r--r--src/test/ui/suggestions/dont-suggest-ufcs-for-const.rs4
-rw-r--r--src/test/ui/suggestions/dont-suggest-ufcs-for-const.stderr9
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr23
-rw-r--r--src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr28
-rw-r--r--src/test/ui/suggestions/if-let-typo.stderr15
-rw-r--r--src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs71
-rw-r--r--src/test/ui/suggestions/impl-trait-missing-lifetime-gated.stderr162
-rw-r--r--src/test/ui/suggestions/inner_type2.rs2
-rw-r--r--src/test/ui/suggestions/inner_type2.stderr2
-rw-r--r--src/test/ui/suggestions/issue-102354.stderr13
-rw-r--r--src/test/ui/suggestions/issue-104086-suggest-let.rs30
-rw-r--r--src/test/ui/suggestions/issue-104086-suggest-let.stderr135
-rw-r--r--src/test/ui/suggestions/issue-104287.rs9
-rw-r--r--src/test/ui/suggestions/issue-104287.stderr36
-rw-r--r--src/test/ui/suggestions/issue-84700.stderr10
-rw-r--r--src/test/ui/suggestions/issue-99240-2.stderr6
-rw-r--r--src/test/ui/suggestions/missing-lifetime-specifier.stderr24
-rw-r--r--src/test/ui/suggestions/multibyte-escapes.rs12
-rw-r--r--src/test/ui/suggestions/multibyte-escapes.stderr12
-rw-r--r--src/test/ui/suggestions/option-to-bool.rs9
-rw-r--r--src/test/ui/suggestions/option-to-bool.stderr16
-rw-r--r--src/test/ui/suggestions/ref-pattern-binding.fixed19
-rw-r--r--src/test/ui/suggestions/ref-pattern-binding.rs19
-rw-r--r--src/test/ui/suggestions/ref-pattern-binding.stderr107
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-deref.fixed15
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-deref.rs15
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-deref.stderr19
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs11
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr22
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr4
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed26
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs19
-rw-r--r--src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr88
-rw-r--r--src/test/ui/suggestions/suggest-remove-refs-3.stderr4
-rw-r--r--src/test/ui/suggestions/suggest-tryinto-edition-change.rs5
-rw-r--r--src/test/ui/suggestions/suggest-tryinto-edition-change.stderr11
-rw-r--r--src/test/ui/suggestions/suggest_print_over_printf.rs8
-rw-r--r--src/test/ui/suggestions/suggest_print_over_printf.stderr14
-rw-r--r--src/test/ui/suggestions/try-removing-the-field.rs15
-rw-r--r--src/test/ui/suggestions/try-removing-the-field.stderr16
-rw-r--r--src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs6
-rw-r--r--src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr59
-rw-r--r--src/test/ui/target-feature/invalid-attribute.stderr72
-rw-r--r--src/test/ui/target-feature/tied-features-cli.one.stderr2
-rw-r--r--src/test/ui/target-feature/tied-features-cli.three.stderr2
-rw-r--r--src/test/ui/target-feature/tied-features-cli.two.stderr2
-rw-r--r--src/test/ui/test-attrs/test-thread-capture.run.stdout2
-rw-r--r--src/test/ui/test-attrs/test-thread-nocapture.run.stderr2
-rw-r--r--src/test/ui/threads-sendsync/mpsc_stress.rs67
-rw-r--r--src/test/ui/track-diagnostics/track.rs11
-rw-r--r--src/test/ui/track-diagnostics/track.stderr26
-rw-r--r--src/test/ui/track-diagnostics/track2.rs10
-rw-r--r--src/test/ui/track-diagnostics/track2.stderr18
-rw-r--r--src/test/ui/track-diagnostics/track3.rs10
-rw-r--r--src/test/ui/track-diagnostics/track3.stderr18
-rw-r--r--src/test/ui/track-diagnostics/track4.rs13
-rw-r--r--src/test/ui/track-diagnostics/track4.stderr14
-rw-r--r--src/test/ui/track-diagnostics/track5.rs8
-rw-r--r--src/test/ui/track-diagnostics/track5.stderr9
-rw-r--r--src/test/ui/track-diagnostics/track6.rs14
-rw-r--r--src/test/ui/track-diagnostics/track6.stderr13
-rw-r--r--src/test/ui/trait-bounds/impl-bound-with-references-error.rs20
-rw-r--r--src/test/ui/trait-bounds/impl-bound-with-references-error.stderr24
-rw-r--r--src/test/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.rs38
-rw-r--r--src/test/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr36
-rw-r--r--src/test/ui/traits/alias/issue-83613.rs1
-rw-r--r--src/test/ui/traits/alias/issue-83613.stderr14
-rw-r--r--src/test/ui/traits/invalid_operator_trait.rs23
-rw-r--r--src/test/ui/traits/invalid_operator_trait.stderr8
-rw-r--r--src/test/ui/traits/issue-102989.rs4
-rw-r--r--src/test/ui/traits/issue-102989.stderr31
-rw-r--r--src/test/ui/traits/issue-104322.rs80
-rw-r--r--src/test/ui/traits/issue-33140-hack-boundaries.stderr30
-rw-r--r--src/test/ui/traits/issue-33140.stderr8
-rw-r--r--src/test/ui/traits/issue-7013.rs (renamed from src/test/ui/issues/issue-7013.rs)0
-rw-r--r--src/test/ui/traits/issue-7013.stderr (renamed from src/test/ui/issues/issue-7013.stderr)0
-rw-r--r--src/test/ui/traits/issue-77982.stderr7
-rw-r--r--src/test/ui/traits/issue-79458.stderr5
-rw-r--r--src/test/ui/traits/issue-82830.rs4
-rw-r--r--src/test/ui/traits/issue-82830.stderr15
-rw-r--r--src/test/ui/traits/issue-91949-hangs-on-recursion.rs1
-rw-r--r--src/test/ui/traits/issue-91949-hangs-on-recursion.stderr5
-rw-r--r--src/test/ui/traits/item-privacy.stderr5
-rw-r--r--src/test/ui/traits/negative-impls/eager-mono.rs12
-rw-r--r--src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr2
-rw-r--r--src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr2
-rw-r--r--src/test/ui/traits/object/issue-33140-traitobject-crate.stderr24
-rw-r--r--src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr2
-rw-r--r--src/test/ui/traits/suggest-fully-qualified-closure.rs24
-rw-r--r--src/test/ui/traits/suggest-fully-qualified-closure.stderr34
-rw-r--r--src/test/ui/traits/trait-upcasting/basic.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/diamond.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/invalid-upcast.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/invalid-upcast.stderr30
-rw-r--r--src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/lifetime.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/migrate-lint-deny.rs6
-rw-r--r--src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr11
-rw-r--r--src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs3
-rw-r--r--src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr2
-rw-r--r--src/test/ui/traits/trait-upcasting/replace-vptr.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/struct.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/subtrait-method.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/subtrait-method.stderr20
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-1.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr4
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-2.rs1
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr8
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr8
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-3.rs5
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr4
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr39
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-4.rs13
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr12
-rw-r--r--src/test/ui/transmutability/arrays/issue-103783-array-length.rs24
-rw-r--r--src/test/ui/transmutability/arrays/issue-103783-array-length.stderr9
-rw-r--r--src/test/ui/transmute/transmute-padding-ice.rs29
-rw-r--r--src/test/ui/transmute/transmute-padding-ice.stderr24
-rw-r--r--src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr4
-rw-r--r--src/test/ui/try-trait/bad-interconversion.stderr11
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr2
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs2
-rw-r--r--src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr10
-rw-r--r--src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr40
-rw-r--r--src/test/ui/type-alias-impl-trait/coherence.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/coherence.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/coherence_generalization.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs33
-rw-r--r--src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr30
-rw-r--r--src/test/ui/type-alias-impl-trait/impl_trait_for_tait.rs21
-rw-r--r--src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs38
-rw-r--r--src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs3
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr26
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65384.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65384.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs9
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/missing_lifetime_bound.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/missing_lifetime_bound.stderr7
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr10
-rw-r--r--src/test/ui/type-alias-impl-trait/self-referential-2.stderr11
-rw-r--r--src/test/ui/type-alias-impl-trait/self-referential-4.stderr33
-rw-r--r--src/test/ui/type-alias-impl-trait/self-referential.stderr33
-rw-r--r--src/test/ui/type-alias-impl-trait/self_implication.rs38
-rw-r--r--src/test/ui/type/issue-103271.rs18
-rw-r--r--src/test/ui/type/issue-103271.stderr25
-rw-r--r--src/test/ui/type/issue-94187-verbose-type-name.rs13
-rw-r--r--src/test/ui/type/type-ascription-soundness.rs8
-rw-r--r--src/test/ui/type/type-ascription-soundness.stderr24
-rw-r--r--src/test/ui/type/type-ascription.rs20
-rw-r--r--src/test/ui/type/type-check-defaults.stderr11
-rw-r--r--src/test/ui/type/type-dependent-def-issue-49241.rs2
-rw-r--r--src/test/ui/type/type-dependent-def-issue-49241.stderr9
-rw-r--r--src/test/ui/type_length_limit.rs11
-rw-r--r--src/test/ui/type_length_limit.stderr15
-rw-r--r--src/test/ui/typeck/issue-103899.rs30
-rw-r--r--src/test/ui/typeck/issue-104510-ice.rs16
-rw-r--r--src/test/ui/typeck/issue-104510-ice.stderr9
-rw-r--r--src/test/ui/typeck/issue-104513-ice.rs6
-rw-r--r--src/test/ui/typeck/issue-104513-ice.stderr18
-rw-r--r--src/test/ui/typeck/issue-10969.rs (renamed from src/test/ui/issues/issue-10969.rs)0
-rw-r--r--src/test/ui/typeck/issue-10969.stderr (renamed from src/test/ui/issues/issue-10969.stderr)0
-rw-r--r--src/test/ui/typeck/issue-50687-ice-on-borrow.rs (renamed from src/test/ui/issues/issue-50687-ice-on-borrow.rs)0
-rw-r--r--src/test/ui/typeck/issue-50687-ice-on-borrow.stderr (renamed from src/test/ui/issues/issue-50687-ice-on-borrow.stderr)0
-rw-r--r--src/test/ui/typeck/issue-81293.stderr13
-rw-r--r--src/test/ui/typeck/issue-83693.stderr4
-rw-r--r--src/test/ui/typeck/issue-91267.rs4
-rw-r--r--src/test/ui/typeck/issue-91267.stderr21
-rw-r--r--src/test/ui/typeck/path-to-method-sugg-unresolved-expr.rs4
-rw-r--r--src/test/ui/typeck/path-to-method-sugg-unresolved-expr.stderr9
-rw-r--r--src/test/ui/typeof/issue-29184.rs (renamed from src/test/ui/issues/issue-29184.rs)0
-rw-r--r--src/test/ui/typeof/issue-29184.stderr (renamed from src/test/ui/issues/issue-29184.stderr)0
-rw-r--r--src/test/ui/typeof/issue-42060.rs (renamed from src/test/ui/issues/issue-42060.rs)0
-rw-r--r--src/test/ui/typeof/issue-42060.stderr (renamed from src/test/ui/issues/issue-42060.stderr)0
-rw-r--r--src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr22
-rw-r--r--src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs2
-rw-r--r--src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr20
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-illegal-move.rs8
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs6
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr4
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs4
-rw-r--r--src/test/ui/underscore-ident-matcher.stderr6
-rw-r--r--src/test/ui/union/union-move.mirunsafeck.stderr16
-rw-r--r--src/test/ui/union/union-move.thirunsafeck.stderr16
-rw-r--r--src/test/ui/unop-move-semantics.stderr4
-rw-r--r--src/test/ui/unsafe/unsafe-not-inherited.rs26
-rw-r--r--src/test/ui/unsafe/unsafe-not-inherited.stderr24
-rw-r--r--src/test/ui/unsized-locals/borrow-after-move.stderr13
-rw-r--r--src/test/ui/unsized-locals/double-move.stderr8
-rw-r--r--src/test/ui/use/use-after-move-based-on-type.stderr4
-rw-r--r--src/test/ui/use/use-after-move-implicity-coerced-object.stderr8
-rw-r--r--src/test/ui/use/use-crate-self.rs4
-rw-r--r--src/test/ui/use/use-crate-self.stderr8
-rw-r--r--src/test/ui/weird-exprs.rs11
-rw-r--r--src/test/ui/where-clauses/higher-ranked-fn-type.rs2
-rw-r--r--src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr4
-rw-r--r--src/tools/build-manifest/README.md32
-rw-r--r--src/tools/build-manifest/src/main.rs215
-rw-r--r--src/tools/build-manifest/src/manifest.rs5
-rw-r--r--src/tools/build-manifest/src/versions.rs140
-rw-r--r--src/tools/clippy/CHANGELOG.md161
-rw-r--r--src/tools/clippy/CODE_OF_CONDUCT.md69
-rw-r--r--src/tools/clippy/CONTRIBUTING.md33
-rw-r--r--src/tools/clippy/Cargo.toml2
-rw-r--r--src/tools/clippy/README.md14
-rw-r--r--src/tools/clippy/book/src/SUMMARY.md1
-rw-r--r--src/tools/clippy/book/src/configuration.md6
-rw-r--r--src/tools/clippy/book/src/development/adding_lints.md18
-rw-r--r--src/tools/clippy/book/src/development/proposals/syntax-tree-patterns.md986
-rw-r--r--src/tools/clippy/clippy_dev/Cargo.toml1
-rw-r--r--src/tools/clippy/clippy_dev/src/lint.rs8
-rw-r--r--src/tools/clippy/clippy_dev/src/new_lint.rs16
-rw-r--r--src/tools/clippy/clippy_dev/src/setup/git_hook.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs307
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml3
-rw-r--r--src/tools/clippy/clippy_lints/src/almost_complete_letter_range.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/approx_const.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/await_holding_invalid.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/bool_to_int_with_if.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/checked_conversions.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/cognitive_complexity.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/collapsible_if.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs630
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs191
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_macros.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_methods.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_types.rs44
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs128
-rw-r--r--src/tools/clippy/clippy_lints/src/double_parens.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_variants.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/equatable_if_let.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_bools.rs129
-rw-r--r--src/tools/clippy/clippy_lints/src/exit.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/fallible_impl_from.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/format.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs80
-rw-r--r--src/tools/clippy/clippy_lints/src/format_push_string.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/from_over_into.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs77
-rw-r--r--src/tools/clippy/clippy_lints/src/from_str_radix_10.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs125
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/mod.rs47
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/result.rs70
-rw-r--r--src/tools/clippy/clippy_lints/src/future_not_send.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_hasher.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/index_refutable_slice.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/indexing_slicing.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/inherent_to_string.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/instant_subtraction.rs182
-rw-r--r--src/tools/clippy/clippy_lints/src/int_plus_one.rs35
-rw-r--r--src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_enum_variant.rs60
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/let_underscore.rs157
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_all.rs368
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_cargo.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_complexity.rs111
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_correctness.rs78
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_internal.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_lints.rs620
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_nursery.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs104
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_perf.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_restriction.rs90
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_style.rs131
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs371
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs165
-rw-r--r--src/tools/clippy/clippy_lints/src/literal_representation.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mod.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs114
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_use.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_bits.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_clamp.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_instant_elapsed.rs69
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs155
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_let_else.rs295
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_retain.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_string_new.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/map_unit_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/infallible_destructuring_match.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_filter.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/try_err.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_replace.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/chars_last_cmp.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/chars_next_cmp.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/err_expect.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/expect_used.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_nth_zero.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_clone.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs307
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_collect.rs (renamed from src/tools/clippy/clippy_lints/src/loops/needless_collect.rs)223
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs57
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/repeat_once.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/search_is_some.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs48
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs45
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/str_splitn.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs62
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unwrap_used.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/mod.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/zero_prefixed_literal.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs61
-rw-r--r--src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_key.rs155
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_mut.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs108
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_continue.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/octal_escapes.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs110
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/op_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/option_env_unwrap.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/option_if_let_else.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/partialeq_to_none.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/precedence.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/ranges.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_clone.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_field_names.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/renamed_lints.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/single_component_path_imports.rs219
-rw-r--r--src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/swap.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/trailing_empty_array.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/mod.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs164
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/utils.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/types/borrowed_box.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/types/box_collection.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/types/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/types/rc_buffer.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/types/vec_box.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs467
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_async.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_peekable.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_rounding.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_unit.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs35
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs16
-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.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs72
-rw-r--r--src/tools/clippy/clippy_lints/src/wildcard_imports.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs17
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs68
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs24
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs32
-rw-r--r--src/tools/clippy/clippy_utils/src/diagnostics.rs12
-rw-r--r--src/tools/clippy/clippy_utils/src/eager_or_lazy.rs28
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs51
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs355
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs12
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs107
-rw-r--r--src/tools/clippy/clippy_utils/src/numeric_literal.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs33
-rw-r--r--src/tools/clippy/clippy_utils/src/source.rs60
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs68
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs307
-rw-r--r--src/tools/clippy/clippy_utils/src/usage.rs9
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs12
-rw-r--r--src/tools/clippy/declare_clippy_lint/Cargo.toml16
-rw-r--r--src/tools/clippy/declare_clippy_lint/src/lib.rs175
-rw-r--r--src/tools/clippy/lintcheck/src/main.rs62
-rw-r--r--src/tools/clippy/rust-toolchain4
-rw-r--r--src/tools/clippy/src/docs.rs606
-rw-r--r--src/tools/clippy/src/docs/absurd_extreme_comparisons.txt25
-rw-r--r--src/tools/clippy/src/docs/alloc_instead_of_core.txt18
-rw-r--r--src/tools/clippy/src/docs/allow_attributes_without_reason.txt22
-rw-r--r--src/tools/clippy/src/docs/almost_complete_letter_range.txt15
-rw-r--r--src/tools/clippy/src/docs/almost_swapped.txt15
-rw-r--r--src/tools/clippy/src/docs/approx_constant.txt24
-rw-r--r--src/tools/clippy/src/docs/arithmetic_side_effects.txt33
-rw-r--r--src/tools/clippy/src/docs/as_conversions.txt32
-rw-r--r--src/tools/clippy/src/docs/as_ptr_cast_mut.txt19
-rw-r--r--src/tools/clippy/src/docs/as_underscore.txt21
-rw-r--r--src/tools/clippy/src/docs/assertions_on_constants.txt14
-rw-r--r--src/tools/clippy/src/docs/assertions_on_result_states.txt14
-rw-r--r--src/tools/clippy/src/docs/assign_op_pattern.txt28
-rw-r--r--src/tools/clippy/src/docs/async_yields_async.txt28
-rw-r--r--src/tools/clippy/src/docs/await_holding_invalid_type.txt29
-rw-r--r--src/tools/clippy/src/docs/await_holding_lock.txt51
-rw-r--r--src/tools/clippy/src/docs/await_holding_refcell_ref.txt47
-rw-r--r--src/tools/clippy/src/docs/bad_bit_mask.txt30
-rw-r--r--src/tools/clippy/src/docs/bind_instead_of_map.txt22
-rw-r--r--src/tools/clippy/src/docs/blanket_clippy_restriction_lints.txt16
-rw-r--r--src/tools/clippy/src/docs/blocks_in_if_conditions.txt21
-rw-r--r--src/tools/clippy/src/docs/bool_assert_comparison.txt16
-rw-r--r--src/tools/clippy/src/docs/bool_comparison.txt18
-rw-r--r--src/tools/clippy/src/docs/bool_to_int_with_if.txt26
-rw-r--r--src/tools/clippy/src/docs/borrow_as_ptr.txt26
-rw-r--r--src/tools/clippy/src/docs/borrow_deref_ref.txt27
-rw-r--r--src/tools/clippy/src/docs/borrow_interior_mutable_const.txt40
-rw-r--r--src/tools/clippy/src/docs/borrowed_box.txt19
-rw-r--r--src/tools/clippy/src/docs/box_collection.txt23
-rw-r--r--src/tools/clippy/src/docs/box_default.txt17
-rw-r--r--src/tools/clippy/src/docs/boxed_local.txt18
-rw-r--r--src/tools/clippy/src/docs/branches_sharing_code.txt32
-rw-r--r--src/tools/clippy/src/docs/builtin_type_shadow.txt15
-rw-r--r--src/tools/clippy/src/docs/bytes_count_to_len.txt18
-rw-r--r--src/tools/clippy/src/docs/bytes_nth.txt16
-rw-r--r--src/tools/clippy/src/docs/cargo_common_metadata.txt33
-rw-r--r--src/tools/clippy/src/docs/case_sensitive_file_extension_comparisons.txt21
-rw-r--r--src/tools/clippy/src/docs/cast_abs_to_unsigned.txt16
-rw-r--r--src/tools/clippy/src/docs/cast_enum_constructor.txt11
-rw-r--r--src/tools/clippy/src/docs/cast_enum_truncation.txt12
-rw-r--r--src/tools/clippy/src/docs/cast_lossless.txt26
-rw-r--r--src/tools/clippy/src/docs/cast_nan_to_int.txt15
-rw-r--r--src/tools/clippy/src/docs/cast_possible_truncation.txt16
-rw-r--r--src/tools/clippy/src/docs/cast_possible_wrap.txt17
-rw-r--r--src/tools/clippy/src/docs/cast_precision_loss.txt19
-rw-r--r--src/tools/clippy/src/docs/cast_ptr_alignment.txt21
-rw-r--r--src/tools/clippy/src/docs/cast_ref_to_mut.txt28
-rw-r--r--src/tools/clippy/src/docs/cast_sign_loss.txt15
-rw-r--r--src/tools/clippy/src/docs/cast_slice_different_sizes.txt38
-rw-r--r--src/tools/clippy/src/docs/cast_slice_from_raw_parts.txt20
-rw-r--r--src/tools/clippy/src/docs/char_lit_as_u8.txt21
-rw-r--r--src/tools/clippy/src/docs/chars_last_cmp.txt17
-rw-r--r--src/tools/clippy/src/docs/chars_next_cmp.txt19
-rw-r--r--src/tools/clippy/src/docs/checked_conversions.txt15
-rw-r--r--src/tools/clippy/src/docs/clone_double_ref.txt16
-rw-r--r--src/tools/clippy/src/docs/clone_on_copy.txt11
-rw-r--r--src/tools/clippy/src/docs/clone_on_ref_ptr.txt21
-rw-r--r--src/tools/clippy/src/docs/cloned_instead_of_copied.txt16
-rw-r--r--src/tools/clippy/src/docs/cmp_nan.txt16
-rw-r--r--src/tools/clippy/src/docs/cmp_null.txt23
-rw-r--r--src/tools/clippy/src/docs/cmp_owned.txt18
-rw-r--r--src/tools/clippy/src/docs/cognitive_complexity.txt13
-rw-r--r--src/tools/clippy/src/docs/collapsible_else_if.txt29
-rw-r--r--src/tools/clippy/src/docs/collapsible_if.txt23
-rw-r--r--src/tools/clippy/src/docs/collapsible_match.txt31
-rw-r--r--src/tools/clippy/src/docs/collapsible_str_replace.txt19
-rw-r--r--src/tools/clippy/src/docs/comparison_chain.txt36
-rw-r--r--src/tools/clippy/src/docs/comparison_to_empty.txt31
-rw-r--r--src/tools/clippy/src/docs/copy_iterator.txt20
-rw-r--r--src/tools/clippy/src/docs/crate_in_macro_def.txt35
-rw-r--r--src/tools/clippy/src/docs/create_dir.txt15
-rw-r--r--src/tools/clippy/src/docs/crosspointer_transmute.txt12
-rw-r--r--src/tools/clippy/src/docs/dbg_macro.txt16
-rw-r--r--src/tools/clippy/src/docs/debug_assert_with_mut_call.txt18
-rw-r--r--src/tools/clippy/src/docs/decimal_literal_representation.txt13
-rw-r--r--src/tools/clippy/src/docs/declare_interior_mutable_const.txt46
-rw-r--r--src/tools/clippy/src/docs/default_instead_of_iter_empty.txt15
-rw-r--r--src/tools/clippy/src/docs/default_numeric_fallback.txt28
-rw-r--r--src/tools/clippy/src/docs/default_trait_access.txt16
-rw-r--r--src/tools/clippy/src/docs/default_union_representation.txt36
-rw-r--r--src/tools/clippy/src/docs/deprecated_cfg_attr.txt24
-rw-r--r--src/tools/clippy/src/docs/deprecated_semver.txt13
-rw-r--r--src/tools/clippy/src/docs/deref_addrof.txt22
-rw-r--r--src/tools/clippy/src/docs/deref_by_slicing.txt17
-rw-r--r--src/tools/clippy/src/docs/derivable_impls.txt35
-rw-r--r--src/tools/clippy/src/docs/derive_hash_xor_eq.txt23
-rw-r--r--src/tools/clippy/src/docs/derive_ord_xor_partial_ord.txt44
-rw-r--r--src/tools/clippy/src/docs/derive_partial_eq_without_eq.txt25
-rw-r--r--src/tools/clippy/src/docs/disallowed_macros.txt36
-rw-r--r--src/tools/clippy/src/docs/disallowed_methods.txt41
-rw-r--r--src/tools/clippy/src/docs/disallowed_names.txt12
-rw-r--r--src/tools/clippy/src/docs/disallowed_script_idents.txt32
-rw-r--r--src/tools/clippy/src/docs/disallowed_types.txt33
-rw-r--r--src/tools/clippy/src/docs/diverging_sub_expression.txt19
-rw-r--r--src/tools/clippy/src/docs/doc_link_with_quotes.txt16
-rw-r--r--src/tools/clippy/src/docs/doc_markdown.txt35
-rw-r--r--src/tools/clippy/src/docs/double_comparisons.txt17
-rw-r--r--src/tools/clippy/src/docs/double_must_use.txt17
-rw-r--r--src/tools/clippy/src/docs/double_neg.txt12
-rw-r--r--src/tools/clippy/src/docs/double_parens.txt24
-rw-r--r--src/tools/clippy/src/docs/drop_copy.txt15
-rw-r--r--src/tools/clippy/src/docs/drop_non_drop.txt13
-rw-r--r--src/tools/clippy/src/docs/drop_ref.txt17
-rw-r--r--src/tools/clippy/src/docs/duplicate_mod.txt31
-rw-r--r--src/tools/clippy/src/docs/duplicate_underscore_argument.txt16
-rw-r--r--src/tools/clippy/src/docs/duration_subsec.txt19
-rw-r--r--src/tools/clippy/src/docs/else_if_without_else.txt27
-rw-r--r--src/tools/clippy/src/docs/empty_drop.txt20
-rw-r--r--src/tools/clippy/src/docs/empty_enum.txt27
-rw-r--r--src/tools/clippy/src/docs/empty_line_after_outer_attr.txt35
-rw-r--r--src/tools/clippy/src/docs/empty_loop.txt27
-rw-r--r--src/tools/clippy/src/docs/empty_structs_with_brackets.txt14
-rw-r--r--src/tools/clippy/src/docs/enum_clike_unportable_variant.txt16
-rw-r--r--src/tools/clippy/src/docs/enum_glob_use.txt24
-rw-r--r--src/tools/clippy/src/docs/enum_variant_names.txt30
-rw-r--r--src/tools/clippy/src/docs/eq_op.txt22
-rw-r--r--src/tools/clippy/src/docs/equatable_if_let.txt23
-rw-r--r--src/tools/clippy/src/docs/erasing_op.txt15
-rw-r--r--src/tools/clippy/src/docs/err_expect.txt16
-rw-r--r--src/tools/clippy/src/docs/excessive_precision.txt18
-rw-r--r--src/tools/clippy/src/docs/exhaustive_enums.txt23
-rw-r--r--src/tools/clippy/src/docs/exhaustive_structs.txt23
-rw-r--r--src/tools/clippy/src/docs/exit.txt12
-rw-r--r--src/tools/clippy/src/docs/expect_fun_call.txt24
-rw-r--r--src/tools/clippy/src/docs/expect_used.txt26
-rw-r--r--src/tools/clippy/src/docs/expl_impl_clone_on_copy.txt20
-rw-r--r--src/tools/clippy/src/docs/explicit_auto_deref.txt16
-rw-r--r--src/tools/clippy/src/docs/explicit_counter_loop.txt21
-rw-r--r--src/tools/clippy/src/docs/explicit_deref_methods.txt24
-rw-r--r--src/tools/clippy/src/docs/explicit_into_iter_loop.txt20
-rw-r--r--src/tools/clippy/src/docs/explicit_iter_loop.txt25
-rw-r--r--src/tools/clippy/src/docs/explicit_write.txt18
-rw-r--r--src/tools/clippy/src/docs/extend_with_drain.txt21
-rw-r--r--src/tools/clippy/src/docs/extra_unused_lifetimes.txt23
-rw-r--r--src/tools/clippy/src/docs/fallible_impl_from.txt32
-rw-r--r--src/tools/clippy/src/docs/field_reassign_with_default.txt23
-rw-r--r--src/tools/clippy/src/docs/filetype_is_file.txt29
-rw-r--r--src/tools/clippy/src/docs/filter_map_identity.txt14
-rw-r--r--src/tools/clippy/src/docs/filter_map_next.txt16
-rw-r--r--src/tools/clippy/src/docs/filter_next.txt16
-rw-r--r--src/tools/clippy/src/docs/flat_map_identity.txt14
-rw-r--r--src/tools/clippy/src/docs/flat_map_option.txt16
-rw-r--r--src/tools/clippy/src/docs/float_arithmetic.txt11
-rw-r--r--src/tools/clippy/src/docs/float_cmp.txt28
-rw-r--r--src/tools/clippy/src/docs/float_cmp_const.txt26
-rw-r--r--src/tools/clippy/src/docs/float_equality_without_abs.txt26
-rw-r--r--src/tools/clippy/src/docs/fn_address_comparisons.txt17
-rw-r--r--src/tools/clippy/src/docs/fn_params_excessive_bools.txt31
-rw-r--r--src/tools/clippy/src/docs/fn_to_numeric_cast.txt21
-rw-r--r--src/tools/clippy/src/docs/fn_to_numeric_cast_any.txt35
-rw-r--r--src/tools/clippy/src/docs/fn_to_numeric_cast_with_truncation.txt26
-rw-r--r--src/tools/clippy/src/docs/for_kv_map.txt22
-rw-r--r--src/tools/clippy/src/docs/forget_copy.txt21
-rw-r--r--src/tools/clippy/src/docs/forget_non_drop.txt13
-rw-r--r--src/tools/clippy/src/docs/forget_ref.txt15
-rw-r--r--src/tools/clippy/src/docs/format_in_format_args.txt16
-rw-r--r--src/tools/clippy/src/docs/format_push_string.txt26
-rw-r--r--src/tools/clippy/src/docs/from_iter_instead_of_collect.txt24
-rw-r--r--src/tools/clippy/src/docs/from_over_into.txt26
-rw-r--r--src/tools/clippy/src/docs/from_str_radix_10.txt25
-rw-r--r--src/tools/clippy/src/docs/future_not_send.txt29
-rw-r--r--src/tools/clippy/src/docs/get_first.txt19
-rw-r--r--src/tools/clippy/src/docs/get_last_with_len.txt26
-rw-r--r--src/tools/clippy/src/docs/get_unwrap.txt30
-rw-r--r--src/tools/clippy/src/docs/identity_op.txt11
-rw-r--r--src/tools/clippy/src/docs/if_let_mutex.txt25
-rw-r--r--src/tools/clippy/src/docs/if_not_else.txt25
-rw-r--r--src/tools/clippy/src/docs/if_same_then_else.txt15
-rw-r--r--src/tools/clippy/src/docs/if_then_some_else_none.txt26
-rw-r--r--src/tools/clippy/src/docs/ifs_same_cond.txt25
-rw-r--r--src/tools/clippy/src/docs/implicit_clone.txt19
-rw-r--r--src/tools/clippy/src/docs/implicit_hasher.txt26
-rw-r--r--src/tools/clippy/src/docs/implicit_return.txt22
-rw-r--r--src/tools/clippy/src/docs/implicit_saturating_add.txt20
-rw-r--r--src/tools/clippy/src/docs/implicit_saturating_sub.txt21
-rw-r--r--src/tools/clippy/src/docs/imprecise_flops.txt23
-rw-r--r--src/tools/clippy/src/docs/inconsistent_digit_grouping.txt17
-rw-r--r--src/tools/clippy/src/docs/inconsistent_struct_constructor.txt40
-rw-r--r--src/tools/clippy/src/docs/index_refutable_slice.txt29
-rw-r--r--src/tools/clippy/src/docs/indexing_slicing.txt33
-rw-r--r--src/tools/clippy/src/docs/ineffective_bit_mask.txt25
-rw-r--r--src/tools/clippy/src/docs/inefficient_to_string.txt17
-rw-r--r--src/tools/clippy/src/docs/infallible_destructuring_match.txt29
-rw-r--r--src/tools/clippy/src/docs/infinite_iter.txt13
-rw-r--r--src/tools/clippy/src/docs/inherent_to_string.txt29
-rw-r--r--src/tools/clippy/src/docs/inherent_to_string_shadow_display.txt37
-rw-r--r--src/tools/clippy/src/docs/init_numbered_fields.txt24
-rw-r--r--src/tools/clippy/src/docs/inline_always.txt23
-rw-r--r--src/tools/clippy/src/docs/inline_asm_x86_att_syntax.txt16
-rw-r--r--src/tools/clippy/src/docs/inline_asm_x86_intel_syntax.txt16
-rw-r--r--src/tools/clippy/src/docs/inline_fn_without_body.txt14
-rw-r--r--src/tools/clippy/src/docs/inspect_for_each.txt23
-rw-r--r--src/tools/clippy/src/docs/int_plus_one.txt15
-rw-r--r--src/tools/clippy/src/docs/integer_arithmetic.txt18
-rw-r--r--src/tools/clippy/src/docs/integer_division.txt19
-rw-r--r--src/tools/clippy/src/docs/into_iter_on_ref.txt18
-rw-r--r--src/tools/clippy/src/docs/invalid_null_ptr_usage.txt16
-rw-r--r--src/tools/clippy/src/docs/invalid_regex.txt12
-rw-r--r--src/tools/clippy/src/docs/invalid_upcast_comparisons.txt18
-rw-r--r--src/tools/clippy/src/docs/invalid_utf8_in_unchecked.txt12
-rw-r--r--src/tools/clippy/src/docs/invisible_characters.txt10
-rw-r--r--src/tools/clippy/src/docs/is_digit_ascii_radix.txt20
-rw-r--r--src/tools/clippy/src/docs/items_after_statements.txt37
-rw-r--r--src/tools/clippy/src/docs/iter_cloned_collect.txt17
-rw-r--r--src/tools/clippy/src/docs/iter_count.txt22
-rw-r--r--src/tools/clippy/src/docs/iter_kv_map.txt22
-rw-r--r--src/tools/clippy/src/docs/iter_next_loop.txt17
-rw-r--r--src/tools/clippy/src/docs/iter_next_slice.txt16
-rw-r--r--src/tools/clippy/src/docs/iter_not_returning_iterator.txt26
-rw-r--r--src/tools/clippy/src/docs/iter_nth.txt20
-rw-r--r--src/tools/clippy/src/docs/iter_nth_zero.txt17
-rw-r--r--src/tools/clippy/src/docs/iter_on_empty_collections.txt25
-rw-r--r--src/tools/clippy/src/docs/iter_on_single_items.txt24
-rw-r--r--src/tools/clippy/src/docs/iter_overeager_cloned.txt22
-rw-r--r--src/tools/clippy/src/docs/iter_skip_next.txt18
-rw-r--r--src/tools/clippy/src/docs/iter_with_drain.txt16
-rw-r--r--src/tools/clippy/src/docs/iterator_step_by_zero.txt13
-rw-r--r--src/tools/clippy/src/docs/just_underscores_and_digits.txt14
-rw-r--r--src/tools/clippy/src/docs/large_const_arrays.txt17
-rw-r--r--src/tools/clippy/src/docs/large_digit_groups.txt12
-rw-r--r--src/tools/clippy/src/docs/large_enum_variant.txt41
-rw-r--r--src/tools/clippy/src/docs/large_include_file.txt21
-rw-r--r--src/tools/clippy/src/docs/large_stack_arrays.txt10
-rw-r--r--src/tools/clippy/src/docs/large_types_passed_by_value.txt24
-rw-r--r--src/tools/clippy/src/docs/len_without_is_empty.txt19
-rw-r--r--src/tools/clippy/src/docs/len_zero.txt28
-rw-r--r--src/tools/clippy/src/docs/let_and_return.txt21
-rw-r--r--src/tools/clippy/src/docs/let_underscore_drop.txt29
-rw-r--r--src/tools/clippy/src/docs/let_underscore_lock.txt20
-rw-r--r--src/tools/clippy/src/docs/let_underscore_must_use.txt17
-rw-r--r--src/tools/clippy/src/docs/let_unit_value.txt13
-rw-r--r--src/tools/clippy/src/docs/linkedlist.txt32
-rw-r--r--src/tools/clippy/src/docs/lossy_float_literal.txt18
-rw-r--r--src/tools/clippy/src/docs/macro_use_imports.txt12
-rw-r--r--src/tools/clippy/src/docs/main_recursion.txt13
-rw-r--r--src/tools/clippy/src/docs/manual_assert.txt18
-rw-r--r--src/tools/clippy/src/docs/manual_async_fn.txt16
-rw-r--r--src/tools/clippy/src/docs/manual_bits.txt15
-rw-r--r--src/tools/clippy/src/docs/manual_clamp.txt46
-rw-r--r--src/tools/clippy/src/docs/manual_filter.txt21
-rw-r--r--src/tools/clippy/src/docs/manual_filter_map.txt19
-rw-r--r--src/tools/clippy/src/docs/manual_find.txt24
-rw-r--r--src/tools/clippy/src/docs/manual_find_map.txt19
-rw-r--r--src/tools/clippy/src/docs/manual_flatten.txt25
-rw-r--r--src/tools/clippy/src/docs/manual_instant_elapsed.txt21
-rw-r--r--src/tools/clippy/src/docs/manual_map.txt17
-rw-r--r--src/tools/clippy/src/docs/manual_memcpy.txt18
-rw-r--r--src/tools/clippy/src/docs/manual_non_exhaustive.txt41
-rw-r--r--src/tools/clippy/src/docs/manual_ok_or.txt19
-rw-r--r--src/tools/clippy/src/docs/manual_range_contains.txt19
-rw-r--r--src/tools/clippy/src/docs/manual_rem_euclid.txt17
-rw-r--r--src/tools/clippy/src/docs/manual_retain.txt15
-rw-r--r--src/tools/clippy/src/docs/manual_saturating_arithmetic.txt18
-rw-r--r--src/tools/clippy/src/docs/manual_split_once.txt29
-rw-r--r--src/tools/clippy/src/docs/manual_str_repeat.txt15
-rw-r--r--src/tools/clippy/src/docs/manual_string_new.txt20
-rw-r--r--src/tools/clippy/src/docs/manual_strip.txt24
-rw-r--r--src/tools/clippy/src/docs/manual_swap.txt22
-rw-r--r--src/tools/clippy/src/docs/manual_unwrap_or.txt20
-rw-r--r--src/tools/clippy/src/docs/many_single_char_names.txt12
-rw-r--r--src/tools/clippy/src/docs/map_clone.txt22
-rw-r--r--src/tools/clippy/src/docs/map_collect_result_unit.txt14
-rw-r--r--src/tools/clippy/src/docs/map_entry.txt28
-rw-r--r--src/tools/clippy/src/docs/map_err_ignore.txt93
-rw-r--r--src/tools/clippy/src/docs/map_flatten.txt21
-rw-r--r--src/tools/clippy/src/docs/map_identity.txt16
-rw-r--r--src/tools/clippy/src/docs/map_unwrap_or.txt22
-rw-r--r--src/tools/clippy/src/docs/match_as_ref.txt23
-rw-r--r--src/tools/clippy/src/docs/match_bool.txt24
-rw-r--r--src/tools/clippy/src/docs/match_like_matches_macro.txt32
-rw-r--r--src/tools/clippy/src/docs/match_on_vec_items.txt29
-rw-r--r--src/tools/clippy/src/docs/match_overlapping_arm.txt16
-rw-r--r--src/tools/clippy/src/docs/match_ref_pats.txt26
-rw-r--r--src/tools/clippy/src/docs/match_result_ok.txt27
-rw-r--r--src/tools/clippy/src/docs/match_same_arms.txt38
-rw-r--r--src/tools/clippy/src/docs/match_single_binding.txt23
-rw-r--r--src/tools/clippy/src/docs/match_str_case_mismatch.txt22
-rw-r--r--src/tools/clippy/src/docs/match_wild_err_arm.txt16
-rw-r--r--src/tools/clippy/src/docs/match_wildcard_for_single_variants.txt27
-rw-r--r--src/tools/clippy/src/docs/maybe_infinite_iter.txt16
-rw-r--r--src/tools/clippy/src/docs/mem_forget.txt12
-rw-r--r--src/tools/clippy/src/docs/mem_replace_option_with_none.txt21
-rw-r--r--src/tools/clippy/src/docs/mem_replace_with_default.txt18
-rw-r--r--src/tools/clippy/src/docs/mem_replace_with_uninit.txt24
-rw-r--r--src/tools/clippy/src/docs/min_max.txt18
-rw-r--r--src/tools/clippy/src/docs/mismatched_target_os.txt24
-rw-r--r--src/tools/clippy/src/docs/mismatching_type_param_order.txt33
-rw-r--r--src/tools/clippy/src/docs/misrefactored_assign_op.txt20
-rw-r--r--src/tools/clippy/src/docs/missing_const_for_fn.txt40
-rw-r--r--src/tools/clippy/src/docs/missing_docs_in_private_items.txt9
-rw-r--r--src/tools/clippy/src/docs/missing_enforced_import_renames.txt22
-rw-r--r--src/tools/clippy/src/docs/missing_errors_doc.txt21
-rw-r--r--src/tools/clippy/src/docs/missing_inline_in_public_items.txt45
-rw-r--r--src/tools/clippy/src/docs/missing_panics_doc.txt24
-rw-r--r--src/tools/clippy/src/docs/missing_safety_doc.txt26
-rw-r--r--src/tools/clippy/src/docs/missing_spin_loop.txt27
-rw-r--r--src/tools/clippy/src/docs/missing_trait_methods.txt40
-rw-r--r--src/tools/clippy/src/docs/mistyped_literal_suffixes.txt15
-rw-r--r--src/tools/clippy/src/docs/mixed_case_hex_literals.txt16
-rw-r--r--src/tools/clippy/src/docs/mixed_read_write_in_expression.txt32
-rw-r--r--src/tools/clippy/src/docs/mod_module_files.txt22
-rw-r--r--src/tools/clippy/src/docs/module_inception.txt24
-rw-r--r--src/tools/clippy/src/docs/module_name_repetitions.txt20
-rw-r--r--src/tools/clippy/src/docs/modulo_arithmetic.txt15
-rw-r--r--src/tools/clippy/src/docs/modulo_one.txt16
-rw-r--r--src/tools/clippy/src/docs/multi_assignments.txt17
-rw-r--r--src/tools/clippy/src/docs/multiple_crate_versions.txt19
-rw-r--r--src/tools/clippy/src/docs/multiple_inherent_impl.txt26
-rw-r--r--src/tools/clippy/src/docs/must_use_candidate.txt23
-rw-r--r--src/tools/clippy/src/docs/must_use_unit.txt13
-rw-r--r--src/tools/clippy/src/docs/mut_from_ref.txt26
-rw-r--r--src/tools/clippy/src/docs/mut_mut.txt12
-rw-r--r--src/tools/clippy/src/docs/mut_mutex_lock.txt29
-rw-r--r--src/tools/clippy/src/docs/mut_range_bound.txt29
-rw-r--r--src/tools/clippy/src/docs/mutable_key_type.txt61
-rw-r--r--src/tools/clippy/src/docs/mutex_atomic.txt22
-rw-r--r--src/tools/clippy/src/docs/mutex_integer.txt22
-rw-r--r--src/tools/clippy/src/docs/naive_bytecount.txt22
-rw-r--r--src/tools/clippy/src/docs/needless_arbitrary_self_type.txt44
-rw-r--r--src/tools/clippy/src/docs/needless_bitwise_bool.txt22
-rw-r--r--src/tools/clippy/src/docs/needless_bool.txt26
-rw-r--r--src/tools/clippy/src/docs/needless_borrow.txt21
-rw-r--r--src/tools/clippy/src/docs/needless_borrowed_reference.txt22
-rw-r--r--src/tools/clippy/src/docs/needless_collect.txt14
-rw-r--r--src/tools/clippy/src/docs/needless_continue.txt61
-rw-r--r--src/tools/clippy/src/docs/needless_doctest_main.txt22
-rw-r--r--src/tools/clippy/src/docs/needless_for_each.txt24
-rw-r--r--src/tools/clippy/src/docs/needless_late_init.txt42
-rw-r--r--src/tools/clippy/src/docs/needless_lifetimes.txt29
-rw-r--r--src/tools/clippy/src/docs/needless_match.txt36
-rw-r--r--src/tools/clippy/src/docs/needless_option_as_deref.txt18
-rw-r--r--src/tools/clippy/src/docs/needless_option_take.txt17
-rw-r--r--src/tools/clippy/src/docs/needless_parens_on_range_literals.txt23
-rw-r--r--src/tools/clippy/src/docs/needless_pass_by_value.txt27
-rw-r--r--src/tools/clippy/src/docs/needless_question_mark.txt43
-rw-r--r--src/tools/clippy/src/docs/needless_range_loop.txt23
-rw-r--r--src/tools/clippy/src/docs/needless_return.txt19
-rw-r--r--src/tools/clippy/src/docs/needless_splitn.txt16
-rw-r--r--src/tools/clippy/src/docs/needless_update.txt30
-rw-r--r--src/tools/clippy/src/docs/neg_cmp_op_on_partial_ord.txt26
-rw-r--r--src/tools/clippy/src/docs/neg_multiply.txt18
-rw-r--r--src/tools/clippy/src/docs/negative_feature_names.txt22
-rw-r--r--src/tools/clippy/src/docs/never_loop.txt15
-rw-r--r--src/tools/clippy/src/docs/new_ret_no_self.txt47
-rw-r--r--src/tools/clippy/src/docs/new_without_default.txt32
-rw-r--r--src/tools/clippy/src/docs/no_effect.txt12
-rw-r--r--src/tools/clippy/src/docs/no_effect_replace.txt11
-rw-r--r--src/tools/clippy/src/docs/no_effect_underscore_binding.txt16
-rw-r--r--src/tools/clippy/src/docs/non_ascii_literal.txt19
-rw-r--r--src/tools/clippy/src/docs/non_octal_unix_permissions.txt23
-rw-r--r--src/tools/clippy/src/docs/non_send_fields_in_send_ty.txt36
-rw-r--r--src/tools/clippy/src/docs/nonminimal_bool.txt23
-rw-r--r--src/tools/clippy/src/docs/nonsensical_open_options.txt14
-rw-r--r--src/tools/clippy/src/docs/nonstandard_macro_braces.txt15
-rw-r--r--src/tools/clippy/src/docs/not_unsafe_ptr_arg_deref.txt30
-rw-r--r--src/tools/clippy/src/docs/obfuscated_if_else.txt21
-rw-r--r--src/tools/clippy/src/docs/octal_escapes.txt33
-rw-r--r--src/tools/clippy/src/docs/ok_expect.txt19
-rw-r--r--src/tools/clippy/src/docs/only_used_in_recursion.txt58
-rw-r--r--src/tools/clippy/src/docs/op_ref.txt17
-rw-r--r--src/tools/clippy/src/docs/option_as_ref_deref.txt15
-rw-r--r--src/tools/clippy/src/docs/option_env_unwrap.txt19
-rw-r--r--src/tools/clippy/src/docs/option_filter_map.txt15
-rw-r--r--src/tools/clippy/src/docs/option_if_let_else.txt46
-rw-r--r--src/tools/clippy/src/docs/option_map_or_none.txt19
-rw-r--r--src/tools/clippy/src/docs/option_map_unit_fn.txt27
-rw-r--r--src/tools/clippy/src/docs/option_option.txt32
-rw-r--r--src/tools/clippy/src/docs/or_fun_call.txt27
-rw-r--r--src/tools/clippy/src/docs/or_then_unwrap.txt22
-rw-r--r--src/tools/clippy/src/docs/out_of_bounds_indexing.txt22
-rw-r--r--src/tools/clippy/src/docs/overflow_check_conditional.txt11
-rw-r--r--src/tools/clippy/src/docs/overly_complex_bool_expr.txt20
-rw-r--r--src/tools/clippy/src/docs/panic.txt10
-rw-r--r--src/tools/clippy/src/docs/panic_in_result_fn.txt22
-rw-r--r--src/tools/clippy/src/docs/panicking_unwrap.txt18
-rw-r--r--src/tools/clippy/src/docs/partial_pub_fields.txt27
-rw-r--r--src/tools/clippy/src/docs/partialeq_ne_impl.txt18
-rw-r--r--src/tools/clippy/src/docs/partialeq_to_none.txt24
-rw-r--r--src/tools/clippy/src/docs/path_buf_push_overwrite.txt25
-rw-r--r--src/tools/clippy/src/docs/pattern_type_mismatch.txt64
-rw-r--r--src/tools/clippy/src/docs/possible_missing_comma.txt14
-rw-r--r--src/tools/clippy/src/docs/precedence.txt17
-rw-r--r--src/tools/clippy/src/docs/print_in_format_impl.txt34
-rw-r--r--src/tools/clippy/src/docs/print_literal.txt16
-rw-r--r--src/tools/clippy/src/docs/print_stderr.txt15
-rw-r--r--src/tools/clippy/src/docs/print_stdout.txt15
-rw-r--r--src/tools/clippy/src/docs/print_with_newline.txt16
-rw-r--r--src/tools/clippy/src/docs/println_empty_string.txt16
-rw-r--r--src/tools/clippy/src/docs/ptr_arg.txt29
-rw-r--r--src/tools/clippy/src/docs/ptr_as_ptr.txt22
-rw-r--r--src/tools/clippy/src/docs/ptr_eq.txt22
-rw-r--r--src/tools/clippy/src/docs/ptr_offset_with_cast.txt30
-rw-r--r--src/tools/clippy/src/docs/pub_use.txt28
-rw-r--r--src/tools/clippy/src/docs/question_mark.txt18
-rw-r--r--src/tools/clippy/src/docs/range_minus_one.txt27
-rw-r--r--src/tools/clippy/src/docs/range_plus_one.txt36
-rw-r--r--src/tools/clippy/src/docs/range_zip_with_len.txt16
-rw-r--r--src/tools/clippy/src/docs/rc_buffer.txt27
-rw-r--r--src/tools/clippy/src/docs/rc_clone_in_vec_init.txt29
-rw-r--r--src/tools/clippy/src/docs/rc_mutex.txt26
-rw-r--r--src/tools/clippy/src/docs/read_zero_byte_vec.txt30
-rw-r--r--src/tools/clippy/src/docs/recursive_format_impl.txt32
-rw-r--r--src/tools/clippy/src/docs/redundant_allocation.txt17
-rw-r--r--src/tools/clippy/src/docs/redundant_clone.txt23
-rw-r--r--src/tools/clippy/src/docs/redundant_closure.txt25
-rw-r--r--src/tools/clippy/src/docs/redundant_closure_call.txt17
-rw-r--r--src/tools/clippy/src/docs/redundant_closure_for_method_calls.txt15
-rw-r--r--src/tools/clippy/src/docs/redundant_else.txt30
-rw-r--r--src/tools/clippy/src/docs/redundant_feature_names.txt23
-rw-r--r--src/tools/clippy/src/docs/redundant_field_names.txt22
-rw-r--r--src/tools/clippy/src/docs/redundant_pattern.txt22
-rw-r--r--src/tools/clippy/src/docs/redundant_pattern_matching.txt45
-rw-r--r--src/tools/clippy/src/docs/redundant_pub_crate.txt21
-rw-r--r--src/tools/clippy/src/docs/redundant_slicing.txt24
-rw-r--r--src/tools/clippy/src/docs/redundant_static_lifetimes.txt19
-rw-r--r--src/tools/clippy/src/docs/ref_binding_to_reference.txt21
-rw-r--r--src/tools/clippy/src/docs/ref_option_ref.txt19
-rw-r--r--src/tools/clippy/src/docs/repeat_once.txt25
-rw-r--r--src/tools/clippy/src/docs/rest_pat_in_fully_bound_structs.txt24
-rw-r--r--src/tools/clippy/src/docs/result_large_err.txt36
-rw-r--r--src/tools/clippy/src/docs/result_map_or_into_option.txt16
-rw-r--r--src/tools/clippy/src/docs/result_map_unit_fn.txt26
-rw-r--r--src/tools/clippy/src/docs/result_unit_err.txt40
-rw-r--r--src/tools/clippy/src/docs/return_self_not_must_use.txt46
-rw-r--r--src/tools/clippy/src/docs/reversed_empty_ranges.txt26
-rw-r--r--src/tools/clippy/src/docs/same_functions_in_if_condition.txt41
-rw-r--r--src/tools/clippy/src/docs/same_item_push.txt29
-rw-r--r--src/tools/clippy/src/docs/same_name_method.txt23
-rw-r--r--src/tools/clippy/src/docs/search_is_some.txt24
-rw-r--r--src/tools/clippy/src/docs/self_assignment.txt32
-rw-r--r--src/tools/clippy/src/docs/self_named_constructors.txt26
-rw-r--r--src/tools/clippy/src/docs/self_named_module_files.txt22
-rw-r--r--src/tools/clippy/src/docs/semicolon_if_nothing_returned.txt20
-rw-r--r--src/tools/clippy/src/docs/separated_literal_suffix.txt17
-rw-r--r--src/tools/clippy/src/docs/serde_api_misuse.txt10
-rw-r--r--src/tools/clippy/src/docs/shadow_reuse.txt20
-rw-r--r--src/tools/clippy/src/docs/shadow_same.txt18
-rw-r--r--src/tools/clippy/src/docs/shadow_unrelated.txt22
-rw-r--r--src/tools/clippy/src/docs/short_circuit_statement.txt14
-rw-r--r--src/tools/clippy/src/docs/should_implement_trait.txt22
-rw-r--r--src/tools/clippy/src/docs/significant_drop_in_scrutinee.txt43
-rw-r--r--src/tools/clippy/src/docs/similar_names.txt16
-rw-r--r--src/tools/clippy/src/docs/single_char_add_str.txt18
-rw-r--r--src/tools/clippy/src/docs/single_char_lifetime_names.txt28
-rw-r--r--src/tools/clippy/src/docs/single_char_pattern.txt20
-rw-r--r--src/tools/clippy/src/docs/single_component_path_imports.txt21
-rw-r--r--src/tools/clippy/src/docs/single_element_loop.txt21
-rw-r--r--src/tools/clippy/src/docs/single_match.txt21
-rw-r--r--src/tools/clippy/src/docs/single_match_else.txt29
-rw-r--r--src/tools/clippy/src/docs/size_of_in_element_count.txt16
-rw-r--r--src/tools/clippy/src/docs/skip_while_next.txt16
-rw-r--r--src/tools/clippy/src/docs/slow_vector_initialization.txt24
-rw-r--r--src/tools/clippy/src/docs/stable_sort_primitive.txt31
-rw-r--r--src/tools/clippy/src/docs/std_instead_of_alloc.txt18
-rw-r--r--src/tools/clippy/src/docs/std_instead_of_core.txt18
-rw-r--r--src/tools/clippy/src/docs/str_to_string.txt18
-rw-r--r--src/tools/clippy/src/docs/string_add.txt27
-rw-r--r--src/tools/clippy/src/docs/string_add_assign.txt17
-rw-r--r--src/tools/clippy/src/docs/string_extend_chars.txt23
-rw-r--r--src/tools/clippy/src/docs/string_from_utf8_as_bytes.txt15
-rw-r--r--src/tools/clippy/src/docs/string_lit_as_bytes.txt39
-rw-r--r--src/tools/clippy/src/docs/string_slice.txt17
-rw-r--r--src/tools/clippy/src/docs/string_to_string.txt19
-rw-r--r--src/tools/clippy/src/docs/strlen_on_c_strings.txt20
-rw-r--r--src/tools/clippy/src/docs/struct_excessive_bools.txt29
-rw-r--r--src/tools/clippy/src/docs/suboptimal_flops.txt50
-rw-r--r--src/tools/clippy/src/docs/suspicious_arithmetic_impl.txt17
-rw-r--r--src/tools/clippy/src/docs/suspicious_assignment_formatting.txt12
-rw-r--r--src/tools/clippy/src/docs/suspicious_else_formatting.txt30
-rw-r--r--src/tools/clippy/src/docs/suspicious_map.txt13
-rw-r--r--src/tools/clippy/src/docs/suspicious_op_assign_impl.txt15
-rw-r--r--src/tools/clippy/src/docs/suspicious_operation_groupings.txt41
-rw-r--r--src/tools/clippy/src/docs/suspicious_splitn.txt22
-rw-r--r--src/tools/clippy/src/docs/suspicious_to_owned.txt39
-rw-r--r--src/tools/clippy/src/docs/suspicious_unary_op_formatting.txt18
-rw-r--r--src/tools/clippy/src/docs/swap_ptr_to_ref.txt23
-rw-r--r--src/tools/clippy/src/docs/tabs_in_doc_comments.txt44
-rw-r--r--src/tools/clippy/src/docs/temporary_assignment.txt12
-rw-r--r--src/tools/clippy/src/docs/to_digit_is_some.txt15
-rw-r--r--src/tools/clippy/src/docs/to_string_in_format_args.txt17
-rw-r--r--src/tools/clippy/src/docs/todo.txt10
-rw-r--r--src/tools/clippy/src/docs/too_many_arguments.txt14
-rw-r--r--src/tools/clippy/src/docs/too_many_lines.txt17
-rw-r--r--src/tools/clippy/src/docs/toplevel_ref_arg.txt28
-rw-r--r--src/tools/clippy/src/docs/trailing_empty_array.txt22
-rw-r--r--src/tools/clippy/src/docs/trait_duplication_in_bounds.txt37
-rw-r--r--src/tools/clippy/src/docs/transmute_bytes_to_str.txt27
-rw-r--r--src/tools/clippy/src/docs/transmute_float_to_int.txt16
-rw-r--r--src/tools/clippy/src/docs/transmute_int_to_bool.txt16
-rw-r--r--src/tools/clippy/src/docs/transmute_int_to_char.txt27
-rw-r--r--src/tools/clippy/src/docs/transmute_int_to_float.txt16
-rw-r--r--src/tools/clippy/src/docs/transmute_num_to_bytes.txt16
-rw-r--r--src/tools/clippy/src/docs/transmute_ptr_to_ptr.txt21
-rw-r--r--src/tools/clippy/src/docs/transmute_ptr_to_ref.txt21
-rw-r--r--src/tools/clippy/src/docs/transmute_undefined_repr.txt22
-rw-r--r--src/tools/clippy/src/docs/transmutes_expressible_as_ptr_casts.txt16
-rw-r--r--src/tools/clippy/src/docs/transmuting_null.txt15
-rw-r--r--src/tools/clippy/src/docs/trim_split_whitespace.txt14
-rw-r--r--src/tools/clippy/src/docs/trivial_regex.txt18
-rw-r--r--src/tools/clippy/src/docs/trivially_copy_pass_by_ref.txt43
-rw-r--r--src/tools/clippy/src/docs/try_err.txt28
-rw-r--r--src/tools/clippy/src/docs/type_complexity.txt14
-rw-r--r--src/tools/clippy/src/docs/type_repetition_in_bounds.txt16
-rw-r--r--src/tools/clippy/src/docs/undocumented_unsafe_blocks.txt43
-rw-r--r--src/tools/clippy/src/docs/undropped_manually_drops.txt22
-rw-r--r--src/tools/clippy/src/docs/unicode_not_nfc.txt12
-rw-r--r--src/tools/clippy/src/docs/unimplemented.txt10
-rw-r--r--src/tools/clippy/src/docs/uninit_assumed_init.txt28
-rw-r--r--src/tools/clippy/src/docs/uninit_vec.txt41
-rw-r--r--src/tools/clippy/src/docs/uninlined_format_args.txt36
-rw-r--r--src/tools/clippy/src/docs/unit_arg.txt14
-rw-r--r--src/tools/clippy/src/docs/unit_cmp.txt33
-rw-r--r--src/tools/clippy/src/docs/unit_hash.txt20
-rw-r--r--src/tools/clippy/src/docs/unit_return_expecting_ord.txt20
-rw-r--r--src/tools/clippy/src/docs/unnecessary_cast.txt19
-rw-r--r--src/tools/clippy/src/docs/unnecessary_filter_map.txt23
-rw-r--r--src/tools/clippy/src/docs/unnecessary_find_map.txt23
-rw-r--r--src/tools/clippy/src/docs/unnecessary_fold.txt17
-rw-r--r--src/tools/clippy/src/docs/unnecessary_join.txt25
-rw-r--r--src/tools/clippy/src/docs/unnecessary_lazy_evaluations.txt32
-rw-r--r--src/tools/clippy/src/docs/unnecessary_mut_passed.txt17
-rw-r--r--src/tools/clippy/src/docs/unnecessary_operation.txt12
-rw-r--r--src/tools/clippy/src/docs/unnecessary_owned_empty_strings.txt16
-rw-r--r--src/tools/clippy/src/docs/unnecessary_self_imports.txt19
-rw-r--r--src/tools/clippy/src/docs/unnecessary_sort_by.txt21
-rw-r--r--src/tools/clippy/src/docs/unnecessary_to_owned.txt24
-rw-r--r--src/tools/clippy/src/docs/unnecessary_unwrap.txt20
-rw-r--r--src/tools/clippy/src/docs/unnecessary_wraps.txt36
-rw-r--r--src/tools/clippy/src/docs/unneeded_field_pattern.txt26
-rw-r--r--src/tools/clippy/src/docs/unneeded_wildcard_pattern.txt28
-rw-r--r--src/tools/clippy/src/docs/unnested_or_patterns.txt22
-rw-r--r--src/tools/clippy/src/docs/unreachable.txt10
-rw-r--r--src/tools/clippy/src/docs/unreadable_literal.txt16
-rw-r--r--src/tools/clippy/src/docs/unsafe_derive_deserialize.txt27
-rw-r--r--src/tools/clippy/src/docs/unsafe_removed_from_name.txt15
-rw-r--r--src/tools/clippy/src/docs/unseparated_literal_suffix.txt18
-rw-r--r--src/tools/clippy/src/docs/unsound_collection_transmute.txt25
-rw-r--r--src/tools/clippy/src/docs/unused_async.txt23
-rw-r--r--src/tools/clippy/src/docs/unused_format_specs.txt24
-rw-r--r--src/tools/clippy/src/docs/unused_io_amount.txt31
-rw-r--r--src/tools/clippy/src/docs/unused_peekable.txt26
-rw-r--r--src/tools/clippy/src/docs/unused_rounding.txt17
-rw-r--r--src/tools/clippy/src/docs/unused_self.txt23
-rw-r--r--src/tools/clippy/src/docs/unused_unit.txt18
-rw-r--r--src/tools/clippy/src/docs/unusual_byte_groupings.txt12
-rw-r--r--src/tools/clippy/src/docs/unwrap_in_result.txt39
-rw-r--r--src/tools/clippy/src/docs/unwrap_or_else_default.txt18
-rw-r--r--src/tools/clippy/src/docs/unwrap_used.txt37
-rw-r--r--src/tools/clippy/src/docs/upper_case_acronyms.txt25
-rw-r--r--src/tools/clippy/src/docs/use_debug.txt12
-rw-r--r--src/tools/clippy/src/docs/use_self.txt31
-rw-r--r--src/tools/clippy/src/docs/used_underscore_binding.txt19
-rw-r--r--src/tools/clippy/src/docs/useless_asref.txt17
-rw-r--r--src/tools/clippy/src/docs/useless_attribute.txt36
-rw-r--r--src/tools/clippy/src/docs/useless_conversion.txt17
-rw-r--r--src/tools/clippy/src/docs/useless_format.txt22
-rw-r--r--src/tools/clippy/src/docs/useless_let_if_seq.txt39
-rw-r--r--src/tools/clippy/src/docs/useless_transmute.txt12
-rw-r--r--src/tools/clippy/src/docs/useless_vec.txt18
-rw-r--r--src/tools/clippy/src/docs/vec_box.txt26
-rw-r--r--src/tools/clippy/src/docs/vec_init_then_push.txt23
-rw-r--r--src/tools/clippy/src/docs/vec_resize_to_zero.txt15
-rw-r--r--src/tools/clippy/src/docs/verbose_bit_mask.txt15
-rw-r--r--src/tools/clippy/src/docs/verbose_file_reads.txt17
-rw-r--r--src/tools/clippy/src/docs/vtable_address_comparisons.txt17
-rw-r--r--src/tools/clippy/src/docs/while_immutable_condition.txt20
-rw-r--r--src/tools/clippy/src/docs/while_let_loop.txt25
-rw-r--r--src/tools/clippy/src/docs/while_let_on_iterator.txt20
-rw-r--r--src/tools/clippy/src/docs/wildcard_dependencies.txt13
-rw-r--r--src/tools/clippy/src/docs/wildcard_enum_match_arm.txt25
-rw-r--r--src/tools/clippy/src/docs/wildcard_imports.txt45
-rw-r--r--src/tools/clippy/src/docs/wildcard_in_or_patterns.txt22
-rw-r--r--src/tools/clippy/src/docs/write_literal.txt17
-rw-r--r--src/tools/clippy/src/docs/write_with_newline.txt18
-rw-r--r--src/tools/clippy/src/docs/writeln_empty_string.txt16
-rw-r--r--src/tools/clippy/src/docs/wrong_self_convention.txt39
-rw-r--r--src/tools/clippy/src/docs/wrong_transmute.txt15
-rw-r--r--src/tools/clippy/src/docs/zero_divided_by_zero.txt15
-rw-r--r--src/tools/clippy/src/docs/zero_prefixed_literal.txt32
-rw-r--r--src/tools/clippy/src/docs/zero_ptr.txt16
-rw-r--r--src/tools/clippy/src/docs/zero_sized_map_values.txt24
-rw-r--r--src/tools/clippy/src/docs/zst_offset.txt11
-rw-r--r--src/tools/clippy/src/driver.rs121
-rw-r--r--src/tools/clippy/src/main.rs4
-rw-r--r--src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_both_diff/src/main.stderr8
-rw-r--r--src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_both_same/src/main.stderr8
-rw-r--r--src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_cargo/src/main.stderr8
-rw-r--r--src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_clippy/src/main.stderr8
-rw-r--r--src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_file_attr/src/main.stderr8
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.stderr2
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed4
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs4
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed6
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr6
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr20
-rw-r--r--src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed14
-rw-r--r--src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs14
-rw-r--r--src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr76
-rw-r--r--src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr4
-rw-r--r--src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs23
-rw-r--r--src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr4
-rw-r--r--src/tools/clippy/tests/ui-toml/mut_key/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs53
-rw-r--r--src/tools/clippy/tests/ui-toml/print_macro/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/print_macro/print_macro.rs20
-rw-r--r--src/tools/clippy/tests/ui-toml/print_macro/print_macro.stderr18
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallowed_methods/clippy.toml6
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs30
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr50
-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/unwrap_used/unwrap_used.rs21
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr32
-rw-r--r--src/tools/clippy/tests/ui-toml/vec_box_sized/test.rs5
-rw-r--r--src/tools/clippy/tests/ui-toml/vec_box_sized/test.stderr6
-rw-r--r--src/tools/clippy/tests/ui/almost_complete_letter_range.fixed5
-rw-r--r--src/tools/clippy/tests/ui/almost_complete_letter_range.rs5
-rw-r--r--src/tools/clippy/tests/ui/almost_complete_letter_range.stderr26
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.rs8
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.stderr110
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.stderr20
-rw-r--r--src/tools/clippy/tests/ui/author/blocks.stdout2
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/doc_unsafe_macros.rs8
-rw-r--r--src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs2
-rw-r--r--src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr27
-rw-r--r--src/tools/clippy/tests/ui/bool_to_int_with_if.fixed22
-rw-r--r--src/tools/clippy/tests/ui/bool_to_int_with_if.rs22
-rw-r--r--src/tools/clippy/tests/ui/bool_to_int_with_if.stderr18
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed7
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs7
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr36
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_bool.fixed7
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_bool.rs7
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_bool.stderr28
-rw-r--r--src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed8
-rw-r--r--src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs8
-rw-r--r--src/tools/clippy/tests/ui/cfg_attr_rustfmt.stderr2
-rw-r--r--src/tools/clippy/tests/ui/checked_conversions.fixed7
-rw-r--r--src/tools/clippy/tests/ui/checked_conversions.rs7
-rw-r--r--src/tools/clippy/tests/ui/checked_conversions.stderr34
-rw-r--r--src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed10
-rw-r--r--src/tools/clippy/tests/ui/cloned_instead_of_copied.rs10
-rw-r--r--src/tools/clippy/tests/ui/cloned_instead_of_copied.stderr16
-rw-r--r--src/tools/clippy/tests/ui/cognitive_complexity.rs16
-rw-r--r--src/tools/clippy/tests/ui/cognitive_complexity.stderr18
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2774.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6250.stderr5
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-9746.rs15
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs1
-rw-r--r--src/tools/clippy/tests/ui/doc_errors.stderr36
-rw-r--r--src/tools/clippy/tests/ui/doc_unsafe.stderr34
-rw-r--r--src/tools/clippy/tests/ui/eq_op.rs1
-rw-r--r--src/tools/clippy/tests/ui/eq_op.stderr56
-rw-r--r--src/tools/clippy/tests/ui/equatable_if_let.fixed11
-rw-r--r--src/tools/clippy/tests/ui/equatable_if_let.rs7
-rw-r--r--src/tools/clippy/tests/ui/equatable_if_let.stderr42
-rw-r--r--src/tools/clippy/tests/ui/err_expect.fixed7
-rw-r--r--src/tools/clippy/tests/ui/err_expect.rs7
-rw-r--r--src/tools/clippy/tests/ui/err_expect.stderr4
-rw-r--r--src/tools/clippy/tests/ui/eta.fixed22
-rw-r--r--src/tools/clippy/tests/ui/eta.rs22
-rw-r--r--src/tools/clippy/tests/ui/eta.stderr26
-rw-r--r--src/tools/clippy/tests/ui/expect.stderr6
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.fixed15
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.rs15
-rw-r--r--src/tools/clippy/tests/ui/filter_map_next_fixable.fixed7
-rw-r--r--src/tools/clippy/tests/ui/filter_map_next_fixable.rs7
-rw-r--r--src/tools/clippy/tests/ui/filter_map_next_fixable.stderr4
-rw-r--r--src/tools/clippy/tests/ui/fn_params_excessive_bools.rs8
-rw-r--r--src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr22
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.fixed7
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.rs7
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.stderr10
-rw-r--r--src/tools/clippy/tests/ui/from_raw_with_void_ptr.rs34
-rw-r--r--src/tools/clippy/tests/ui/from_raw_with_void_ptr.stderr63
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.stderr26
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.rs5
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.stderr10
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.stderr6
-rw-r--r--src/tools/clippy/tests/ui/infallible_destructuring_match.fixed12
-rw-r--r--src/tools/clippy/tests/ui/infallible_destructuring_match.rs14
-rw-r--r--src/tools/clippy/tests/ui/infallible_destructuring_match.stderr16
-rw-r--r--src/tools/clippy/tests/ui/issue_4266.stderr4
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_drop.rs28
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_drop.stderr27
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_future.rs20
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_future.stderr27
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_lock.rs31
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_lock.stderr66
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_must_use.stderr24
-rw-r--r--src/tools/clippy/tests/ui/macro_use_imports.stderr8
-rw-r--r--src/tools/clippy/tests/ui/manual_clamp.rs7
-rw-r--r--src/tools/clippy/tests/ui/manual_clamp.stderr70
-rw-r--r--src/tools/clippy/tests/ui/manual_flatten.rs2
-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.stderr4
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.fixed42
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.rs42
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.stderr70
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.rs251
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.stderr272
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.rs121
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.stderr58
-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.stderr8
-rw-r--r--src/tools/clippy/tests/ui/manual_rem_euclid.fixed13
-rw-r--r--src/tools/clippy/tests/ui/manual_rem_euclid.rs13
-rw-r--r--src/tools/clippy/tests/ui/manual_rem_euclid.stderr20
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.fixed7
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.rs7
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.stderr38
-rw-r--r--src/tools/clippy/tests/ui/manual_split_once.fixed5
-rw-r--r--src/tools/clippy/tests/ui/manual_split_once.rs5
-rw-r--r--src/tools/clippy/tests/ui/manual_split_once.stderr38
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.fixed5
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.rs5
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.stderr20
-rw-r--r--src/tools/clippy/tests/ui/manual_strip.rs7
-rw-r--r--src/tools/clippy/tests/ui/manual_strip.stderr32
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.stderr18
-rw-r--r--src/tools/clippy/tests/ui/map_unwrap_or.rs7
-rw-r--r--src/tools/clippy/tests/ui/map_unwrap_or.stderr24
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed14
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs14
-rw-r--r--src/tools/clippy/tests/ui/match_expr_like_matches_macro.stderr28
-rw-r--r--src/tools/clippy/tests/ui/mem_replace.fixed7
-rw-r--r--src/tools/clippy/tests/ui/mem_replace.rs7
-rw-r--r--src/tools/clippy/tests/ui/mem_replace.stderr40
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.rs41
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.stderr26
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr2
-rw-r--r--src/tools/clippy/tests/ui/misnamed_getters.rs124
-rw-r--r--src/tools/clippy/tests/ui/misnamed_getters.stderr166
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs4
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs10
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr24
-rw-r--r--src/tools/clippy/tests/ui/missing_panics_doc.stderr49
-rw-r--r--src/tools/clippy/tests/ui/mut_from_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/mut_mut.rs17
-rw-r--r--src/tools/clippy/tests/ui/mut_range_bound.rs2
-rw-r--r--src/tools/clippy/tests/ui/mut_range_bound.stderr2
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.fixed144
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.rs144
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.stderr24
-rw-r--r--src/tools/clippy/tests/ui/needless_borrowed_ref.fixed67
-rw-r--r--src/tools/clippy/tests/ui/needless_borrowed_ref.rs67
-rw-r--r--src/tools/clippy/tests/ui/needless_borrowed_ref.stderr113
-rw-r--r--src/tools/clippy/tests/ui/needless_collect.fixed29
-rw-r--r--src/tools/clippy/tests/ui/needless_collect.rs29
-rw-r--r--src/tools/clippy/tests/ui/needless_collect.stderr26
-rw-r--r--src/tools/clippy/tests/ui/needless_collect_indirect.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_collect_indirect.stderr32
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.rs96
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.stderr246
-rw-r--r--src/tools/clippy/tests/ui/needless_question_mark.fixed1
-rw-r--r--src/tools/clippy/tests/ui/needless_question_mark.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_question_mark.stderr28
-rw-r--r--src/tools/clippy/tests/ui/needless_return.fixed19
-rw-r--r--src/tools/clippy/tests/ui/needless_return.rs13
-rw-r--r--src/tools/clippy/tests/ui/needless_return.stderr85
-rw-r--r--src/tools/clippy/tests/ui/needless_splitn.fixed3
-rw-r--r--src/tools/clippy/tests/ui/needless_splitn.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_splitn.stderr26
-rw-r--r--src/tools/clippy/tests/ui/never_loop.rs21
-rw-r--r--src/tools/clippy/tests/ui/never_loop.stderr14
-rw-r--r--src/tools/clippy/tests/ui/new_ret_no_self.rs73
-rw-r--r--src/tools/clippy/tests/ui/new_ret_no_self.stderr54
-rw-r--r--src/tools/clippy/tests/ui/option_as_ref_deref.fixed7
-rw-r--r--src/tools/clippy/tests/ui/option_as_ref_deref.rs7
-rw-r--r--src/tools/clippy/tests/ui/option_as_ref_deref.stderr36
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.fixed9
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.rs9
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.fixed16
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.rs16
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.stderr14
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.fixed5
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.rs5
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.stderr16
-rw-r--r--src/tools/clippy/tests/ui/question_mark.fixed3
-rw-r--r--src/tools/clippy/tests/ui/question_mark.rs3
-rw-r--r--src/tools/clippy/tests/ui/question_mark.stderr4
-rw-r--r--src/tools/clippy/tests/ui/range_contains.fixed7
-rw-r--r--src/tools/clippy/tests/ui/range_contains.rs7
-rw-r--r--src/tools/clippy/tests/ui/range_contains.stderr42
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed12
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs12
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr24
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.fixed7
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.rs7
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.stderr16
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed7
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.rs7
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr34
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed8
-rw-r--r--src/tools/clippy/tests/ui/rename.rs8
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr106
-rw-r--r--src/tools/clippy/tests/ui/result_large_err.rs18
-rw-r--r--src/tools/clippy/tests/ui/result_large_err.stderr30
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.stderr6
-rw-r--r--src/tools/clippy/tests/ui/seek_from_current.fixed25
-rw-r--r--src/tools/clippy/tests/ui/seek_from_current.rs25
-rw-r--r--src/tools/clippy/tests/ui/seek_from_current.stderr10
-rw-r--r--src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed134
-rw-r--r--src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs134
-rw-r--r--src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr22
-rw-r--r--src/tools/clippy/tests/ui/single_component_path_imports.stderr12
-rw-r--r--src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr15
-rw-r--r--src/tools/clippy/tests/ui/string_extend.fixed3
-rw-r--r--src/tools/clippy/tests/ui/string_extend.rs3
-rw-r--r--src/tools/clippy/tests/ui/string_extend.stderr8
-rw-r--r--src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.rs34
-rw-r--r--src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr51
-rw-r--r--src/tools/clippy/tests/ui/swap.fixed9
-rw-r--r--src/tools/clippy/tests/ui/swap.rs9
-rw-r--r--src/tools/clippy/tests/ui/track-diagnostics.rs12
-rw-r--r--src/tools/clippy/tests/ui/track-diagnostics.stderr10
-rw-r--r--src/tools/clippy/tests/ui/transmute.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed5
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs5
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr44
-rw-r--r--src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs1
-rw-r--r--src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.stderr36
-rw-r--r--src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed17
-rw-r--r--src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs17
-rw-r--r--src/tools/clippy/tests/ui/unchecked_duration_subtraction.stderr28
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs21
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr57
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args.fixed24
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args.rs5
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args.stderr213
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.fixed14
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.rs14
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.stderr52
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_join.stderr4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed23
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs23
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr84
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.fixed9
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.rs9
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_safety_comment.rs51
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr115
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed34
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs34
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.stderr168
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs149
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr51
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.fixed8
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.rs8
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unused_rounding.fixed8
-rw-r--r--src/tools/clippy/tests/ui/unused_rounding.rs8
-rw-r--r--src/tools/clippy/tests/ui/unused_rounding.stderr14
-rw-r--r--src/tools/clippy/tests/ui/unused_unit.fixed7
-rw-r--r--src/tools/clippy/tests/ui/unused_unit.rs7
-rw-r--r--src/tools/clippy/tests/ui/unused_unit.stderr40
-rw-r--r--src/tools/clippy/tests/ui/unwrap.stderr6
-rw-r--r--src/tools/clippy/tests/ui/unwrap_expect_used.stderr12
-rw-r--r--src/tools/clippy/tests/ui/unwrap_or.rs2
-rw-r--r--src/tools/clippy/tests/ui/use_self.fixed7
-rw-r--r--src/tools/clippy/tests/ui/use_self.rs7
-rw-r--r--src/tools/clippy/tests/ui/use_self.stderr84
-rw-r--r--src/tools/clippy/tests/ui/use_self_trait.fixed41
-rw-r--r--src/tools/clippy/tests/ui/use_self_trait.rs39
-rw-r--r--src/tools/clippy/tests/ui/use_self_trait.stderr14
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.fixed21
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.rs21
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.stderr6
-rw-r--r--src/tools/clippy/tests/versioncheck.rs15
-rw-r--r--src/tools/clippy/triagebot.toml21
-rw-r--r--src/tools/collect-license-metadata/Cargo.toml10
-rw-r--r--src/tools/collect-license-metadata/src/licenses.rs65
-rw-r--r--src/tools/collect-license-metadata/src/main.rs30
-rw-r--r--src/tools/collect-license-metadata/src/path_tree.rs294
-rw-r--r--src/tools/collect-license-metadata/src/reuse.rs49
-rw-r--r--src/tools/compiletest/Cargo.toml1
-rw-r--r--src/tools/compiletest/src/common.rs23
-rw-r--r--src/tools/compiletest/src/header.rs8
-rw-r--r--src/tools/compiletest/src/header/tests.rs1
-rw-r--r--src/tools/compiletest/src/main.rs3
-rw-r--r--src/tools/compiletest/src/runtest.rs310
-rw-r--r--src/tools/compiletest/src/util.rs23
-rw-r--r--src/tools/generate-copyright/Cargo.toml11
-rw-r--r--src/tools/generate-copyright/src/main.rs94
-rw-r--r--src/tools/jsondoclint/src/item_kind.rs33
-rw-r--r--src/tools/jsondoclint/src/json_find.rs5
-rw-r--r--src/tools/jsondoclint/src/json_find/tests.rs27
-rw-r--r--src/tools/jsondoclint/src/main.rs4
-rw-r--r--src/tools/jsondoclint/src/validator.rs53
-rw-r--r--src/tools/jsondoclint/src/validator/tests.rs50
-rw-r--r--src/tools/linkchecker/main.rs57
-rw-r--r--src/tools/lint-docs/src/lib.rs6
-rw-r--r--src/tools/miropt-test-tools/Cargo.toml7
-rw-r--r--src/tools/miropt-test-tools/src/lib.rs70
-rw-r--r--src/tools/rust-analyzer/Cargo.lock120
-rw-r--r--src/tools/rust-analyzer/crates/base-db/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/cfg/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/flycheck/Cargo.toml3
-rw-r--r--src/tools/rust-analyzer/crates/flycheck/src/lib.rs31
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/path_resolution.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/globs.rs33
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/mod_resolution.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/path.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/pretty.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs96
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/lib.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs17
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs43
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs1
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs12
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs108
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lower.rs143
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs86
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs40
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs31
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs40
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs16
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs157
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tls.rs28
-rw-r--r--src/tools/rust-analyzer/crates/hir/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs39
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs37
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs81
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_type.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_impl_members.rs38
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs7
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs13
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs413
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs70
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs318
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs31
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs38
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs14
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs38
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs90
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_format_string_arg.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs29
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_dbg.rs69
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs11
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs25
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs44
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/item_list/trait_impl.rs159
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs29
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs32
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/line_index.rs7
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/search.rs70
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs60
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/macro_error.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs12
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/useless_braces.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs22
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/ide/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs88
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs243
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/moniker.rs48
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/references.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/rename.rs35
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/signature_help.rs58
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/static_index.rs7
-rw-r--r--src/tools/rust-analyzer/crates/limit/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/mbe/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs89
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/syntax_bridge/tests.rs93
-rw-r--r--src/tools/rust-analyzer/crates/parser/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/paths/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs4
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs4
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs6
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-test/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-test/imp/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/profile/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs50
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/sysroot.rs27
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/tests.rs71
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs84
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs8
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/caps.rs14
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cargo_target_spec.rs10
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/load_cargo.rs22
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs12
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs159
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs95
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs38
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/from_proto.rs12
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs19
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/line_index.rs64
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_ext.rs11
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp_utils.rs115
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs54
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/mem_docs.rs8
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs64
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs68
-rw-r--r--src/tools/rust-analyzer/crates/sourcegen/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/stdx/Cargo.toml4
-rw-r--r--src/tools/rust-analyzer/crates/syntax/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/rust.ungram9
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs56
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs20
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs46
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/tests/sourcegen_ast.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/validation.rs6
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/text-edit/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/toolchain/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/tt/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/vfs/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/docs/dev/architecture.md6
-rw-r--r--src/tools/rust-analyzer/docs/dev/guide.md50
-rw-r--r--src/tools/rust-analyzer/docs/dev/lsp-extensions.md8
-rw-r--r--src/tools/rust-analyzer/docs/user/generated_config.adoc26
-rw-r--r--src/tools/rust-analyzer/docs/user/manual.adoc8
-rw-r--r--src/tools/rust-analyzer/lib/lsp-server/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/triagebot.toml10
-rw-r--r--src/tools/rust-analyzer/xtask/Cargo.toml2
-rw-r--r--src/tools/rust-installer/install-template.sh22
-rw-r--r--src/tools/rust-installer/triagebot.toml3
-rw-r--r--src/tools/rustc-workspace-hack/Cargo.toml4
-rw-r--r--src/tools/rustdoc-gui/tester.js1
-rw-r--r--src/tools/rustdoc-js/tester.js7
-rw-r--r--src/tools/rustfmt/src/attr.rs21
-rw-r--r--src/tools/rustfmt/src/chains.rs12
-rw-r--r--src/tools/rustfmt/src/closures.rs31
-rw-r--r--src/tools/rustfmt/src/expr.rs72
-rw-r--r--src/tools/rustfmt/src/imports.rs2
-rw-r--r--src/tools/rustfmt/src/macros.rs6
-rw-r--r--src/tools/rustfmt/src/modules/visitor.rs12
-rw-r--r--src/tools/rustfmt/src/overflow.rs4
-rw-r--r--src/tools/rustfmt/src/parse/macros/asm.rs2
-rw-r--r--src/tools/rustfmt/src/parse/macros/cfg_if.rs2
-rw-r--r--src/tools/rustfmt/src/parse/session.rs1
-rw-r--r--src/tools/rustfmt/src/patterns.rs9
-rw-r--r--src/tools/rustfmt/src/types.rs8
-rw-r--r--src/tools/rustfmt/src/utils.rs5
-rw-r--r--src/tools/tidy/Cargo.toml2
-rw-r--r--src/tools/tidy/src/deps.rs48
-rw-r--r--src/tools/tidy/src/lib.rs1
-rw-r--r--src/tools/tidy/src/main.rs2
-rw-r--r--src/tools/tidy/src/mir_opt_tests.rs74
-rw-r--r--src/tools/tidy/src/style.rs2
-rw-r--r--src/tools/tidy/src/ui_tests.rs63
-rw-r--r--src/tools/tier-check/src/main.rs18
-rw-r--r--src/tools/x/src/main.rs9
-rw-r--r--src/version2
3486 files changed, 51468 insertions, 37785 deletions
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index baecca44c..efe8ae316 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -12,15 +12,6 @@ dependencies = [
]
[[package]]
-name = "ansi_term"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
-dependencies = [
- "winapi",
-]
-
-[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -53,6 +44,7 @@ dependencies = [
"hex",
"ignore",
"libc",
+ "object",
"once_cell",
"opener",
"pretty_assertions",
@@ -107,18 +99,18 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "cpufeatures"
-version = "0.2.2"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
+checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
dependencies = [
"libc",
]
[[package]]
name = "crossbeam-channel"
-version = "0.5.4"
+version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
+checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
@@ -126,9 +118,9 @@ dependencies = [
[[package]]
name = "crossbeam-deque"
-version = "0.8.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
+checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
"cfg-if",
"crossbeam-epoch",
@@ -137,26 +129,24 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
-version = "0.9.8"
+version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
+checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
- "lazy_static",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
-version = "0.8.8"
+version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
+checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [
"cfg-if",
- "lazy_static",
]
[[package]]
@@ -224,9 +214,9 @@ dependencies = [
[[package]]
name = "fd-lock"
-version = "3.0.6"
+version = "3.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e11dcc7e4d79a8c89b9ab4c6f5c30b1fc4a83c420792da3542fd31179ed5f517"
+checksum = "bb21c69b9fea5e15dbc1049e4b77145dd0ba1c84019c488102de0dc4ea4b0a27"
dependencies = [
"cfg-if",
"rustix",
@@ -318,9 +308,13 @@ dependencies = [
[[package]]
name = "io-lifetimes"
-version = "0.7.2"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24c3f4eff5495aee4c0399d7b6a0dc2b6e81be84242ffbfcf253ebacccc1d0cb"
+checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
[[package]]
name = "itoa"
@@ -336,15 +330,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.126"
+version = "0.2.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
[[package]]
name = "linux-raw-sys"
-version = "0.0.46"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d"
+checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
[[package]]
name = "log"
@@ -374,18 +368,18 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
-version = "0.6.5"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
+checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
dependencies = [
"autocfg",
]
[[package]]
name = "ntapi"
-version = "0.3.7"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
+checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc"
dependencies = [
"winapi",
]
@@ -401,6 +395,15 @@ dependencies = [
]
[[package]]
+name = "object"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "once_cell"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -433,14 +436,14 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]]
name = "pretty_assertions"
-version = "0.7.2"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cab0e7c02cf376875e9335e0ba1da535775beb5450d21e1dffca068818ed98b"
+checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755"
dependencies = [
- "ansi_term",
"ctor",
"diff",
"output_vt100",
+ "yansi",
]
[[package]]
@@ -463,11 +466,10 @@ dependencies = [
[[package]]
name = "rayon"
-version = "1.5.3"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
+checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b"
dependencies = [
- "autocfg",
"crossbeam-deque",
"either",
"rayon-core",
@@ -475,9 +477,9 @@ dependencies = [
[[package]]
name = "rayon-core"
-version = "1.9.3"
+version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
+checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
@@ -519,9 +521,9 @@ checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
[[package]]
name = "rustix"
-version = "0.35.6"
+version = "0.36.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef258c11e17f5c01979a10543a30a4e12faef6aab217a74266e747eefa3aed88"
+checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e"
dependencies = [
"bitflags",
"errno",
@@ -607,9 +609,9 @@ dependencies = [
[[package]]
name = "sysinfo"
-version = "0.24.2"
+version = "0.26.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2809487b962344ca55d9aea565f9ffbcb6929780802217acc82561f6746770"
+checksum = "c375d5fd899e32847b8566e10598d6e9f1d9b55ec6de3cdf9e7da4bdc51371bc"
dependencies = [
"cfg-if",
"core-foundation-sys",
@@ -717,46 +719,60 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
-version = "0.36.1"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
+ "windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
+
+[[package]]
name = "windows_aarch64_msvc"
-version = "0.36.1"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
[[package]]
name = "windows_i686_gnu"
-version = "0.36.1"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
[[package]]
name = "windows_i686_msvc"
-version = "0.36.1"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.36.1"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.36.1"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
+checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
[[package]]
name = "xattr"
@@ -775,3 +791,9 @@ checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c"
dependencies = [
"lzma-sys",
]
+
+[[package]]
+name = "yansi"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 95e711737..ccc7ec1fc 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -36,12 +36,13 @@ test = false
[dependencies]
cmake = "0.1.38"
-fd-lock = "3.0.6"
+fd-lock = "3.0.8"
filetime = "0.2"
getopts = "0.2.19"
cc = "1.0.69"
libc = "0.2"
hex = "0.4"
+object = { version = "0.29.0", default-features = false, features = ["archive", "coff", "read_core", "unaligned"] }
serde = { version = "1.0.8", features = ["derive"] }
serde_json = "1.0.2"
sha2 = "0.10"
@@ -54,7 +55,7 @@ xz2 = "0.1"
walkdir = "2"
# Dependencies needed by the build-metrics feature
-sysinfo = { version = "0.24.1", optional = true }
+sysinfo = { version = "0.26.0", optional = true }
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3"
@@ -71,7 +72,7 @@ features = [
]
[dev-dependencies]
-pretty_assertions = "0.7"
+pretty_assertions = "1.2"
[features]
build-metrics = ["sysinfo"]
diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs
index 9b4861ccd..be69f819c 100644
--- a/src/bootstrap/bin/main.rs
+++ b/src/bootstrap/bin/main.rs
@@ -35,7 +35,7 @@ fn main() {
// NOTE: Since `./configure` generates a `config.toml`, distro maintainers will see the
// changelog warning, not the `x.py setup` message.
- let suggest_setup = !config.config.exists() && !matches!(config.cmd, Subcommand::Setup { .. });
+ let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. });
if suggest_setup {
println!("warning: you have not made a `config.toml`");
println!(
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 776d73b98..1d5260228 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -97,13 +97,7 @@ fn main() {
// This... is a bit of a hack how we detect this. Ideally this
// information should be encoded in the crate I guess? Would likely
// require an RFC amendment to RFC 1513, however.
- //
- // `compiler_builtins` are unconditionally compiled with panic=abort to
- // workaround undefined references to `rust_eh_unwind_resume` generated
- // otherwise, see issue https://github.com/rust-lang/rust/issues/43095.
- if crate_name == Some("panic_abort")
- || crate_name == Some("compiler_builtins") && stage != "0"
- {
+ if crate_name == Some("panic_abort") {
cmd.arg("-C").arg("panic=abort");
}
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index e69cab956..23828f475 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -55,13 +55,9 @@ fn main() {
arg.push(&linker);
cmd.arg(arg);
}
- if env::var_os("RUSTDOC_FUSE_LD_LLD").is_some() {
+ if let Ok(no_threads) = env::var("RUSTDOC_LLD_NO_THREADS") {
cmd.arg("-Clink-arg=-fuse-ld=lld");
- if cfg!(windows) {
- cmd.arg("-Clink-arg=-Wl,/threads:1");
- } else {
- cmd.arg("-Clink-arg=-Wl,--threads=1");
- }
+ cmd.arg(format!("-Clink-arg=-Wl,{}", no_threads));
}
// Cargo doesn't pass RUSTDOCFLAGS to proc_macros:
// https://github.com/rust-lang/cargo/issues/4423
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 57128685d..2d5018d93 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -441,6 +441,7 @@ class RustBuild(object):
self.fix_bin_or_dylib("{}/bin/rustc".format(bin_root))
self.fix_bin_or_dylib("{}/bin/rustdoc".format(bin_root))
+ self.fix_bin_or_dylib("{}/libexec/rust-analyzer-proc-macro-srv".format(bin_root))
lib_dir = "{}/lib".format(bin_root)
for lib in os.listdir(lib_dir):
if lib.endswith(".so"):
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 8b144f146..8ee6d49da 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -2,14 +2,13 @@ use std::any::{type_name, Any};
use std::cell::{Cell, RefCell};
use std::collections::BTreeSet;
use std::env;
-use std::ffi::{OsStr, OsString};
+use std::ffi::OsStr;
use std::fmt::{Debug, Write};
-use std::fs::{self, File};
+use std::fs::{self};
use std::hash::Hash;
-use std::io::{BufRead, BufReader, ErrorKind};
use std::ops::Deref;
use std::path::{Component, Path, PathBuf};
-use std::process::{Command, Stdio};
+use std::process::Command;
use std::time::{Duration, Instant};
use crate::cache::{Cache, Interned, INTERNER};
@@ -24,14 +23,12 @@ use crate::test;
use crate::tool::{self, SourceType};
use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir, output, t};
use crate::EXTRA_CHECK_CFGS;
-use crate::{check, Config};
-use crate::{compile, Crate};
+use crate::{check, compile, Crate};
use crate::{Build, CLang, DocTests, GitRepo, Mode};
pub use crate::Compiler;
// FIXME: replace with std::lazy after it gets stabilized and reaches beta
-use once_cell::sync::{Lazy, OnceCell};
-use xz2::bufread::XzDecoder;
+use once_cell::sync::Lazy;
pub struct Builder<'a> {
pub build: &'a Build,
@@ -621,6 +618,8 @@ impl<'a> Builder<'a> {
check::CodegenBackend,
check::Clippy,
check::Miri,
+ check::CargoMiri,
+ check::MiroptTestTools,
check::Rls,
check::RustAnalyzer,
check::Rustfmt,
@@ -645,6 +644,7 @@ impl<'a> Builder<'a> {
test::CrateLibrustc,
test::CrateRustdoc,
test::CrateRustdocJsonTypes,
+ test::CrateJsonDocLint,
test::Linkcheck,
test::TierCheck,
test::ReplacePlaceholderTest,
@@ -753,6 +753,9 @@ impl<'a> Builder<'a> {
run::BuildManifest,
run::BumpStage0,
run::ReplaceVersionPlaceholder,
+ run::Miri,
+ run::CollectLicenseMetadata,
+ run::GenerateCopyright,
),
// These commands either don't use paths, or they're special-cased in Build::build()
Kind::Clean | Kind::Format | Kind::Setup => vec![],
@@ -816,7 +819,7 @@ impl<'a> Builder<'a> {
Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]),
Subcommand::Install { ref paths } => (Kind::Install, &paths[..]),
- Subcommand::Run { ref paths } => (Kind::Run, &paths[..]),
+ Subcommand::Run { ref paths, .. } => (Kind::Run, &paths[..]),
Subcommand::Format { .. } => (Kind::Format, &[][..]),
Subcommand::Clean { .. } | Subcommand::Setup { .. } => {
panic!()
@@ -850,241 +853,6 @@ impl<'a> Builder<'a> {
StepDescription::run(v, self, paths);
}
- /// Modifies the interpreter section of 'fname' to fix the dynamic linker,
- /// or the RPATH section, to fix the dynamic library search path
- ///
- /// This is only required on NixOS and uses the PatchELF utility to
- /// change the interpreter/RPATH of ELF executables.
- ///
- /// Please see https://nixos.org/patchelf.html for more information
- pub(crate) fn fix_bin_or_dylib(&self, fname: &Path) {
- // FIXME: cache NixOS detection?
- match Command::new("uname").arg("-s").stderr(Stdio::inherit()).output() {
- Err(_) => return,
- Ok(output) if !output.status.success() => return,
- Ok(output) => {
- let mut s = output.stdout;
- if s.last() == Some(&b'\n') {
- s.pop();
- }
- if s != b"Linux" {
- return;
- }
- }
- }
-
- // If the user has asked binaries to be patched for Nix, then
- // don't check for NixOS or `/lib`, just continue to the patching.
- // NOTE: this intentionally comes after the Linux check:
- // - patchelf only works with ELF files, so no need to run it on Mac or Windows
- // - On other Unix systems, there is no stable syscall interface, so Nix doesn't manage the global libc.
- if !self.config.patch_binaries_for_nix {
- // Use `/etc/os-release` instead of `/etc/NIXOS`.
- // The latter one does not exist on NixOS when using tmpfs as root.
- const NIX_IDS: &[&str] = &["ID=nixos", "ID='nixos'", "ID=\"nixos\""];
- let os_release = match File::open("/etc/os-release") {
- Err(e) if e.kind() == ErrorKind::NotFound => return,
- Err(e) => panic!("failed to access /etc/os-release: {}", e),
- Ok(f) => f,
- };
- if !BufReader::new(os_release).lines().any(|l| NIX_IDS.contains(&t!(l).trim())) {
- return;
- }
- if Path::new("/lib").exists() {
- return;
- }
- }
-
- // At this point we're pretty sure the user is running NixOS or using Nix
- println!("info: you seem to be using Nix. Attempting to patch {}", fname.display());
-
- // Only build `.nix-deps` once.
- static NIX_DEPS_DIR: OnceCell<PathBuf> = OnceCell::new();
- let mut nix_build_succeeded = true;
- let nix_deps_dir = NIX_DEPS_DIR.get_or_init(|| {
- // Run `nix-build` to "build" each dependency (which will likely reuse
- // the existing `/nix/store` copy, or at most download a pre-built copy).
- //
- // Importantly, we create a gc-root called `.nix-deps` in the `build/`
- // directory, but still reference the actual `/nix/store` path in the rpath
- // as it makes it significantly more robust against changes to the location of
- // the `.nix-deps` location.
- //
- // bintools: Needed for the path of `ld-linux.so` (via `nix-support/dynamic-linker`).
- // zlib: Needed as a system dependency of `libLLVM-*.so`.
- // patchelf: Needed for patching ELF binaries (see doc comment above).
- let nix_deps_dir = self.out.join(".nix-deps");
- const NIX_EXPR: &str = "
- with (import <nixpkgs> {});
- symlinkJoin {
- name = \"rust-stage0-dependencies\";
- paths = [
- zlib
- patchelf
- stdenv.cc.bintools
- ];
- }
- ";
- nix_build_succeeded = self.try_run(Command::new("nix-build").args(&[
- Path::new("-E"),
- Path::new(NIX_EXPR),
- Path::new("-o"),
- &nix_deps_dir,
- ]));
- nix_deps_dir
- });
- if !nix_build_succeeded {
- return;
- }
-
- let mut patchelf = Command::new(nix_deps_dir.join("bin/patchelf"));
- let rpath_entries = {
- // ORIGIN is a relative default, all binary and dynamic libraries we ship
- // appear to have this (even when `../lib` is redundant).
- // NOTE: there are only two paths here, delimited by a `:`
- let mut entries = OsString::from("$ORIGIN/../lib:");
- entries.push(t!(fs::canonicalize(nix_deps_dir)));
- entries.push("/lib");
- entries
- };
- patchelf.args(&[OsString::from("--set-rpath"), rpath_entries]);
- if !fname.extension().map_or(false, |ext| ext == "so") {
- // Finally, set the correct .interp for binaries
- let dynamic_linker_path = nix_deps_dir.join("nix-support/dynamic-linker");
- // FIXME: can we support utf8 here? `args` doesn't accept Vec<u8>, only OsString ...
- let dynamic_linker = t!(String::from_utf8(t!(fs::read(dynamic_linker_path))));
- patchelf.args(&["--set-interpreter", dynamic_linker.trim_end()]);
- }
-
- self.try_run(patchelf.arg(fname));
- }
-
- pub(crate) fn download_component(&self, url: &str, dest_path: &Path, help_on_error: &str) {
- self.verbose(&format!("download {url}"));
- // Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/.
- let tempfile = self.tempdir().join(dest_path.file_name().unwrap());
- // While bootstrap itself only supports http and https downloads, downstream forks might
- // need to download components from other protocols. The match allows them adding more
- // protocols without worrying about merge conflicts if we change the HTTP implementation.
- match url.split_once("://").map(|(proto, _)| proto) {
- Some("http") | Some("https") => {
- self.download_http_with_retries(&tempfile, url, help_on_error)
- }
- Some(other) => panic!("unsupported protocol {other} in {url}"),
- None => panic!("no protocol in {url}"),
- }
- t!(std::fs::rename(&tempfile, dest_path));
- }
-
- fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
- println!("downloading {}", url);
- // Try curl. If that fails and we are on windows, fallback to PowerShell.
- let mut curl = Command::new("curl");
- curl.args(&[
- "-#",
- "-y",
- "30",
- "-Y",
- "10", // timeout if speed is < 10 bytes/sec for > 30 seconds
- "--connect-timeout",
- "30", // timeout if cannot connect within 30 seconds
- "--retry",
- "3",
- "-Sf",
- "-o",
- ]);
- curl.arg(tempfile);
- curl.arg(url);
- if !self.check_run(&mut curl) {
- if self.build.build.contains("windows-msvc") {
- println!("Fallback to PowerShell");
- for _ in 0..3 {
- if self.try_run(Command::new("PowerShell.exe").args(&[
- "/nologo",
- "-Command",
- "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;",
- &format!(
- "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
- url, tempfile.to_str().expect("invalid UTF-8 not supported with powershell downloads"),
- ),
- ])) {
- return;
- }
- println!("\nspurious failure, trying again");
- }
- }
- if !help_on_error.is_empty() {
- eprintln!("{}", help_on_error);
- }
- crate::detail_exit(1);
- }
- }
-
- pub(crate) fn unpack(&self, tarball: &Path, dst: &Path, pattern: &str) {
- println!("extracting {} to {}", tarball.display(), dst.display());
- if !dst.exists() {
- t!(fs::create_dir_all(dst));
- }
-
- // `tarball` ends with `.tar.xz`; strip that suffix
- // example: `rust-dev-nightly-x86_64-unknown-linux-gnu`
- let uncompressed_filename =
- Path::new(tarball.file_name().expect("missing tarball filename")).file_stem().unwrap();
- let directory_prefix = Path::new(Path::new(uncompressed_filename).file_stem().unwrap());
-
- // decompress the file
- let data = t!(File::open(tarball));
- let decompressor = XzDecoder::new(BufReader::new(data));
-
- let mut tar = tar::Archive::new(decompressor);
- for member in t!(tar.entries()) {
- let mut member = t!(member);
- let original_path = t!(member.path()).into_owned();
- // skip the top-level directory
- if original_path == directory_prefix {
- continue;
- }
- let mut short_path = t!(original_path.strip_prefix(directory_prefix));
- if !short_path.starts_with(pattern) {
- continue;
- }
- short_path = t!(short_path.strip_prefix(pattern));
- let dst_path = dst.join(short_path);
- self.verbose(&format!("extracting {} to {}", original_path.display(), dst.display()));
- if !t!(member.unpack_in(dst)) {
- panic!("path traversal attack ??");
- }
- let src_path = dst.join(original_path);
- if src_path.is_dir() && dst_path.exists() {
- continue;
- }
- t!(fs::rename(src_path, dst_path));
- }
- t!(fs::remove_dir_all(dst.join(directory_prefix)));
- }
-
- /// Returns whether the SHA256 checksum of `path` matches `expected`.
- pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool {
- use sha2::Digest;
-
- self.verbose(&format!("verifying {}", path.display()));
- let mut hasher = sha2::Sha256::new();
- // FIXME: this is ok for rustfmt (4.1 MB large at time of writing), but it seems memory-intensive for rustc and larger components.
- // Consider using streaming IO instead?
- let contents = if self.config.dry_run { vec![] } else { t!(fs::read(path)) };
- hasher.update(&contents);
- let found = hex::encode(hasher.finalize().as_slice());
- let verified = found == expected;
- if !verified && !self.config.dry_run {
- println!(
- "invalid checksum: \n\
- found: {found}\n\
- expected: {expected}",
- );
- }
- return verified;
- }
-
/// Obtain a compiler at a given stage and for a given host. Explicitly does
/// not take `Compiler` since all `Compiler` instances are meant to be
/// obtained through this function, since it ensures that they are valid
@@ -1289,7 +1057,7 @@ impl<'a> Builder<'a> {
/// Note that this returns `None` if LLVM is disabled, or if we're in a
/// check build or dry-run, where there's no need to build all of LLVM.
fn llvm_config(&self, target: TargetSelection) -> Option<PathBuf> {
- if self.config.llvm_enabled() && self.kind != Kind::Check && !self.config.dry_run {
+ if self.config.llvm_enabled() && self.kind != Kind::Check && !self.config.dry_run() {
let llvm_config = self.ensure(native::Llvm { target });
if llvm_config.is_file() {
return Some(llvm_config);
@@ -1298,19 +1066,6 @@ impl<'a> Builder<'a> {
None
}
- /// Convenience wrapper to allow `builder.llvm_link_shared()` instead of `builder.config.llvm_link_shared(&builder)`.
- pub(crate) fn llvm_link_shared(&self) -> bool {
- Config::llvm_link_shared(self)
- }
-
- pub(crate) fn download_rustc(&self) -> bool {
- Config::download_rustc(self)
- }
-
- pub(crate) fn initial_rustfmt(&self) -> Option<PathBuf> {
- Config::initial_rustfmt(self)
- }
-
/// Prepares an invocation of `cargo` to be run.
///
/// This will create a `Command` that represents a pending execution of
@@ -1342,7 +1097,13 @@ impl<'a> Builder<'a> {
let my_out = match mode {
// This is the intended out directory for compiler documentation.
Mode::Rustc | Mode::ToolRustc => self.compiler_doc_out(target),
- Mode::Std => out_dir.join(target.triple).join("doc"),
+ Mode::Std => {
+ if self.config.cmd.json() {
+ out_dir.join(target.triple).join("json-doc")
+ } else {
+ out_dir.join(target.triple).join("doc")
+ }
+ }
_ => panic!("doc mode {:?} not expected", mode),
};
let rustdoc = self.rustdoc(compiler);
@@ -1641,7 +1402,7 @@ impl<'a> Builder<'a> {
//
// Only clear out the directory if we're compiling std; otherwise, we
// should let Cargo take care of things for us (via depdep info)
- if !self.config.dry_run && mode == Mode::Std && cmd == "build" {
+ if !self.config.dry_run() && mode == Mode::Std && cmd == "build" {
self.clear_if_dirty(&out_dir, &self.rustc(compiler));
}
@@ -2139,7 +1900,7 @@ impl<'a> Builder<'a> {
(out, dur - deps)
};
- if self.config.print_step_timings && !self.config.dry_run {
+ if self.config.print_step_timings && !self.config.dry_run() {
let step_string = format!("{:?}", step);
let brace_index = step_string.find("{").unwrap_or(0);
let type_string = type_name::<S>();
@@ -2205,6 +1966,24 @@ impl<'a> Builder<'a> {
false
}
+
+ pub(crate) fn maybe_open_in_browser<S: Step>(&self, path: impl AsRef<Path>) {
+ if self.was_invoked_explicitly::<S>(Kind::Doc) {
+ self.open_in_browser(path);
+ }
+ }
+
+ pub(crate) fn open_in_browser(&self, path: impl AsRef<Path>) {
+ if self.config.dry_run() || !self.config.cmd.open() {
+ return;
+ }
+
+ let path = path.as_ref();
+ self.info(&format!("Opening doc {}", path.display()));
+ if let Err(err) = opener::open(path) {
+ self.info(&format!("{}\n", err));
+ }
+ }
}
#[cfg(test)]
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index 88bbcc93d..5f21d2b00 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -1,5 +1,5 @@
use super::*;
-use crate::config::{Config, TargetSelection};
+use crate::config::{Config, DryRun, TargetSelection};
use std::thread;
fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
@@ -10,7 +10,7 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config
let mut config = Config::parse(cmd);
// don't save toolstates
config.save_toolstates = None;
- config.dry_run = true;
+ config.dry_run = DryRun::SelfCheck;
// Ignore most submodules, since we don't need them for a dry run.
// But make sure to check out the `doc` and `rust-analyzer` submodules, since some steps need them
diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs
index be5c9bb07..05f25af68 100644
--- a/src/bootstrap/cache.rs
+++ b/src/bootstrap/cache.rs
@@ -89,16 +89,16 @@ impl<T: Internable + Hash> Hash for Interned<T> {
impl<T: Internable + Deref> Deref for Interned<T> {
type Target = T::Target;
- fn deref(&self) -> &'static Self::Target {
+ fn deref(&self) -> &Self::Target {
let l = T::intern_cache().lock().unwrap();
- unsafe { mem::transmute::<&Self::Target, &'static Self::Target>(l.get(*self)) }
+ unsafe { mem::transmute::<&Self::Target, &Self::Target>(l.get(*self)) }
}
}
impl<T: Internable + AsRef<U>, U: ?Sized> AsRef<U> for Interned<T> {
- fn as_ref(&self) -> &'static U {
+ fn as_ref(&self) -> &U {
let l = T::intern_cache().lock().unwrap();
- unsafe { mem::transmute::<&U, &'static U>(l.get(*self).as_ref()) }
+ unsafe { mem::transmute::<&U, &U>(l.get(*self).as_ref()) }
}
}
diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs
index 759a99c33..7128d542a 100644
--- a/src/bootstrap/cc_detect.rs
+++ b/src/bootstrap/cc_detect.rs
@@ -166,14 +166,7 @@ fn set_compiler(
// compiler already takes into account the triple in question.
t if t.contains("android") => {
if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) {
- let target = target
- .triple
- .replace("armv7neon", "arm")
- .replace("armv7", "arm")
- .replace("thumbv7neon", "arm")
- .replace("thumbv7", "arm");
- let compiler = format!("{}-{}", target, compiler.clang());
- cfg.compiler(ndk.join("bin").join(compiler));
+ cfg.compiler(ndk_compiler(compiler, &*target.triple, ndk));
}
}
@@ -225,8 +218,18 @@ fn set_compiler(
}
}
+pub(crate) fn ndk_compiler(compiler: Language, triple: &str, ndk: &Path) -> PathBuf {
+ let triple_translated = triple
+ .replace("armv7neon", "arm")
+ .replace("armv7", "arm")
+ .replace("thumbv7neon", "arm")
+ .replace("thumbv7", "arm");
+ let compiler = format!("{}-{}", triple_translated, compiler.clang());
+ ndk.join("bin").join(compiler)
+}
+
/// The target programming language for a native compiler.
-enum Language {
+pub(crate) enum Language {
/// The compiler is targeting C.
C,
/// The compiler is targeting C++.
diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs
index 258352a21..eae81b9fc 100644
--- a/src/bootstrap/channel.rs
+++ b/src/bootstrap/channel.rs
@@ -13,8 +13,10 @@ use crate::util::output;
use crate::util::t;
use crate::Build;
+#[derive(Clone, Default)]
pub enum GitInfo {
/// This is not a git repository.
+ #[default]
Absent,
/// This is a git repository.
/// If the info should be used (`ignore_git` is false), this will be
@@ -25,6 +27,7 @@ pub enum GitInfo {
RecordedForTarball(Info),
}
+#[derive(Clone)]
pub struct Info {
pub commit_date: String,
pub sha: String,
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 229851238..2e1bd8d6d 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -451,16 +451,16 @@ macro_rules! tool_check_step {
}
tool_check_step!(Rustdoc, "src/tools/rustdoc", "src/librustdoc", SourceType::InTree);
-// Clippy and Rustfmt are hybrids. They are external tools, but use a git subtree instead
+// Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
// of a submodule. Since the SourceType only drives the deny-warnings
// behavior, treat it as in-tree so that any new warnings in clippy will be
// rejected.
tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree);
-// Miri on the other hand is treated as out of tree, since InTree also causes it to
-// be run as part of `check`, which can fail on platforms which libffi-sys has no support for.
-tool_check_step!(Miri, "src/tools/miri", SourceType::Submodule);
+tool_check_step!(Miri, "src/tools/miri", SourceType::InTree);
+tool_check_step!(CargoMiri, "src/tools/miri/cargo-miri", SourceType::InTree);
tool_check_step!(Rls, "src/tools/rls", SourceType::InTree);
tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree);
+tool_check_step!(MiroptTestTools, "src/tools/miropt-test-tools", SourceType::InTree);
tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree, false);
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index e02a10b81..0deed3f99 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -206,7 +206,6 @@ fn copy_third_party_objects(
}
if target == "x86_64-fortanix-unknown-sgx"
- || target.contains("pc-windows-gnullvm")
|| builder.config.llvm_libunwind(target) == LlvmLibunwind::InTree
&& (target.contains("linux") || target.contains("fuchsia"))
{
@@ -299,7 +298,9 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
// Determine if we're going to compile in optimized C intrinsics to
// the `compiler-builtins` crate. These intrinsics live in LLVM's
- // `compiler-rt` repository.
+ // `compiler-rt` repository, but our `src/llvm-project` submodule isn't
+ // always checked out, so we need to conditionally look for this. (e.g. if
+ // an external LLVM is used we skip the LLVM submodule checkout).
//
// Note that this shouldn't affect the correctness of `compiler-builtins`,
// but only its speed. Some intrinsics in C haven't been translated to Rust
@@ -310,15 +311,8 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
// If `compiler-rt` is available ensure that the `c` feature of the
// `compiler-builtins` crate is enabled and it's configured to learn where
// `compiler-rt` is located.
- let compiler_builtins_c_feature = if builder.config.optimized_compiler_builtins {
- if !builder.is_rust_llvm(target) {
- panic!(
- "need a managed LLVM submodule for optimized intrinsics support; unset `llvm-config` or `optimized-compiler-builtins`"
- );
- }
-
- builder.update_submodule(&Path::new("src").join("llvm-project"));
- let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
+ let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
+ let compiler_builtins_c_feature = if compiler_builtins_root.exists() {
// Note that `libprofiler_builtins/build.rs` also computes this so if
// you're changing something here please also change that.
cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root);
@@ -452,7 +446,7 @@ fn copy_sanitizers(
) -> Vec<PathBuf> {
let runtimes: Vec<native::SanitizerRuntime> = builder.ensure(native::Sanitizers { target });
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return Vec::new();
}
@@ -769,10 +763,10 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS
cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative);
- if let Some(ref ver_date) = builder.rust_info.commit_date() {
+ if let Some(ref ver_date) = builder.rust_info().commit_date() {
cargo.env("CFG_VER_DATE", ver_date);
}
- if let Some(ref ver_hash) = builder.rust_info.sha() {
+ if let Some(ref ver_hash) = builder.rust_info().sha() {
cargo.env("CFG_VER_HASH", ver_hash);
}
if !builder.unstable_features() {
@@ -991,7 +985,7 @@ impl Step for CodegenBackend {
compiler.stage, backend, &compiler.host, target
));
let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false);
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return;
}
let mut files = files.into_iter().filter(|f| {
@@ -1039,7 +1033,7 @@ fn copy_codegen_backends_to_sysroot(
let dst = builder.sysroot_codegen_backends(target_compiler);
t!(fs::create_dir_all(&dst), dst);
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return;
}
@@ -1127,13 +1121,18 @@ impl Step for Sysroot {
fn run(self, builder: &Builder<'_>) -> Interned<PathBuf> {
let compiler = self.compiler;
let host_dir = builder.out.join(&compiler.host.triple);
- let sysroot = if compiler.stage == 0 {
- host_dir.join("stage0-sysroot")
- } else if builder.download_rustc() {
- host_dir.join("ci-rustc-sysroot")
- } else {
- host_dir.join(format!("stage{}", compiler.stage))
+
+ let sysroot_dir = |stage| {
+ if stage == 0 {
+ host_dir.join("stage0-sysroot")
+ } else if builder.download_rustc() && compiler.stage != builder.top_stage {
+ host_dir.join("ci-rustc-sysroot")
+ } else {
+ host_dir.join(format!("stage{}", stage))
+ }
};
+ let sysroot = sysroot_dir(compiler.stage);
+
let _ = fs::remove_dir_all(&sysroot);
t!(fs::create_dir_all(&sysroot));
@@ -1144,9 +1143,15 @@ impl Step for Sysroot {
"Cross-compiling is not yet supported with `download-rustc`",
);
- // #102002, cleanup stage1 and stage0-sysroot folders when using download-rustc so people don't use old versions of the toolchain by accident.
- let _ = fs::remove_dir_all(host_dir.join("stage1"));
- let _ = fs::remove_dir_all(host_dir.join("stage0-sysroot"));
+ // #102002, cleanup old toolchain folders when using download-rustc so people don't use them by accident.
+ for stage in 0..=2 {
+ if stage != compiler.stage {
+ let dir = sysroot_dir(stage);
+ if !dir.ends_with("ci-rustc-sysroot") {
+ let _ = fs::remove_dir_all(dir);
+ }
+ }
+ }
// Copy the compiler into the correct sysroot.
let ci_rustc_dir =
@@ -1337,7 +1342,7 @@ impl Step for Assemble {
if builder.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) {
let llvm_config_bin = builder.ensure(native::Llvm { target: target_compiler.host });
- if !builder.config.dry_run {
+ if !builder.config.dry_run() {
let llvm_bin_dir = output(Command::new(llvm_config_bin).arg("--bindir"));
let llvm_bin_dir = Path::new(llvm_bin_dir.trim());
@@ -1407,7 +1412,7 @@ pub fn run_cargo(
additional_target_deps: Vec<(PathBuf, DependencyType)>,
is_check: bool,
) -> Vec<PathBuf> {
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return Vec::new();
}
@@ -1547,7 +1552,7 @@ pub fn stream_cargo(
cb: &mut dyn FnMut(CargoMessage<'_>),
) -> bool {
let mut cargo = Command::from(cargo);
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return true;
}
// Instruct Cargo to give us json messages on stdout, critically leaving
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index a8c403675..d8c15c76e 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -7,19 +7,19 @@ use std::cell::{Cell, RefCell};
use std::cmp;
use std::collections::{HashMap, HashSet};
use std::env;
-use std::ffi::OsStr;
use std::fmt;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::str::FromStr;
-use crate::builder::{Builder, TaskPath};
+use crate::builder::TaskPath;
use crate::cache::{Interned, INTERNER};
-use crate::channel::GitInfo;
+use crate::cc_detect::{ndk_compiler, Language};
+use crate::channel::{self, GitInfo};
pub use crate::flags::Subcommand;
use crate::flags::{Color, Flags};
-use crate::util::{exe, output, program_out_of_date, t};
+use crate::util::{exe, output, t};
use once_cell::sync::OnceCell;
use serde::{Deserialize, Deserializer};
@@ -33,6 +33,17 @@ macro_rules! check_ci_llvm {
};
}
+#[derive(Clone, Default)]
+pub enum DryRun {
+ /// This isn't a dry run.
+ #[default]
+ Disabled,
+ /// This is a dry run enabled by bootstrap itself, so it can verify that no work is done.
+ SelfCheck,
+ /// This is a dry run enabled by the `--dry-run` flag.
+ UserSelected,
+}
+
/// Global configuration for the entire build and/or bootstrap.
///
/// This structure is derived from a combination of both `config.toml` and
@@ -73,8 +84,6 @@ pub struct Config {
pub color: Color,
pub patch_binaries_for_nix: bool,
pub stage0_metadata: Stage0Metadata,
- /// Whether to use the `c` feature of the `compiler_builtins` crate.
- pub optimized_compiler_builtins: bool,
pub on_fail: Option<String>,
pub stage: u32,
@@ -82,11 +91,11 @@ pub struct Config {
pub keep_stage_std: Vec<u32>,
pub src: PathBuf,
/// defaults to `config.toml`
- pub config: PathBuf,
+ pub config: Option<PathBuf>,
pub jobs: Option<u32>,
pub cmd: Subcommand,
pub incremental: bool,
- pub dry_run: bool,
+ pub dry_run: DryRun,
/// `None` if we shouldn't download CI compiler artifacts, or the commit to download if we should.
#[cfg(not(test))]
download_rustc_commit: Option<String>,
@@ -204,6 +213,7 @@ pub struct Config {
pub npm: Option<PathBuf>,
pub gdb: Option<PathBuf>,
pub python: Option<PathBuf>,
+ pub reuse: Option<PathBuf>,
pub cargo_native_static: bool,
pub configure_args: Vec<String>,
@@ -215,6 +225,7 @@ pub struct Config {
#[cfg(test)]
pub initial_rustfmt: RefCell<RustfmtState>,
pub out: PathBuf,
+ pub rust_info: channel::GitInfo,
}
#[derive(Default, Deserialize)]
@@ -601,6 +612,7 @@ define_config! {
nodejs: Option<String> = "nodejs",
npm: Option<String> = "npm",
python: Option<String> = "python",
+ reuse: Option<String> = "reuse",
locked_deps: Option<bool> = "locked-deps",
vendor: Option<bool> = "vendor",
full_bootstrap: Option<bool> = "full-bootstrap",
@@ -624,7 +636,6 @@ define_config! {
bench_stage: Option<u32> = "bench-stage",
patch_binaries_for_nix: Option<bool> = "patch-binaries-for-nix",
metrics: Option<bool> = "metrics",
- optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
}
}
@@ -784,7 +795,7 @@ impl Config {
config.llvm_optimize = true;
config.ninja_in_file = true;
config.llvm_version_check = true;
- config.llvm_static_stdcpp = true;
+ config.llvm_static_stdcpp = false;
config.backtrace = true;
config.rust_optimize = true;
config.rust_optimize_tests = true;
@@ -823,7 +834,7 @@ impl Config {
config.jobs = flags.jobs.map(threads_from_config);
config.cmd = flags.cmd;
config.incremental = flags.incremental;
- config.dry_run = flags.dry_run;
+ config.dry_run = if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled };
config.keep_stage = flags.keep_stage;
config.keep_stage_std = flags.keep_stage_std;
config.color = flags.color;
@@ -929,8 +940,10 @@ impl Config {
// Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path,
// but not if `config.toml` hasn't been created.
let mut toml = if !using_default_path || toml_path.exists() {
+ config.config = Some(toml_path.clone());
get_toml(&toml_path)
} else {
+ config.config = None;
TomlConfig::default()
};
@@ -945,7 +958,6 @@ impl Config {
}
config.changelog_seen = toml.changelog_seen;
- config.config = toml_path;
let build = toml.build.unwrap_or_default();
@@ -967,7 +979,7 @@ impl Config {
.unwrap_or_else(|| config.out.join(config.build.triple).join("stage0/bin/cargo"));
// NOTE: it's important this comes *after* we set `initial_rustc` just above.
- if config.dry_run {
+ if config.dry_run() {
let dir = config.out.join("tmp-dry-run");
t!(fs::create_dir_all(&dir));
config.out = dir;
@@ -994,6 +1006,7 @@ impl Config {
config.npm = build.npm.map(PathBuf::from);
config.gdb = build.gdb.map(PathBuf::from);
config.python = build.python.map(PathBuf::from);
+ config.reuse = build.reuse.map(PathBuf::from);
config.submodules = build.submodules;
set(&mut config.low_priority, build.low_priority);
set(&mut config.compiler_docs, build.compiler_docs);
@@ -1013,7 +1026,6 @@ impl Config {
set(&mut config.print_step_timings, build.print_step_timings);
set(&mut config.print_step_rusage, build.print_step_rusage);
set(&mut config.patch_binaries_for_nix, build.patch_binaries_for_nix);
- set(&mut config.optimized_compiler_builtins, build.optimized_compiler_builtins);
config.verbose = cmp::max(config.verbose, flags.verbose);
@@ -1196,7 +1208,7 @@ impl Config {
config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config);
config.rust_profile_use = flags.rust_profile_use.or(rust.profile_use);
config.rust_profile_generate = flags.rust_profile_generate.or(rust.profile_generate);
- config.download_rustc_commit = download_ci_rustc_commit(&config, rust.download_rustc);
+ config.download_rustc_commit = config.download_ci_rustc_commit(rust.download_rustc);
config.rust_lto = rust
.lto
@@ -1229,8 +1241,12 @@ impl Config {
if let Some(s) = cfg.no_std {
target.no_std = s;
}
- target.cc = cfg.cc.map(PathBuf::from);
- target.cxx = cfg.cxx.map(PathBuf::from);
+ target.cc = cfg.cc.map(PathBuf::from).or_else(|| {
+ target.ndk.as_ref().map(|ndk| ndk_compiler(Language::C, &triple, ndk))
+ });
+ target.cxx = cfg.cxx.map(PathBuf::from).or_else(|| {
+ target.ndk.as_ref().map(|ndk| ndk_compiler(Language::CPlusPlus, &triple, ndk))
+ });
target.ar = cfg.ar.map(PathBuf::from);
target.ranlib = cfg.ranlib.map(PathBuf::from);
target.linker = cfg.linker.map(PathBuf::from);
@@ -1318,6 +1334,7 @@ impl Config {
let default = config.channel == "dev";
config.ignore_git = ignore_git.unwrap_or(default);
+ config.rust_info = GitInfo::new(config.ignore_git, &config.src);
let download_rustc = config.download_rustc_commit.is_some();
// See https://github.com/rust-lang/compiler-team/issues/326
@@ -1375,6 +1392,13 @@ impl Config {
config
}
+ pub(crate) fn dry_run(&self) -> bool {
+ match self.dry_run {
+ DryRun::Disabled => false,
+ DryRun::SelfCheck | DryRun::UserSelected => true,
+ }
+ }
+
/// A git invocation which runs inside the source directory.
///
/// Use this rather than `Command::new("git")` in order to support out-of-tree builds.
@@ -1384,21 +1408,46 @@ impl Config {
git
}
- pub(crate) fn artifact_channel(&self, builder: &Builder<'_>, commit: &str) -> String {
- if builder.rust_info.is_managed_git_subrepository() {
+ /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI.
+ /// Return the version it would have used for the given commit.
+ pub(crate) fn artifact_version_part(&self, commit: &str) -> String {
+ let (channel, version) = if self.rust_info.is_managed_git_subrepository() {
let mut channel = self.git();
channel.arg("show").arg(format!("{}:src/ci/channel", commit));
let channel = output(&mut channel);
- channel.trim().to_owned()
- } else if let Ok(channel) = fs::read_to_string(builder.src.join("src/ci/channel")) {
- channel.trim().to_owned()
+ let mut version = self.git();
+ version.arg("show").arg(format!("{}:src/version", commit));
+ let version = output(&mut version);
+ (channel.trim().to_owned(), version.trim().to_owned())
} else {
- let src = builder.src.display();
- eprintln!("error: failed to determine artifact channel");
- eprintln!(
- "help: either use git or ensure that {src}/src/ci/channel contains the name of the channel to use"
- );
- panic!();
+ let channel = fs::read_to_string(self.src.join("src/ci/channel"));
+ let version = fs::read_to_string(self.src.join("src/version"));
+ match (channel, version) {
+ (Ok(channel), Ok(version)) => {
+ (channel.trim().to_owned(), version.trim().to_owned())
+ }
+ (channel, version) => {
+ let src = self.src.display();
+ eprintln!("error: failed to determine artifact channel and/or version");
+ eprintln!(
+ "help: consider using a git checkout or ensure these files are readable"
+ );
+ if let Err(channel) = channel {
+ eprintln!("reading {}/src/ci/channel failed: {:?}", src, channel);
+ }
+ if let Err(version) = version {
+ eprintln!("reading {}/src/version failed: {:?}", src, version);
+ }
+ panic!();
+ }
+ }
+ };
+
+ match channel.as_str() {
+ "stable" => version,
+ "beta" => channel,
+ "nightly" => channel,
+ other => unreachable!("{:?} is not recognized as a valid channel", other),
}
}
@@ -1437,17 +1486,17 @@ impl Config {
///
/// If `false`, llvm should be linked statically.
/// This is computed on demand since LLVM might have to first be downloaded from CI.
- pub(crate) fn llvm_link_shared(builder: &Builder<'_>) -> bool {
- let mut opt = builder.config.llvm_link_shared.get();
- if opt.is_none() && builder.config.dry_run {
+ pub(crate) fn llvm_link_shared(&self) -> bool {
+ let mut opt = self.llvm_link_shared.get();
+ if opt.is_none() && self.dry_run() {
// just assume static for now - dynamic linking isn't supported on all platforms
return false;
}
let llvm_link_shared = *opt.get_or_insert_with(|| {
- if builder.config.llvm_from_ci {
- crate::native::maybe_download_ci_llvm(builder);
- let ci_llvm = builder.config.ci_llvm_root();
+ if self.llvm_from_ci {
+ self.maybe_download_ci_llvm();
+ let ci_llvm = self.ci_llvm_root();
let link_type = t!(
std::fs::read_to_string(ci_llvm.join("link-type.txt")),
format!("CI llvm missing: {}", ci_llvm.display())
@@ -1459,36 +1508,42 @@ impl Config {
false
}
});
- builder.config.llvm_link_shared.set(opt);
+ self.llvm_link_shared.set(opt);
llvm_link_shared
}
/// Return whether we will use a downloaded, pre-compiled version of rustc, or just build from source.
- pub(crate) fn download_rustc(builder: &Builder<'_>) -> bool {
- static DOWNLOAD_RUSTC: OnceCell<bool> = OnceCell::new();
- if builder.config.dry_run && DOWNLOAD_RUSTC.get().is_none() {
+ pub(crate) fn download_rustc(&self) -> bool {
+ self.download_rustc_commit().is_some()
+ }
+
+ pub(crate) fn download_rustc_commit(&self) -> Option<&'static str> {
+ static DOWNLOAD_RUSTC: OnceCell<Option<String>> = OnceCell::new();
+ if self.dry_run() && DOWNLOAD_RUSTC.get().is_none() {
// avoid trying to actually download the commit
- return false;
+ return None;
}
- *DOWNLOAD_RUSTC.get_or_init(|| match &builder.config.download_rustc_commit {
- None => false,
- Some(commit) => {
- download_ci_rustc(builder, commit);
- true
- }
- })
+ DOWNLOAD_RUSTC
+ .get_or_init(|| match &self.download_rustc_commit {
+ None => None,
+ Some(commit) => {
+ self.download_ci_rustc(commit);
+ Some(commit.clone())
+ }
+ })
+ .as_deref()
}
- pub(crate) fn initial_rustfmt(builder: &Builder<'_>) -> Option<PathBuf> {
- match &mut *builder.config.initial_rustfmt.borrow_mut() {
+ pub(crate) fn initial_rustfmt(&self) -> Option<PathBuf> {
+ match &mut *self.initial_rustfmt.borrow_mut() {
RustfmtState::SystemToolchain(p) | RustfmtState::Downloaded(p) => Some(p.clone()),
RustfmtState::Unavailable => None,
r @ RustfmtState::LazyEvaluated => {
- if builder.config.dry_run {
+ if self.dry_run() {
return Some(PathBuf::new());
}
- let path = maybe_download_rustfmt(builder);
+ let path = self.maybe_download_rustfmt();
*r = if let Some(p) = &path {
RustfmtState::Downloaded(p.clone())
} else {
@@ -1499,8 +1554,10 @@ impl Config {
}
}
- pub fn verbose(&self) -> bool {
- self.verbose > 0
+ pub fn verbose(&self, msg: &str) {
+ if self.verbose > 0 {
+ println!("{}", msg);
+ }
}
pub fn sanitizers_enabled(&self, target: TargetSelection) -> bool {
@@ -1538,218 +1595,77 @@ impl Config {
pub fn submodules(&self, rust_info: &GitInfo) -> bool {
self.submodules.unwrap_or(rust_info.is_managed_git_subrepository())
}
-}
-fn set<T>(field: &mut T, val: Option<T>) {
- if let Some(v) = val {
- *field = v;
- }
-}
-
-fn threads_from_config(v: u32) -> u32 {
- match v {
- 0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32,
- n => n,
- }
-}
+ /// Returns the commit to download, or `None` if we shouldn't download CI artifacts.
+ fn download_ci_rustc_commit(&self, download_rustc: Option<StringOrBool>) -> Option<String> {
+ // If `download-rustc` is not set, default to rebuilding.
+ let if_unchanged = match download_rustc {
+ None | Some(StringOrBool::Bool(false)) => return None,
+ Some(StringOrBool::Bool(true)) => false,
+ Some(StringOrBool::String(s)) if s == "if-unchanged" => true,
+ Some(StringOrBool::String(other)) => {
+ panic!("unrecognized option for download-rustc: {}", other)
+ }
+ };
-/// Returns the commit to download, or `None` if we shouldn't download CI artifacts.
-fn download_ci_rustc_commit(
- config: &Config,
- download_rustc: Option<StringOrBool>,
-) -> Option<String> {
- // If `download-rustc` is not set, default to rebuilding.
- let if_unchanged = match download_rustc {
- None | Some(StringOrBool::Bool(false)) => return None,
- Some(StringOrBool::Bool(true)) => false,
- Some(StringOrBool::String(s)) if s == "if-unchanged" => true,
- Some(StringOrBool::String(other)) => {
- panic!("unrecognized option for download-rustc: {}", other)
+ // Handle running from a directory other than the top level
+ let top_level = output(self.git().args(&["rev-parse", "--show-toplevel"]));
+ let top_level = top_level.trim_end();
+ let compiler = format!("{top_level}/compiler/");
+ let library = format!("{top_level}/library/");
+
+ // Look for a version to compare to based on the current commit.
+ // Only commits merged by bors will have CI artifacts.
+ let merge_base = output(
+ self.git()
+ .arg("rev-list")
+ .arg(format!("--author={}", self.stage0_metadata.config.git_merge_commit_email))
+ .args(&["-n1", "--first-parent", "HEAD"]),
+ );
+ let commit = merge_base.trim_end();
+ if commit.is_empty() {
+ println!("error: could not find commit hash for downloading rustc");
+ println!("help: maybe your repository history is too shallow?");
+ println!("help: consider disabling `download-rustc`");
+ println!("help: or fetch enough history to include one upstream commit");
+ crate::detail_exit(1);
}
- };
- // Handle running from a directory other than the top level
- let top_level = output(config.git().args(&["rev-parse", "--show-toplevel"]));
- let top_level = top_level.trim_end();
- let compiler = format!("{top_level}/compiler/");
- let library = format!("{top_level}/library/");
-
- // Look for a version to compare to based on the current commit.
- // Only commits merged by bors will have CI artifacts.
- let merge_base = output(
- config
+ // Warn if there were changes to the compiler or standard library since the ancestor commit.
+ let has_changes = !t!(self
.git()
- .arg("rev-list")
- .arg(format!("--author={}", config.stage0_metadata.config.git_merge_commit_email))
- .args(&["-n1", "--first-parent", "HEAD"]),
- );
- let commit = merge_base.trim_end();
- if commit.is_empty() {
- println!("error: could not find commit hash for downloading rustc");
- println!("help: maybe your repository history is too shallow?");
- println!("help: consider disabling `download-rustc`");
- println!("help: or fetch enough history to include one upstream commit");
- crate::detail_exit(1);
- }
-
- // Warn if there were changes to the compiler or standard library since the ancestor commit.
- let has_changes = !t!(config
- .git()
- .args(&["diff-index", "--quiet", &commit, "--", &compiler, &library])
- .status())
- .success();
- if has_changes {
- if if_unchanged {
- if config.verbose > 0 {
- println!(
- "warning: saw changes to compiler/ or library/ since {commit}; \
- ignoring `download-rustc`"
- );
+ .args(&["diff-index", "--quiet", &commit, "--", &compiler, &library])
+ .status())
+ .success();
+ if has_changes {
+ if if_unchanged {
+ if self.verbose > 0 {
+ println!(
+ "warning: saw changes to compiler/ or library/ since {commit}; \
+ ignoring `download-rustc`"
+ );
+ }
+ return None;
}
- return None;
+ println!(
+ "warning: `download-rustc` is enabled, but there are changes to \
+ compiler/ or library/"
+ );
}
- println!(
- "warning: `download-rustc` is enabled, but there are changes to \
- compiler/ or library/"
- );
- }
-
- Some(commit.to_string())
-}
-fn maybe_download_rustfmt(builder: &Builder<'_>) -> Option<PathBuf> {
- let RustfmtMetadata { date, version } = builder.config.stage0_metadata.rustfmt.as_ref()?;
- let channel = format!("{version}-{date}");
-
- let host = builder.config.build;
- let rustfmt_path = builder.config.initial_rustc.with_file_name(exe("rustfmt", host));
- let bin_root = builder.config.out.join(host.triple).join("stage0");
- let rustfmt_stamp = bin_root.join(".rustfmt-stamp");
- if rustfmt_path.exists() && !program_out_of_date(&rustfmt_stamp, &channel) {
- return Some(rustfmt_path);
+ Some(commit.to_string())
}
-
- let filename = format!("rustfmt-{version}-{build}.tar.xz", build = host.triple);
- download_component(builder, DownloadSource::Dist, filename, "rustfmt-preview", &date, "stage0");
-
- builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustfmt"));
- builder.fix_bin_or_dylib(&bin_root.join("bin").join("cargo-fmt"));
-
- builder.create(&rustfmt_stamp, &channel);
- Some(rustfmt_path)
}
-fn download_ci_rustc(builder: &Builder<'_>, commit: &str) {
- builder.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})"));
- let channel = builder.config.artifact_channel(builder, commit);
- let host = builder.config.build.triple;
- let bin_root = builder.out.join(host).join("ci-rustc");
- let rustc_stamp = bin_root.join(".rustc-stamp");
-
- if !bin_root.join("bin").join("rustc").exists() || program_out_of_date(&rustc_stamp, commit) {
- if bin_root.exists() {
- t!(fs::remove_dir_all(&bin_root));
- }
- let filename = format!("rust-std-{channel}-{host}.tar.xz");
- let pattern = format!("rust-std-{host}");
- download_ci_component(builder, filename, &pattern, commit);
- let filename = format!("rustc-{channel}-{host}.tar.xz");
- download_ci_component(builder, filename, "rustc", commit);
- // download-rustc doesn't need its own cargo, it can just use beta's.
- let filename = format!("rustc-dev-{channel}-{host}.tar.xz");
- download_ci_component(builder, filename, "rustc-dev", commit);
-
- builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustc"));
- builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustdoc"));
- let lib_dir = bin_root.join("lib");
- for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) {
- let lib = t!(lib);
- if lib.path().extension() == Some(OsStr::new("so")) {
- builder.fix_bin_or_dylib(&lib.path());
- }
- }
- t!(fs::write(rustc_stamp, commit));
+fn set<T>(field: &mut T, val: Option<T>) {
+ if let Some(v) = val {
+ *field = v;
}
}
-pub(crate) enum DownloadSource {
- CI,
- Dist,
-}
-
-/// Download a single component of a CI-built toolchain (not necessarily a published nightly).
-// NOTE: intentionally takes an owned string to avoid downloading multiple times by accident
-fn download_ci_component(builder: &Builder<'_>, filename: String, prefix: &str, commit: &str) {
- download_component(builder, DownloadSource::CI, filename, prefix, commit, "ci-rustc")
-}
-
-fn download_component(
- builder: &Builder<'_>,
- mode: DownloadSource,
- filename: String,
- prefix: &str,
- key: &str,
- destination: &str,
-) {
- let cache_dst = builder.out.join("cache");
- let cache_dir = cache_dst.join(key);
- if !cache_dir.exists() {
- t!(fs::create_dir_all(&cache_dir));
- }
-
- let bin_root = builder.out.join(builder.config.build.triple).join(destination);
- let tarball = cache_dir.join(&filename);
- let (base_url, url, should_verify) = match mode {
- DownloadSource::CI => (
- builder.config.stage0_metadata.config.artifacts_server.clone(),
- format!("{key}/{filename}"),
- false,
- ),
- DownloadSource::Dist => {
- let dist_server = env::var("RUSTUP_DIST_SERVER")
- .unwrap_or(builder.config.stage0_metadata.config.dist_server.to_string());
- // NOTE: make `dist` part of the URL because that's how it's stored in src/stage0.json
- (dist_server, format!("dist/{key}/{filename}"), true)
- }
- };
-
- // For the beta compiler, put special effort into ensuring the checksums are valid.
- // FIXME: maybe we should do this for download-rustc as well? but it would be a pain to update
- // this on each and every nightly ...
- let checksum = if should_verify {
- let error = format!(
- "src/stage0.json doesn't contain a checksum for {url}. \
- Pre-built artifacts might not be available for this \
- target at this time, see https://doc.rust-lang.org/nightly\
- /rustc/platform-support.html for more information."
- );
- let sha256 = builder.config.stage0_metadata.checksums_sha256.get(&url).expect(&error);
- if tarball.exists() {
- if builder.verify(&tarball, sha256) {
- builder.unpack(&tarball, &bin_root, prefix);
- return;
- } else {
- builder.verbose(&format!(
- "ignoring cached file {} due to failed verification",
- tarball.display()
- ));
- builder.remove(&tarball);
- }
- }
- Some(sha256)
- } else if tarball.exists() {
- builder.unpack(&tarball, &bin_root, prefix);
- return;
- } else {
- None
- };
-
- builder.download_component(&format!("{base_url}/{url}"), &tarball, "");
- if let Some(sha256) = checksum {
- if !builder.verify(&tarball, sha256) {
- panic!("failed to verify {}", tarball.display());
- }
+fn threads_from_config(v: u32) -> u32 {
+ match v {
+ 0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32,
+ n => n,
}
-
- builder.unpack(&tarball, &bin_root, prefix);
}
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 12585e80e..3cb0eccd3 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -10,15 +10,20 @@
use std::collections::HashSet;
use std::env;
+use std::ffi::OsStr;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::Command;
+use object::read::archive::ArchiveFile;
+use object::BinaryFormat;
+
use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
use crate::cache::{Interned, INTERNER};
use crate::channel;
use crate::compile;
use crate::config::TargetSelection;
+use crate::doc::DocumentationFormat;
use crate::tarball::{GeneratedTarball, OverlayKind, Tarball};
use crate::tool::{self, Tool};
use crate::util::{exe, is_dylib, output, t, timeit};
@@ -97,7 +102,11 @@ impl Step for JsonDocs {
/// Builds the `rust-docs-json` installer component.
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
let host = self.host;
- builder.ensure(crate::doc::JsonStd { stage: builder.top_stage, target: host });
+ builder.ensure(crate::doc::Std {
+ stage: builder.top_stage,
+ target: host,
+ format: DocumentationFormat::JSON,
+ });
let dest = "share/doc/rust/json";
@@ -550,6 +559,39 @@ fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
}
}
+/// Check that all objects in rlibs for UEFI targets are COFF. This
+/// ensures that the C compiler isn't producing ELF objects, which would
+/// not link correctly with the COFF objects.
+fn verify_uefi_rlib_format(builder: &Builder<'_>, target: TargetSelection, stamp: &Path) {
+ if !target.ends_with("-uefi") {
+ return;
+ }
+
+ for (path, _) in builder.read_stamp_file(stamp) {
+ if path.extension() != Some(OsStr::new("rlib")) {
+ continue;
+ }
+
+ let data = t!(fs::read(&path));
+ let data = data.as_slice();
+ let archive = t!(ArchiveFile::parse(data));
+ for member in archive.members() {
+ let member = t!(member);
+ let member_data = t!(member.data(data));
+
+ let is_coff = match object::File::parse(member_data) {
+ Ok(member_file) => member_file.format() == BinaryFormat::Coff,
+ Err(_) => false,
+ };
+
+ if !is_coff {
+ let member_name = String::from_utf8_lossy(member.name());
+ panic!("member {} in {} is not COFF", member_name, path.display());
+ }
+ }
+ }
+}
+
/// Copy stamped files into an image's `target/lib` directory.
fn copy_target_libs(builder: &Builder<'_>, target: TargetSelection, image: &Path, stamp: &Path) {
let dst = image.join("lib/rustlib").join(target.triple).join("lib");
@@ -605,6 +647,7 @@ impl Step for Std {
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
let stamp = compile::libstd_stamp(builder, compiler_to_use, target);
+ verify_uefi_rlib_format(builder, target, &stamp);
copy_target_libs(builder, target, &tarball.image_dir(), &stamp);
Some(tarball.generate())
@@ -919,13 +962,13 @@ impl Step for PlainSourceTarball {
// Create the version file
builder.create(&plain_dst_src.join("version"), &builder.rust_version());
- if let Some(info) = builder.rust_info.info() {
+ if let Some(info) = builder.rust_info().info() {
channel::write_commit_hash_file(&plain_dst_src, &info.sha);
channel::write_commit_info_file(&plain_dst_src, info);
}
// If we're building from git sources, we need to vendor a complete distribution.
- if builder.rust_info.is_managed_git_subrepository() {
+ if builder.rust_info().is_managed_git_subrepository() {
// Ensure we have the submodules checked out.
builder.update_submodule(Path::new("src/tools/rust-analyzer"));
@@ -940,7 +983,7 @@ impl Step for PlainSourceTarball {
.arg(builder.src.join("./src/bootstrap/Cargo.toml"))
.current_dir(&plain_dst_src);
- let config = if !builder.config.dry_run {
+ let config = if !builder.config.dry_run() {
t!(String::from_utf8(t!(cmd.output()).stdout))
} else {
String::new()
@@ -1381,7 +1424,7 @@ impl Step for Extended {
let etc = builder.src.join("src/etc/installer");
// Avoid producing tarballs during a dry run.
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return;
}
@@ -1819,7 +1862,7 @@ impl Step for Extended {
let _time = timeit(builder);
builder.run(&mut cmd);
- if !builder.config.dry_run {
+ if !builder.config.dry_run() {
t!(fs::rename(exe.join(&filename), distdir(builder).join(&filename)));
}
}
@@ -1853,21 +1896,23 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
///
/// Returns whether the files were actually copied.
fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) -> bool {
- if !builder.is_rust_llvm(target) {
- // If the LLVM was externally provided, then we don't currently copy
- // artifacts into the sysroot. This is not necessarily the right
- // choice (in particular, it will require the LLVM dylib to be in
- // the linker's load path at runtime), but the common use case for
- // external LLVMs is distribution provided LLVMs, and in that case
- // they're usually in the standard search path (e.g., /usr/lib) and
- // copying them here is going to cause problems as we may end up
- // with the wrong files and isn't what distributions want.
- //
- // This behavior may be revisited in the future though.
- //
- // If the LLVM is coming from ourselves (just from CI) though, we
- // still want to install it, as it otherwise won't be available.
- return false;
+ if let Some(config) = builder.config.target_config.get(&target) {
+ if config.llvm_config.is_some() && !builder.config.llvm_from_ci {
+ // If the LLVM was externally provided, then we don't currently copy
+ // artifacts into the sysroot. This is not necessarily the right
+ // choice (in particular, it will require the LLVM dylib to be in
+ // the linker's load path at runtime), but the common use case for
+ // external LLVMs is distribution provided LLVMs, and in that case
+ // they're usually in the standard search path (e.g., /usr/lib) and
+ // copying them here is going to cause problems as we may end up
+ // with the wrong files and isn't what distributions want.
+ //
+ // This behavior may be revisited in the future though.
+ //
+ // If the LLVM is coming from ourselves (just from CI) though, we
+ // still want to install it, as it otherwise won't be available.
+ return false;
+ }
}
// On macOS, rustc (and LLVM tools) link to an unversioned libLLVM.dylib
@@ -1881,12 +1926,12 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir
if llvm_dylib_path.exists() {
builder.install(&llvm_dylib_path, dst_libdir, 0o644);
}
- !builder.config.dry_run
+ !builder.config.dry_run()
} else if let Ok(llvm_config) = crate::native::prebuilt_llvm_config(builder, target) {
let mut cmd = Command::new(llvm_config);
cmd.arg("--libfiles");
builder.verbose(&format!("running {:?}", cmd));
- let files = if builder.config.dry_run { "".into() } else { output(&mut cmd) };
+ let files = if builder.config.dry_run() { "".into() } else { output(&mut cmd) };
let build_llvm_out = &builder.llvm_out(builder.config.build);
let target_llvm_out = &builder.llvm_out(target);
for file in files.trim_end().split(' ') {
@@ -1898,7 +1943,7 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir
};
builder.install(&file, dst_libdir, 0o644);
}
- !builder.config.dry_run
+ !builder.config.dry_run()
} else {
false
}
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index ea06caf9c..2c6fd1e1d 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -85,18 +85,6 @@ book!(
StyleGuide, "src/doc/style-guide", "style-guide";
);
-fn open(builder: &Builder<'_>, path: impl AsRef<Path>) {
- if builder.config.dry_run || !builder.config.cmd.open() {
- return;
- }
-
- let path = path.as_ref();
- builder.info(&format!("Opening doc {}", path.display()));
- if let Err(err) = opener::open(path) {
- builder.info(&format!("{}\n", err));
- }
-}
-
// "library/std" -> ["library", "std"]
//
// Used for deciding whether a particular step is one requested by the user on
@@ -163,7 +151,7 @@ impl Step for RustbookSrc {
let index = out.join("index.html");
let rustbook = builder.tool_exe(Tool::Rustbook);
let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
- if builder.config.dry_run || up_to_date(&src, &index) && up_to_date(&rustbook, &index) {
+ if builder.config.dry_run() || up_to_date(&src, &index) && up_to_date(&rustbook, &index) {
return;
}
builder.info(&format!("Rustbook ({}) - {}", target, name));
@@ -240,11 +228,9 @@ impl Step for TheBook {
invoke_rustdoc(builder, compiler, &shared_assets, target, path);
}
- if builder.was_invoked_explicitly::<Self>(Kind::Doc) {
- let out = builder.doc_out(target);
- let index = out.join("book").join("index.html");
- open(builder, &index);
- }
+ let out = builder.doc_out(target);
+ let index = out.join("book").join("index.html");
+ builder.maybe_open_in_browser::<Self>(index);
}
}
@@ -345,8 +331,8 @@ impl Step for Standalone {
&& up_to_date(&footer, &html)
&& up_to_date(&favicon, &html)
&& up_to_date(&full_toc, &html)
- && (builder.config.dry_run || up_to_date(&version_info, &html))
- && (builder.config.dry_run || up_to_date(&rustdoc, &html))
+ && (builder.config.dry_run() || up_to_date(&version_info, &html))
+ && (builder.config.dry_run() || up_to_date(&rustdoc, &html))
{
continue;
}
@@ -386,7 +372,7 @@ impl Step for Standalone {
// with no particular explicit doc requested (e.g. library/core).
if builder.paths.is_empty() || builder.was_invoked_explicitly::<Self>(Kind::Doc) {
let index = out.join("index.html");
- open(builder, &index);
+ builder.open_in_browser(&index);
}
}
}
@@ -416,11 +402,11 @@ impl Step for SharedAssets {
let version_input = builder.src.join("src").join("doc").join("version_info.html.template");
let version_info = out.join("version_info.html");
- if !builder.config.dry_run && !up_to_date(&version_input, &version_info) {
+ if !builder.config.dry_run() && !up_to_date(&version_input, &version_info) {
let info = t!(fs::read_to_string(&version_input))
.replace("VERSION", &builder.rust_release())
- .replace("SHORT_HASH", builder.rust_info.sha_short().unwrap_or(""))
- .replace("STAMP", builder.rust_info.sha().unwrap_or(""));
+ .replace("SHORT_HASH", builder.rust_info().sha_short().unwrap_or(""))
+ .replace("STAMP", builder.rust_info().sha().unwrap_or(""));
t!(fs::write(&version_info, &info));
}
@@ -434,6 +420,7 @@ impl Step for SharedAssets {
pub struct Std {
pub stage: u32,
pub target: TargetSelection,
+ pub format: DocumentationFormat,
}
impl Step for Std {
@@ -446,7 +433,15 @@ impl Step for Std {
}
fn make_run(run: RunConfig<'_>) {
- run.builder.ensure(Std { stage: run.builder.top_stage, target: run.target });
+ run.builder.ensure(Std {
+ stage: run.builder.top_stage,
+ target: run.target,
+ format: if run.builder.config.cmd.json() {
+ DocumentationFormat::JSON
+ } else {
+ DocumentationFormat::HTML
+ },
+ });
}
/// Compile all standard library documentation.
@@ -456,19 +451,28 @@ impl Step for Std {
fn run(self, builder: &Builder<'_>) {
let stage = self.stage;
let target = self.target;
- let out = builder.doc_out(target);
+ let out = match self.format {
+ DocumentationFormat::HTML => builder.doc_out(target),
+ DocumentationFormat::JSON => builder.json_doc_out(target),
+ };
+
t!(fs::create_dir_all(&out));
- builder.ensure(SharedAssets { target: self.target });
+ if self.format == DocumentationFormat::HTML {
+ builder.ensure(SharedAssets { target: self.target });
+ }
let index_page = builder.src.join("src/doc/index.md").into_os_string();
- let mut extra_args = vec![
- OsStr::new("--markdown-css"),
- OsStr::new("rust.css"),
- OsStr::new("--markdown-no-toc"),
- OsStr::new("--index-page"),
- &index_page,
- ];
+ let mut extra_args = match self.format {
+ DocumentationFormat::HTML => vec![
+ OsStr::new("--markdown-css"),
+ OsStr::new("rust.css"),
+ OsStr::new("--markdown-no-toc"),
+ OsStr::new("--index-page"),
+ &index_page,
+ ],
+ DocumentationFormat::JSON => vec![OsStr::new("--output-format"), OsStr::new("json")],
+ };
if !builder.config.docs_minification {
extra_args.push(OsStr::new("--disable-minification"));
@@ -492,59 +496,24 @@ impl Step for Std {
})
.collect::<Vec<_>>();
- doc_std(
- builder,
- DocumentationFormat::HTML,
- stage,
- target,
- &out,
- &extra_args,
- &requested_crates,
- );
+ doc_std(builder, self.format, stage, target, &out, &extra_args, &requested_crates);
+
+ // Don't open if the format is json
+ if let DocumentationFormat::JSON = self.format {
+ return;
+ }
// Look for library/std, library/core etc in the `x.py doc` arguments and
// open the corresponding rendered docs.
for requested_crate in requested_crates {
if STD_PUBLIC_CRATES.iter().any(|k| *k == requested_crate.as_str()) {
let index = out.join(requested_crate).join("index.html");
- open(builder, &index);
+ builder.open_in_browser(index);
}
}
}
}
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
-pub struct JsonStd {
- pub stage: u32,
- pub target: TargetSelection,
-}
-
-impl Step for JsonStd {
- type Output = ();
- const DEFAULT: bool = false;
-
- fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- let default = run.builder.config.docs && run.builder.config.cmd.json();
- run.all_krates("test").path("library").default_condition(default)
- }
-
- fn make_run(run: RunConfig<'_>) {
- run.builder.ensure(Std { stage: run.builder.top_stage, target: run.target });
- }
-
- /// Build JSON documentation for the standard library crates.
- ///
- /// This is largely just a wrapper around `cargo doc`.
- fn run(self, builder: &Builder<'_>) {
- let stage = self.stage;
- let target = self.target;
- let out = builder.json_doc_out(target);
- t!(fs::create_dir_all(&out));
- let extra_args = [OsStr::new("--output-format"), OsStr::new("json")];
- doc_std(builder, DocumentationFormat::JSON, stage, target, &out, &extra_args, &[])
- }
-}
-
/// Name of the crates that are visible to consumers of the standard library.
/// Documentation for internal crates is handled by the rustc step, so internal crates will show
/// up there.
@@ -557,7 +526,7 @@ impl Step for JsonStd {
const STD_PUBLIC_CRATES: [&str; 5] = ["core", "alloc", "std", "proc_macro", "test"];
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
-enum DocumentationFormat {
+pub enum DocumentationFormat {
HTML,
JSON,
}
@@ -597,27 +566,22 @@ fn doc_std(
);
}
let compiler = builder.compiler(stage, builder.config.build);
+
+ let target_doc_dir_name = if format == DocumentationFormat::JSON { "json-doc" } else { "doc" };
+ let target_dir =
+ builder.stage_out(compiler, Mode::Std).join(target.triple).join(target_doc_dir_name);
+
// This is directory where the compiler will place the output of the command.
// We will then copy the files from this directory into the final `out` directory, the specified
// as a function parameter.
- let out_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join("doc");
- // `cargo` uses the same directory for both JSON docs and HTML docs.
- // This could lead to cross-contamination when copying files into the specified `out` directory.
- // For example:
- // ```bash
- // x doc std
- // x doc std --json
- // ```
- // could lead to HTML docs being copied into the JSON docs output directory.
- // To avoid this issue, we clean the doc folder before invoking `cargo`.
- if out_dir.exists() {
- builder.remove_dir(&out_dir);
- }
+ let out_dir = target_dir.join(target.triple).join("doc");
let run_cargo_rustdoc_for = |package: &str| {
let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustdoc");
compile::std_cargo(builder, target, compiler.stage, &mut cargo);
cargo
+ .arg("--target-dir")
+ .arg(&*target_dir.to_string_lossy())
.arg("-p")
.arg(package)
.arg("-Zskip-rustdoc-fingerprint")
@@ -759,13 +723,13 @@ impl Step for Rustc {
// Let's open the first crate documentation page:
if let Some(krate) = to_open {
let index = out.join(krate).join("index.html");
- open(builder, &index);
+ builder.open_in_browser(index);
}
}
}
macro_rules! tool_doc {
- ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?], in_tree = $in_tree:expr $(,)?) => {
+ ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(,)?) => {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct $tool {
target: TargetSelection,
@@ -821,12 +785,6 @@ macro_rules! tool_doc {
t!(fs::create_dir_all(&out_dir));
t!(symlink_dir_force(&builder.config, &out, &out_dir));
- let source_type = if $in_tree == true {
- SourceType::InTree
- } else {
- SourceType::Submodule
- };
-
// Build cargo command.
let mut cargo = prepare_tool_cargo(
builder,
@@ -835,7 +793,7 @@ macro_rules! tool_doc {
target,
"doc",
$path,
- source_type,
+ SourceType::InTree,
&[],
);
@@ -851,38 +809,21 @@ macro_rules! tool_doc {
cargo.rustdocflag("--show-type-layout");
cargo.rustdocflag("--generate-link-to-definition");
cargo.rustdocflag("-Zunstable-options");
- if $in_tree == true {
- builder.run(&mut cargo.into());
- } else {
- // Allow out-of-tree docs to fail (since the tool might be in a broken state).
- if !builder.try_run(&mut cargo.into()) {
- builder.info(&format!(
- "WARNING: tool {} failed to document; ignoring failure because it is an out-of-tree tool",
- stringify!($tool).to_lowercase(),
- ));
- }
- }
+ builder.run(&mut cargo.into());
}
}
}
}
-tool_doc!(
- Rustdoc,
- "rustdoc-tool",
- "src/tools/rustdoc",
- ["rustdoc", "rustdoc-json-types"],
- in_tree = true
-);
+tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", ["rustdoc", "rustdoc-json-types"],);
tool_doc!(
Rustfmt,
"rustfmt-nightly",
"src/tools/rustfmt",
["rustfmt-nightly", "rustfmt-config_proc_macro"],
- in_tree = true
);
-tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"], in_tree = true);
-tool_doc!(Miri, "miri", "src/tools/miri", ["miri"], in_tree = false);
+tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"]);
+tool_doc!(Miri, "miri", "src/tools/miri", ["miri"]);
#[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct ErrorIndex {
@@ -956,7 +897,7 @@ impl Step for UnstableBookGen {
}
fn symlink_dir_force(config: &Config, src: &Path, dst: &Path) -> io::Result<()> {
- if config.dry_run {
+ if config.dry_run() {
return Ok(());
}
if let Ok(m) = fs::symlink_metadata(dst) {
@@ -1021,7 +962,7 @@ impl Step for RustcBook {
cmd.arg("--rustc");
cmd.arg(&rustc);
cmd.arg("--rustc-target").arg(&self.target.rustc_target_arg());
- if builder.config.verbose() {
+ if builder.is_verbose() {
cmd.arg("--verbose");
}
if self.validate {
@@ -1042,10 +983,9 @@ impl Step for RustcBook {
name: INTERNER.intern_str("rustc"),
src: INTERNER.intern_path(out_base),
});
- if builder.was_invoked_explicitly::<Self>(Kind::Doc) {
- let out = builder.doc_out(self.target);
- let index = out.join("rustc").join("index.html");
- open(builder, &index);
- }
+
+ let out = builder.doc_out(self.target);
+ let index = out.join("rustc").join("index.html");
+ builder.maybe_open_in_browser::<Self>(index);
}
}
diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs
new file mode 100644
index 000000000..6ae283f32
--- /dev/null
+++ b/src/bootstrap/download.rs
@@ -0,0 +1,520 @@
+use std::{
+ env,
+ ffi::{OsStr, OsString},
+ fs::{self, File},
+ io::{BufRead, BufReader, ErrorKind},
+ path::{Path, PathBuf},
+ process::{Command, Stdio},
+};
+
+use once_cell::sync::OnceCell;
+use xz2::bufread::XzDecoder;
+
+use crate::{
+ config::RustfmtMetadata,
+ native::detect_llvm_sha,
+ t,
+ util::{check_run, exe, program_out_of_date, try_run},
+ Config,
+};
+
+/// Generic helpers that are useful anywhere in bootstrap.
+impl Config {
+ pub fn is_verbose(&self) -> bool {
+ self.verbose > 0
+ }
+
+ pub(crate) fn create(&self, path: &Path, s: &str) {
+ if self.dry_run() {
+ return;
+ }
+ t!(fs::write(path, s));
+ }
+
+ pub(crate) fn remove(&self, f: &Path) {
+ if self.dry_run() {
+ return;
+ }
+ fs::remove_file(f).unwrap_or_else(|_| panic!("failed to remove {:?}", f));
+ }
+
+ /// Create a temporary directory in `out` and return its path.
+ ///
+ /// NOTE: this temporary directory is shared between all steps;
+ /// if you need an empty directory, create a new subdirectory inside it.
+ pub(crate) fn tempdir(&self) -> PathBuf {
+ let tmp = self.out.join("tmp");
+ t!(fs::create_dir_all(&tmp));
+ tmp
+ }
+
+ /// Runs a command, printing out nice contextual information if it fails.
+ /// Exits if the command failed to execute at all, otherwise returns its
+ /// `status.success()`.
+ pub(crate) fn try_run(&self, cmd: &mut Command) -> bool {
+ if self.dry_run() {
+ return true;
+ }
+ self.verbose(&format!("running: {:?}", cmd));
+ try_run(cmd, self.is_verbose())
+ }
+
+ /// Runs a command, printing out nice contextual information if it fails.
+ /// Returns false if do not execute at all, otherwise returns its
+ /// `status.success()`.
+ pub(crate) fn check_run(&self, cmd: &mut Command) -> bool {
+ if self.dry_run() {
+ return true;
+ }
+ self.verbose(&format!("running: {:?}", cmd));
+ check_run(cmd, self.is_verbose())
+ }
+
+ /// Modifies the interpreter section of 'fname' to fix the dynamic linker,
+ /// or the RPATH section, to fix the dynamic library search path
+ ///
+ /// This is only required on NixOS and uses the PatchELF utility to
+ /// change the interpreter/RPATH of ELF executables.
+ ///
+ /// Please see https://nixos.org/patchelf.html for more information
+ fn fix_bin_or_dylib(&self, fname: &Path) {
+ // FIXME: cache NixOS detection?
+ match Command::new("uname").arg("-s").stderr(Stdio::inherit()).output() {
+ Err(_) => return,
+ Ok(output) if !output.status.success() => return,
+ Ok(output) => {
+ let mut s = output.stdout;
+ if s.last() == Some(&b'\n') {
+ s.pop();
+ }
+ if s != b"Linux" {
+ return;
+ }
+ }
+ }
+
+ // If the user has asked binaries to be patched for Nix, then
+ // don't check for NixOS or `/lib`, just continue to the patching.
+ // NOTE: this intentionally comes after the Linux check:
+ // - patchelf only works with ELF files, so no need to run it on Mac or Windows
+ // - On other Unix systems, there is no stable syscall interface, so Nix doesn't manage the global libc.
+ if !self.patch_binaries_for_nix {
+ // Use `/etc/os-release` instead of `/etc/NIXOS`.
+ // The latter one does not exist on NixOS when using tmpfs as root.
+ const NIX_IDS: &[&str] = &["ID=nixos", "ID='nixos'", "ID=\"nixos\""];
+ let os_release = match File::open("/etc/os-release") {
+ Err(e) if e.kind() == ErrorKind::NotFound => return,
+ Err(e) => panic!("failed to access /etc/os-release: {}", e),
+ Ok(f) => f,
+ };
+ if !BufReader::new(os_release).lines().any(|l| NIX_IDS.contains(&t!(l).trim())) {
+ return;
+ }
+ if Path::new("/lib").exists() {
+ return;
+ }
+ }
+
+ // At this point we're pretty sure the user is running NixOS or using Nix
+ println!("info: you seem to be using Nix. Attempting to patch {}", fname.display());
+
+ // Only build `.nix-deps` once.
+ static NIX_DEPS_DIR: OnceCell<PathBuf> = OnceCell::new();
+ let mut nix_build_succeeded = true;
+ let nix_deps_dir = NIX_DEPS_DIR.get_or_init(|| {
+ // Run `nix-build` to "build" each dependency (which will likely reuse
+ // the existing `/nix/store` copy, or at most download a pre-built copy).
+ //
+ // Importantly, we create a gc-root called `.nix-deps` in the `build/`
+ // directory, but still reference the actual `/nix/store` path in the rpath
+ // as it makes it significantly more robust against changes to the location of
+ // the `.nix-deps` location.
+ //
+ // bintools: Needed for the path of `ld-linux.so` (via `nix-support/dynamic-linker`).
+ // zlib: Needed as a system dependency of `libLLVM-*.so`.
+ // patchelf: Needed for patching ELF binaries (see doc comment above).
+ let nix_deps_dir = self.out.join(".nix-deps");
+ const NIX_EXPR: &str = "
+ with (import <nixpkgs> {});
+ symlinkJoin {
+ name = \"rust-stage0-dependencies\";
+ paths = [
+ zlib
+ patchelf
+ stdenv.cc.bintools
+ ];
+ }
+ ";
+ nix_build_succeeded = self.try_run(Command::new("nix-build").args(&[
+ Path::new("-E"),
+ Path::new(NIX_EXPR),
+ Path::new("-o"),
+ &nix_deps_dir,
+ ]));
+ nix_deps_dir
+ });
+ if !nix_build_succeeded {
+ return;
+ }
+
+ let mut patchelf = Command::new(nix_deps_dir.join("bin/patchelf"));
+ let rpath_entries = {
+ // ORIGIN is a relative default, all binary and dynamic libraries we ship
+ // appear to have this (even when `../lib` is redundant).
+ // NOTE: there are only two paths here, delimited by a `:`
+ let mut entries = OsString::from("$ORIGIN/../lib:");
+ entries.push(t!(fs::canonicalize(nix_deps_dir)));
+ entries.push("/lib");
+ entries
+ };
+ patchelf.args(&[OsString::from("--set-rpath"), rpath_entries]);
+ if !fname.extension().map_or(false, |ext| ext == "so") {
+ // Finally, set the correct .interp for binaries
+ let dynamic_linker_path = nix_deps_dir.join("nix-support/dynamic-linker");
+ // FIXME: can we support utf8 here? `args` doesn't accept Vec<u8>, only OsString ...
+ let dynamic_linker = t!(String::from_utf8(t!(fs::read(dynamic_linker_path))));
+ patchelf.args(&["--set-interpreter", dynamic_linker.trim_end()]);
+ }
+
+ self.try_run(patchelf.arg(fname));
+ }
+
+ fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) {
+ self.verbose(&format!("download {url}"));
+ // Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/.
+ let tempfile = self.tempdir().join(dest_path.file_name().unwrap());
+ // While bootstrap itself only supports http and https downloads, downstream forks might
+ // need to download components from other protocols. The match allows them adding more
+ // protocols without worrying about merge conflicts if we change the HTTP implementation.
+ match url.split_once("://").map(|(proto, _)| proto) {
+ Some("http") | Some("https") => {
+ self.download_http_with_retries(&tempfile, url, help_on_error)
+ }
+ Some(other) => panic!("unsupported protocol {other} in {url}"),
+ None => panic!("no protocol in {url}"),
+ }
+ t!(std::fs::rename(&tempfile, dest_path));
+ }
+
+ fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
+ println!("downloading {}", url);
+ // Try curl. If that fails and we are on windows, fallback to PowerShell.
+ let mut curl = Command::new("curl");
+ curl.args(&[
+ "-#",
+ "-y",
+ "30",
+ "-Y",
+ "10", // timeout if speed is < 10 bytes/sec for > 30 seconds
+ "--connect-timeout",
+ "30", // timeout if cannot connect within 30 seconds
+ "--retry",
+ "3",
+ "-Sf",
+ "-o",
+ ]);
+ curl.arg(tempfile);
+ curl.arg(url);
+ if !self.check_run(&mut curl) {
+ if self.build.contains("windows-msvc") {
+ println!("Fallback to PowerShell");
+ for _ in 0..3 {
+ if self.try_run(Command::new("PowerShell.exe").args(&[
+ "/nologo",
+ "-Command",
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;",
+ &format!(
+ "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')",
+ url, tempfile.to_str().expect("invalid UTF-8 not supported with powershell downloads"),
+ ),
+ ])) {
+ return;
+ }
+ println!("\nspurious failure, trying again");
+ }
+ }
+ if !help_on_error.is_empty() {
+ eprintln!("{}", help_on_error);
+ }
+ crate::detail_exit(1);
+ }
+ }
+
+ fn unpack(&self, tarball: &Path, dst: &Path, pattern: &str) {
+ println!("extracting {} to {}", tarball.display(), dst.display());
+ if !dst.exists() {
+ t!(fs::create_dir_all(dst));
+ }
+
+ // `tarball` ends with `.tar.xz`; strip that suffix
+ // example: `rust-dev-nightly-x86_64-unknown-linux-gnu`
+ let uncompressed_filename =
+ Path::new(tarball.file_name().expect("missing tarball filename")).file_stem().unwrap();
+ let directory_prefix = Path::new(Path::new(uncompressed_filename).file_stem().unwrap());
+
+ // decompress the file
+ let data = t!(File::open(tarball));
+ let decompressor = XzDecoder::new(BufReader::new(data));
+
+ let mut tar = tar::Archive::new(decompressor);
+ for member in t!(tar.entries()) {
+ let mut member = t!(member);
+ let original_path = t!(member.path()).into_owned();
+ // skip the top-level directory
+ if original_path == directory_prefix {
+ continue;
+ }
+ let mut short_path = t!(original_path.strip_prefix(directory_prefix));
+ if !short_path.starts_with(pattern) {
+ continue;
+ }
+ short_path = t!(short_path.strip_prefix(pattern));
+ let dst_path = dst.join(short_path);
+ self.verbose(&format!("extracting {} to {}", original_path.display(), dst.display()));
+ if !t!(member.unpack_in(dst)) {
+ panic!("path traversal attack ??");
+ }
+ let src_path = dst.join(original_path);
+ if src_path.is_dir() && dst_path.exists() {
+ continue;
+ }
+ t!(fs::rename(src_path, dst_path));
+ }
+ t!(fs::remove_dir_all(dst.join(directory_prefix)));
+ }
+
+ /// Returns whether the SHA256 checksum of `path` matches `expected`.
+ fn verify(&self, path: &Path, expected: &str) -> bool {
+ use sha2::Digest;
+
+ self.verbose(&format!("verifying {}", path.display()));
+ let mut hasher = sha2::Sha256::new();
+ // FIXME: this is ok for rustfmt (4.1 MB large at time of writing), but it seems memory-intensive for rustc and larger components.
+ // Consider using streaming IO instead?
+ let contents = if self.dry_run() { vec![] } else { t!(fs::read(path)) };
+ hasher.update(&contents);
+ let found = hex::encode(hasher.finalize().as_slice());
+ let verified = found == expected;
+ if !verified && !self.dry_run() {
+ println!(
+ "invalid checksum: \n\
+ found: {found}\n\
+ expected: {expected}",
+ );
+ }
+ return verified;
+ }
+}
+
+enum DownloadSource {
+ CI,
+ Dist,
+}
+
+/// Functions that are only ever called once, but named for clarify and to avoid thousand-line functions.
+impl Config {
+ pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
+ let RustfmtMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?;
+ let channel = format!("{version}-{date}");
+
+ let host = self.build;
+ let rustfmt_path = self.initial_rustc.with_file_name(exe("rustfmt", host));
+ let bin_root = self.out.join(host.triple).join("stage0");
+ let rustfmt_stamp = bin_root.join(".rustfmt-stamp");
+ if rustfmt_path.exists() && !program_out_of_date(&rustfmt_stamp, &channel) {
+ return Some(rustfmt_path);
+ }
+
+ let filename = format!("rustfmt-{version}-{build}.tar.xz", build = host.triple);
+ self.download_component(DownloadSource::Dist, filename, "rustfmt-preview", &date, "stage0");
+
+ self.fix_bin_or_dylib(&bin_root.join("bin").join("rustfmt"));
+ self.fix_bin_or_dylib(&bin_root.join("bin").join("cargo-fmt"));
+
+ self.create(&rustfmt_stamp, &channel);
+ Some(rustfmt_path)
+ }
+
+ pub(crate) fn download_ci_rustc(&self, commit: &str) {
+ self.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})"));
+ let version = self.artifact_version_part(commit);
+ let host = self.build.triple;
+ let bin_root = self.out.join(host).join("ci-rustc");
+ let rustc_stamp = bin_root.join(".rustc-stamp");
+
+ if !bin_root.join("bin").join("rustc").exists() || program_out_of_date(&rustc_stamp, commit)
+ {
+ if bin_root.exists() {
+ t!(fs::remove_dir_all(&bin_root));
+ }
+ let filename = format!("rust-std-{version}-{host}.tar.xz");
+ let pattern = format!("rust-std-{host}");
+ self.download_ci_component(filename, &pattern, commit);
+ let filename = format!("rustc-{version}-{host}.tar.xz");
+ self.download_ci_component(filename, "rustc", commit);
+ // download-rustc doesn't need its own cargo, it can just use beta's.
+ let filename = format!("rustc-dev-{version}-{host}.tar.xz");
+ self.download_ci_component(filename, "rustc-dev", commit);
+ let filename = format!("rust-src-{version}.tar.xz");
+ self.download_ci_component(filename, "rust-src", commit);
+
+ self.fix_bin_or_dylib(&bin_root.join("bin").join("rustc"));
+ self.fix_bin_or_dylib(&bin_root.join("bin").join("rustdoc"));
+ self.fix_bin_or_dylib(&bin_root.join("libexec").join("rust-analyzer-proc-macro-srv"));
+ let lib_dir = bin_root.join("lib");
+ for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) {
+ let lib = t!(lib);
+ if lib.path().extension() == Some(OsStr::new("so")) {
+ self.fix_bin_or_dylib(&lib.path());
+ }
+ }
+ t!(fs::write(rustc_stamp, commit));
+ }
+ }
+
+ /// Download a single component of a CI-built toolchain (not necessarily a published nightly).
+ // NOTE: intentionally takes an owned string to avoid downloading multiple times by accident
+ fn download_ci_component(&self, filename: String, prefix: &str, commit: &str) {
+ Self::download_component(self, DownloadSource::CI, filename, prefix, commit, "ci-rustc")
+ }
+
+ fn download_component(
+ &self,
+ mode: DownloadSource,
+ filename: String,
+ prefix: &str,
+ key: &str,
+ destination: &str,
+ ) {
+ let cache_dst = self.out.join("cache");
+ let cache_dir = cache_dst.join(key);
+ if !cache_dir.exists() {
+ t!(fs::create_dir_all(&cache_dir));
+ }
+
+ let bin_root = self.out.join(self.build.triple).join(destination);
+ let tarball = cache_dir.join(&filename);
+ let (base_url, url, should_verify) = match mode {
+ DownloadSource::CI => (
+ self.stage0_metadata.config.artifacts_server.clone(),
+ format!("{key}/{filename}"),
+ false,
+ ),
+ DownloadSource::Dist => {
+ let dist_server = env::var("RUSTUP_DIST_SERVER")
+ .unwrap_or(self.stage0_metadata.config.dist_server.to_string());
+ // NOTE: make `dist` part of the URL because that's how it's stored in src/stage0.json
+ (dist_server, format!("dist/{key}/{filename}"), true)
+ }
+ };
+
+ // For the beta compiler, put special effort into ensuring the checksums are valid.
+ // FIXME: maybe we should do this for download-rustc as well? but it would be a pain to update
+ // this on each and every nightly ...
+ let checksum = if should_verify {
+ let error = format!(
+ "src/stage0.json doesn't contain a checksum for {url}. \
+ Pre-built artifacts might not be available for this \
+ target at this time, see https://doc.rust-lang.org/nightly\
+ /rustc/platform-support.html for more information."
+ );
+ let sha256 = self.stage0_metadata.checksums_sha256.get(&url).expect(&error);
+ if tarball.exists() {
+ if self.verify(&tarball, sha256) {
+ self.unpack(&tarball, &bin_root, prefix);
+ return;
+ } else {
+ self.verbose(&format!(
+ "ignoring cached file {} due to failed verification",
+ tarball.display()
+ ));
+ self.remove(&tarball);
+ }
+ }
+ Some(sha256)
+ } else if tarball.exists() {
+ self.unpack(&tarball, &bin_root, prefix);
+ return;
+ } else {
+ None
+ };
+
+ self.download_file(&format!("{base_url}/{url}"), &tarball, "");
+ if let Some(sha256) = checksum {
+ if !self.verify(&tarball, sha256) {
+ panic!("failed to verify {}", tarball.display());
+ }
+ }
+
+ self.unpack(&tarball, &bin_root, prefix);
+ }
+
+ pub(crate) fn maybe_download_ci_llvm(&self) {
+ if !self.llvm_from_ci {
+ return;
+ }
+ let llvm_root = self.ci_llvm_root();
+ let llvm_stamp = llvm_root.join(".llvm-stamp");
+ let llvm_sha = detect_llvm_sha(&self, self.rust_info.is_managed_git_subrepository());
+ let key = format!("{}{}", llvm_sha, self.llvm_assertions);
+ if program_out_of_date(&llvm_stamp, &key) && !self.dry_run() {
+ self.download_ci_llvm(&llvm_sha);
+ for entry in t!(fs::read_dir(llvm_root.join("bin"))) {
+ self.fix_bin_or_dylib(&t!(entry).path());
+ }
+
+ // Update the timestamp of llvm-config to force rustc_llvm to be
+ // rebuilt. This is a hacky workaround for a deficiency in Cargo where
+ // the rerun-if-changed directive doesn't handle changes very well.
+ // https://github.com/rust-lang/cargo/issues/10791
+ // Cargo only compares the timestamp of the file relative to the last
+ // time `rustc_llvm` build script ran. However, the timestamps of the
+ // files in the tarball are in the past, so it doesn't trigger a
+ // rebuild.
+ let now = filetime::FileTime::from_system_time(std::time::SystemTime::now());
+ let llvm_config = llvm_root.join("bin").join(exe("llvm-config", self.build));
+ t!(filetime::set_file_times(&llvm_config, now, now));
+
+ let llvm_lib = llvm_root.join("lib");
+ for entry in t!(fs::read_dir(&llvm_lib)) {
+ let lib = t!(entry).path();
+ if lib.extension().map_or(false, |ext| ext == "so") {
+ self.fix_bin_or_dylib(&lib);
+ }
+ }
+ t!(fs::write(llvm_stamp, key));
+ }
+ }
+
+ fn download_ci_llvm(&self, llvm_sha: &str) {
+ let llvm_assertions = self.llvm_assertions;
+
+ let cache_prefix = format!("llvm-{}-{}", llvm_sha, llvm_assertions);
+ let cache_dst = self.out.join("cache");
+ let rustc_cache = cache_dst.join(cache_prefix);
+ if !rustc_cache.exists() {
+ t!(fs::create_dir_all(&rustc_cache));
+ }
+ let base = if llvm_assertions {
+ &self.stage0_metadata.config.artifacts_with_llvm_assertions_server
+ } else {
+ &self.stage0_metadata.config.artifacts_server
+ };
+ let version = self.artifact_version_part(llvm_sha);
+ let filename = format!("rust-dev-{}-{}.tar.xz", version, self.build.triple);
+ let tarball = rustc_cache.join(&filename);
+ if !tarball.exists() {
+ let help_on_error = "error: failed to download llvm from ci
+
+ help: old builds get deleted after a certain time
+ help: if trying to compile an old commit of rustc, disable `download-ci-llvm` in config.toml:
+
+ [llvm]
+ download-ci-llvm = false
+ ";
+ self.download_file(&format!("{base}/{llvm_sha}/{filename}"), &tarball, help_on_error);
+ }
+ let llvm_root = self.ci_llvm_root();
+ self.unpack(&tarball, &llvm_root, "rust-dev");
+ }
+}
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index ee341a353..37a8eb884 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -140,9 +140,10 @@ pub enum Subcommand {
},
Run {
paths: Vec<PathBuf>,
+ args: Vec<String>,
},
Setup {
- profile: Profile,
+ profile: Option<Profile>,
},
}
@@ -342,6 +343,9 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
Kind::Format => {
opts.optflag("", "check", "check formatting instead of applying.");
}
+ Kind::Run => {
+ opts.optmulti("", "args", "arguments for the tool", "ARGS");
+ }
_ => {}
};
@@ -613,7 +617,7 @@ Arguments:
println!("\nrun requires at least a path!\n");
usage(1, &opts, verbose, &subcommand_help);
}
- Subcommand::Run { paths }
+ Subcommand::Run { paths, args: matches.opt_strs("args") }
}
Kind::Setup => {
let profile = if paths.len() > 1 {
@@ -624,14 +628,15 @@ Arguments:
|path| format!("{} is not a valid UTF8 string", path.to_string_lossy())
));
- profile_string.parse().unwrap_or_else(|err| {
+ let profile = profile_string.parse().unwrap_or_else(|err| {
eprintln!("error: {}", err);
eprintln!("help: the available profiles are:");
eprint!("{}", Profile::all_for_help("- "));
crate::detail_exit(1);
- })
+ });
+ Some(profile)
} else {
- t!(crate::setup::interactive_path())
+ None
};
Subcommand::Setup { profile }
}
@@ -721,16 +726,12 @@ impl Subcommand {
}
pub fn test_args(&self) -> Vec<&str> {
- let mut args = vec![];
-
match *self {
Subcommand::Test { ref test_args, .. } | Subcommand::Bench { ref test_args, .. } => {
- args.extend(test_args.iter().flat_map(|s| s.split_whitespace()))
+ test_args.iter().flat_map(|s| s.split_whitespace()).collect()
}
- _ => (),
+ _ => vec![],
}
-
- args
}
pub fn rustc_args(&self) -> Vec<&str> {
@@ -738,7 +739,16 @@ impl Subcommand {
Subcommand::Test { ref rustc_args, .. } => {
rustc_args.iter().flat_map(|s| s.split_whitespace()).collect()
}
- _ => Vec::new(),
+ _ => vec![],
+ }
+ }
+
+ pub fn args(&self) -> Vec<&str> {
+ match *self {
+ Subcommand::Run { ref args, .. } => {
+ args.iter().flat_map(|s| s.split_whitespace()).collect()
+ }
+ _ => vec![],
}
}
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs
index 37322670e..5e7264fe7 100644
--- a/src/bootstrap/format.rs
+++ b/src/bootstrap/format.rs
@@ -43,7 +43,7 @@ struct RustfmtConfig {
}
pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
- if build.config.dry_run {
+ if build.config.dry_run() {
return;
}
let mut builder = ignore::types::TypesBuilder::new();
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index 7672b7c91..38426f3a4 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -200,10 +200,14 @@ install!((self, builder, _config),
install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball);
};
Miri, alias = "miri", Self::should_build(_config), only_hosts: true, {
- let tarball = builder
- .ensure(dist::Miri { compiler: self.compiler, target: self.target })
- .expect("missing miri");
- install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
+ if let Some(tarball) = builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }) {
+ install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
+ } else {
+ // Miri is only available on nightly
+ builder.info(
+ &format!("skipping Install miri stage{} ({})", self.compiler.stage, self.target),
+ );
+ }
};
Rustfmt, alias = "rustfmt", Self::should_build(_config), only_hosts: true, {
if let Some(tarball) = builder.ensure(dist::Rustfmt {
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 7e70e99bb..3ed534523 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -112,15 +112,14 @@ use std::path::{Path, PathBuf};
use std::process::Command;
use std::str;
-use config::Target;
+use channel::GitInfo;
+use config::{DryRun, Target};
use filetime::FileTime;
use once_cell::sync::OnceCell;
use crate::builder::Kind;
use crate::config::{LlvmLibunwind, TargetSelection};
-use crate::util::{
- check_run, exe, libdir, mtime, output, run, run_suppressed, try_run, try_run_suppressed, CiEnv,
-};
+use crate::util::{exe, libdir, mtime, output, run, run_suppressed, try_run_suppressed, CiEnv};
mod bolt;
mod builder;
@@ -133,6 +132,7 @@ mod compile;
mod config;
mod dist;
mod doc;
+mod download;
mod flags;
mod format;
mod install;
@@ -281,7 +281,6 @@ pub struct Build {
src: PathBuf,
out: PathBuf,
bootstrap_out: PathBuf,
- rust_info: channel::GitInfo,
cargo_info: channel::GitInfo,
rust_analyzer_info: channel::GitInfo,
clippy_info: channel::GitInfo,
@@ -396,6 +395,28 @@ pub enum CLang {
Cxx,
}
+macro_rules! forward {
+ ( $( $fn:ident( $($param:ident: $ty:ty),* ) $( -> $ret:ty)? ),+ $(,)? ) => {
+ impl Build {
+ $( fn $fn(&self, $($param: $ty),* ) $( -> $ret)? {
+ self.config.$fn( $($param),* )
+ } )+
+ }
+ }
+}
+
+forward! {
+ verbose(msg: &str),
+ is_verbose() -> bool,
+ create(path: &Path, s: &str),
+ remove(f: &Path),
+ tempdir() -> PathBuf,
+ try_run(cmd: &mut Command) -> bool,
+ llvm_link_shared() -> bool,
+ download_rustc() -> bool,
+ initial_rustfmt() -> Option<PathBuf>,
+}
+
impl Build {
/// Creates a new set of build configuration from the `flags` on the command
/// line and the filesystem `config`.
@@ -430,7 +451,7 @@ impl Build {
// we always try to use git for LLVM builds
let in_tree_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-project"));
- let initial_target_libdir_str = if config.dry_run {
+ let initial_target_libdir_str = if config.dry_run() {
"/dummy/lib/path/to/lib/".to_string()
} else {
output(
@@ -444,7 +465,7 @@ impl Build {
let initial_target_dir = Path::new(&initial_target_libdir_str).parent().unwrap();
let initial_lld = initial_target_dir.join("bin").join("rust-lld");
- let initial_sysroot = if config.dry_run {
+ let initial_sysroot = if config.dry_run() {
"/dummy".to_string()
} else {
output(Command::new(&config.initial_rustc).arg("--print").arg("sysroot"))
@@ -499,7 +520,6 @@ impl Build {
out,
bootstrap_out,
- rust_info,
cargo_info,
rust_analyzer_info,
clippy_info,
@@ -522,16 +542,6 @@ impl Build {
metrics: metrics::BuildMetrics::init(),
};
- build.verbose("finding compilers");
- cc_detect::find(&mut build);
- // When running `setup`, the profile is about to change, so any requirements we have now may
- // be different on the next invocation. Don't check for them until the next time x.py is
- // run. This is ok because `setup` never runs any build commands, so it won't fail if commands are missing.
- if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
- build.verbose("running sanity check");
- sanity::check(&mut build);
- }
-
// If local-rust is the same major.minor as the current version, then force a
// local-rebuild
let local_version_verbose =
@@ -547,16 +557,34 @@ impl Build {
build.local_rebuild = true;
}
- // Make sure we update these before gathering metadata so we don't get an error about missing
- // Cargo.toml files.
- let rust_submodules =
- ["src/tools/rust-installer", "src/tools/cargo", "library/backtrace", "library/stdarch"];
- for s in rust_submodules {
- build.update_submodule(Path::new(s));
- }
+ build.verbose("finding compilers");
+ cc_detect::find(&mut build);
+ // When running `setup`, the profile is about to change, so any requirements we have now may
+ // be different on the next invocation. Don't check for them until the next time x.py is
+ // run. This is ok because `setup` never runs any build commands, so it won't fail if commands are missing.
+ //
+ // Similarly, for `setup` we don't actually need submodules or cargo metadata.
+ if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
+ build.verbose("running sanity check");
+ sanity::check(&mut build);
+
+ // Make sure we update these before gathering metadata so we don't get an error about missing
+ // Cargo.toml files.
+ let rust_submodules = [
+ "src/tools/rust-installer",
+ "src/tools/cargo",
+ "library/backtrace",
+ "library/stdarch",
+ ];
+ for s in rust_submodules {
+ build.update_submodule(Path::new(s));
+ }
+ // Now, update all existing submodules.
+ build.update_existing_submodules();
- build.verbose("learning about cargo");
- metadata::build(&mut build);
+ build.verbose("learning about cargo");
+ metadata::build(&mut build);
+ }
build
}
@@ -570,7 +598,7 @@ impl Build {
t!(std::fs::read_dir(dir)).next().is_none()
}
- if !self.config.submodules(&self.rust_info) {
+ if !self.config.submodules(&self.rust_info()) {
return;
}
@@ -628,15 +656,29 @@ impl Build {
self.run(&mut update(false));
}
+ // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error).
+ let has_local_modifications = !self.try_run(
+ Command::new("git")
+ .args(&["diff-index", "--quiet", "HEAD"])
+ .current_dir(&absolute_path),
+ );
+ if has_local_modifications {
+ self.run(Command::new("git").args(&["stash", "push"]).current_dir(&absolute_path));
+ }
+
self.run(Command::new("git").args(&["reset", "-q", "--hard"]).current_dir(&absolute_path));
- self.run(Command::new("git").args(&["clean", "-qdfx"]).current_dir(absolute_path));
+ self.run(Command::new("git").args(&["clean", "-qdfx"]).current_dir(&absolute_path));
+
+ if has_local_modifications {
+ self.run(Command::new("git").args(&["stash", "pop"]).current_dir(absolute_path));
+ }
}
/// If any submodule has been initialized already, sync it unconditionally.
/// This avoids contributors checking in a submodule change by accident.
- pub fn maybe_update_submodules(&self) {
+ pub fn update_existing_submodules(&self) {
// Avoid running git when there isn't a git checkout.
- if !self.config.submodules(&self.rust_info) {
+ if !self.config.submodules(&self.rust_info()) {
return;
}
let output = output(
@@ -663,8 +705,6 @@ impl Build {
job::setup(self);
}
- self.maybe_update_submodules();
-
if let Subcommand::Format { check, paths } = &self.config.cmd {
return format::format(&builder::Builder::new(&self), *check, &paths);
}
@@ -689,13 +729,13 @@ impl Build {
}
}
- if !self.config.dry_run {
+ if !self.config.dry_run() {
{
- self.config.dry_run = true;
+ self.config.dry_run = DryRun::SelfCheck;
let builder = builder::Builder::new(&self);
builder.execute_cli();
}
- self.config.dry_run = false;
+ self.config.dry_run = DryRun::Disabled;
let builder = builder::Builder::new(&self);
builder.execute_cli();
} else {
@@ -735,6 +775,10 @@ impl Build {
cleared
}
+ fn rust_info(&self) -> &GitInfo {
+ &self.config.rust_info
+ }
+
/// Gets the space-separated set of activated features for the standard
/// library.
fn std_features(&self, target: TargetSelection) -> String {
@@ -947,7 +991,7 @@ impl Build {
/// Runs a command, printing out nice contextual information if it fails.
fn run(&self, cmd: &mut Command) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
self.verbose(&format!("running: {:?}", cmd));
@@ -956,7 +1000,7 @@ impl Build {
/// Runs a command, printing out nice contextual information if it fails.
fn run_quiet(&self, cmd: &mut Command) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
self.verbose(&format!("running: {:?}", cmd));
@@ -966,47 +1010,14 @@ impl Build {
/// Runs a command, printing out nice contextual information if it fails.
/// Exits if the command failed to execute at all, otherwise returns its
/// `status.success()`.
- fn try_run(&self, cmd: &mut Command) -> bool {
- if self.config.dry_run {
- return true;
- }
- self.verbose(&format!("running: {:?}", cmd));
- try_run(cmd, self.is_verbose())
- }
-
- /// Runs a command, printing out nice contextual information if it fails.
- /// Exits if the command failed to execute at all, otherwise returns its
- /// `status.success()`.
fn try_run_quiet(&self, cmd: &mut Command) -> bool {
- if self.config.dry_run {
+ if self.config.dry_run() {
return true;
}
self.verbose(&format!("running: {:?}", cmd));
try_run_suppressed(cmd)
}
- /// Runs a command, printing out nice contextual information if it fails.
- /// Returns false if do not execute at all, otherwise returns its
- /// `status.success()`.
- fn check_run(&self, cmd: &mut Command) -> bool {
- if self.config.dry_run {
- return true;
- }
- self.verbose(&format!("running: {:?}", cmd));
- check_run(cmd, self.is_verbose())
- }
-
- pub fn is_verbose(&self) -> bool {
- self.verbosity > 0
- }
-
- /// Prints a message if this build is configured in verbose mode.
- fn verbose(&self, msg: &str) {
- if self.is_verbose() {
- println!("{}", msg);
- }
- }
-
pub fn is_verbose_than(&self, level: usize) -> bool {
self.verbosity > level
}
@@ -1019,10 +1030,12 @@ impl Build {
}
fn info(&self, msg: &str) {
- if self.config.dry_run {
- return;
+ match self.config.dry_run {
+ DryRun::SelfCheck => return,
+ DryRun::Disabled | DryRun::UserSelected => {
+ println!("{}", msg);
+ }
}
- println!("{}", msg);
}
/// Returns the number of parallel jobs that have been configured for this
@@ -1152,8 +1165,8 @@ impl Build {
options[0] = Some("-Clink-arg=-fuse-ld=lld".to_string());
}
- let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" };
- options[1] = Some(format!("-Clink-arg=-Wl,{}", threads));
+ let no_threads = util::lld_flag_no_threads(target.contains("windows"));
+ options[1] = Some(format!("-Clink-arg=-Wl,{}", no_threads));
}
IntoIterator::into_iter(options).flatten()
@@ -1267,7 +1280,7 @@ impl Build {
match &self.config.channel[..] {
"stable" => num.to_string(),
"beta" => {
- if self.rust_info.is_managed_git_subrepository() && !self.config.ignore_git {
+ if self.rust_info().is_managed_git_subrepository() && !self.config.ignore_git {
format!("{}-beta.{}", num, self.beta_prerelease_version())
} else {
format!("{}-beta", num)
@@ -1327,7 +1340,7 @@ impl Build {
/// Note that this is a descriptive string which includes the commit date,
/// sha, version, etc.
fn rust_version(&self) -> String {
- let mut version = self.rust_info.version(self, &self.version);
+ let mut version = self.rust_info().version(self, &self.version);
if let Some(ref s) = self.config.description {
version.push_str(" (");
version.push_str(s);
@@ -1338,7 +1351,7 @@ impl Build {
/// Returns the full commit hash.
fn rust_sha(&self) -> Option<&str> {
- self.rust_info.sha()
+ self.rust_info().sha()
}
/// Returns the `a.b.c` version that the given package is at.
@@ -1400,7 +1413,7 @@ impl Build {
}
fn read_stamp_file(&self, stamp: &Path) -> Vec<(PathBuf, DependencyType)> {
- if self.config.dry_run {
+ if self.config.dry_run() {
return Vec::new();
}
@@ -1424,23 +1437,13 @@ impl Build {
paths
}
- /// Create a temporary directory in `out` and return its path.
- ///
- /// NOTE: this temporary directory is shared between all steps;
- /// if you need an empty directory, create a new subdirectory inside it.
- fn tempdir(&self) -> PathBuf {
- let tmp = self.out.join("tmp");
- t!(fs::create_dir_all(&tmp));
- tmp
- }
-
/// Copies a file from `src` to `dst`
pub fn copy(&self, src: &Path, dst: &Path) {
self.copy_internal(src, dst, false);
}
fn copy_internal(&self, src: &Path, dst: &Path, dereference_symlinks: bool) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
@@ -1477,7 +1480,7 @@ impl Build {
/// Copies the `src` directory recursively to `dst`. Both are assumed to exist
/// when this function is called.
pub fn cp_r(&self, src: &Path, dst: &Path) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
for f in self.read_dir(src) {
@@ -1530,7 +1533,7 @@ impl Build {
}
fn install(&self, src: &Path, dstdir: &Path, perms: u32) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
let dst = dstdir.join(src.file_name().unwrap());
@@ -1543,29 +1546,22 @@ impl Build {
chmod(&dst, perms);
}
- fn create(&self, path: &Path, s: &str) {
- if self.config.dry_run {
- return;
- }
- t!(fs::write(path, s));
- }
-
fn read(&self, path: &Path) -> String {
- if self.config.dry_run {
+ if self.config.dry_run() {
return String::new();
}
t!(fs::read_to_string(path))
}
fn create_dir(&self, dir: &Path) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
t!(fs::create_dir_all(dir))
}
fn remove_dir(&self, dir: &Path) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
t!(fs::remove_dir_all(dir))
@@ -1574,7 +1570,7 @@ impl Build {
fn read_dir(&self, dir: &Path) -> impl Iterator<Item = fs::DirEntry> {
let iter = match fs::read_dir(dir) {
Ok(v) => v,
- Err(_) if self.config.dry_run => return vec![].into_iter(),
+ Err(_) if self.config.dry_run() => return vec![].into_iter(),
Err(err) => panic!("could not read dir {:?}: {:?}", dir, err),
};
iter.map(|e| t!(e)).collect::<Vec<_>>().into_iter()
@@ -1585,14 +1581,7 @@ impl Build {
use std::os::unix::fs::symlink as symlink_file;
#[cfg(windows)]
use std::os::windows::fs::symlink_file;
- if !self.config.dry_run { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) }
- }
-
- fn remove(&self, f: &Path) {
- if self.config.dry_run {
- return;
- }
- fs::remove_file(f).unwrap_or_else(|_| panic!("failed to remove {:?}", f));
+ if !self.config.dry_run() { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) }
}
/// Returns if config.ninja is enabled, and checks for ninja existence,
diff --git a/src/bootstrap/metrics.rs b/src/bootstrap/metrics.rs
index 451febddc..c823dc796 100644
--- a/src/bootstrap/metrics.rs
+++ b/src/bootstrap/metrics.rs
@@ -97,7 +97,7 @@ impl BuildMetrics {
cpu_threads_count: system.cpus().len(),
cpu_model: system.cpus()[0].brand().into(),
- memory_total_bytes: system.total_memory() * 1024,
+ memory_total_bytes: system.total_memory(),
};
let steps = std::mem::take(&mut state.finished_steps);
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 2f856c276..f6c453ebe 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -19,9 +19,9 @@ use std::process::Command;
use crate::bolt::{instrument_with_bolt_inplace, optimize_library_with_bolt_inplace};
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::channel;
-use crate::config::TargetSelection;
+use crate::config::{Config, TargetSelection};
use crate::util::get_clang_cl_resource_dir;
-use crate::util::{self, exe, output, program_out_of_date, t, up_to_date};
+use crate::util::{self, exe, output, t, up_to_date};
use crate::{CLang, GitRepo};
pub struct Meta {
@@ -65,7 +65,7 @@ pub fn prebuilt_llvm_config(
builder: &Builder<'_>,
target: TargetSelection,
) -> Result<PathBuf, Meta> {
- maybe_download_ci_llvm(builder);
+ builder.config.maybe_download_ci_llvm();
// If we're using a custom LLVM bail out here, but we can only use a
// custom LLVM for the build triple.
@@ -117,7 +117,7 @@ pub fn prebuilt_llvm_config(
}
/// This retrieves the LLVM sha we *want* to use, according to git history.
-pub(crate) fn detect_llvm_sha(config: &crate::config::Config, is_git: bool) -> String {
+pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
let llvm_sha = if is_git {
let mut rev_list = config.git();
rev_list.args(&[
@@ -155,7 +155,7 @@ pub(crate) fn detect_llvm_sha(config: &crate::config::Config, is_git: bool) -> S
/// This checks both the build triple platform to confirm we're usable at all,
/// and then verifies if the current HEAD matches the detected LLVM SHA head,
/// in which case LLVM is indicated as not available.
-pub(crate) fn is_ci_llvm_available(config: &crate::config::Config, asserts: bool) -> bool {
+pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
// This is currently all tier 1 targets and tier 2 targets with host tools
// (since others may not have CI artifacts)
// https://doc.rust-lang.org/rustc/platform-support.html#tier-1
@@ -217,80 +217,6 @@ pub(crate) fn is_ci_llvm_available(config: &crate::config::Config, asserts: bool
true
}
-pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
- let config = &builder.config;
- if !config.llvm_from_ci {
- return;
- }
- let llvm_root = config.ci_llvm_root();
- let llvm_stamp = llvm_root.join(".llvm-stamp");
- let llvm_sha = detect_llvm_sha(&config, builder.rust_info.is_managed_git_subrepository());
- let key = format!("{}{}", llvm_sha, config.llvm_assertions);
- if program_out_of_date(&llvm_stamp, &key) && !config.dry_run {
- download_ci_llvm(builder, &llvm_sha);
- for entry in t!(fs::read_dir(llvm_root.join("bin"))) {
- builder.fix_bin_or_dylib(&t!(entry).path());
- }
-
- // Update the timestamp of llvm-config to force rustc_llvm to be
- // rebuilt. This is a hacky workaround for a deficiency in Cargo where
- // the rerun-if-changed directive doesn't handle changes very well.
- // https://github.com/rust-lang/cargo/issues/10791
- // Cargo only compares the timestamp of the file relative to the last
- // time `rustc_llvm` build script ran. However, the timestamps of the
- // files in the tarball are in the past, so it doesn't trigger a
- // rebuild.
- let now = filetime::FileTime::from_system_time(std::time::SystemTime::now());
- let llvm_config = llvm_root.join("bin").join(exe("llvm-config", builder.config.build));
- t!(filetime::set_file_times(&llvm_config, now, now));
-
- let llvm_lib = llvm_root.join("lib");
- for entry in t!(fs::read_dir(&llvm_lib)) {
- let lib = t!(entry).path();
- if lib.extension().map_or(false, |ext| ext == "so") {
- builder.fix_bin_or_dylib(&lib);
- }
- }
- t!(fs::write(llvm_stamp, key));
- }
-}
-
-fn download_ci_llvm(builder: &Builder<'_>, llvm_sha: &str) {
- let llvm_assertions = builder.config.llvm_assertions;
-
- let cache_prefix = format!("llvm-{}-{}", llvm_sha, llvm_assertions);
- let cache_dst = builder.out.join("cache");
- let rustc_cache = cache_dst.join(cache_prefix);
- if !rustc_cache.exists() {
- t!(fs::create_dir_all(&rustc_cache));
- }
- let base = if llvm_assertions {
- &builder.config.stage0_metadata.config.artifacts_with_llvm_assertions_server
- } else {
- &builder.config.stage0_metadata.config.artifacts_server
- };
- let channel = builder.config.artifact_channel(builder, llvm_sha);
- let filename = format!("rust-dev-{}-{}.tar.xz", channel, builder.build.build.triple);
- let tarball = rustc_cache.join(&filename);
- if !tarball.exists() {
- let help_on_error = "error: failed to download llvm from ci
-
-help: old builds get deleted after a certain time
-help: if trying to compile an old commit of rustc, disable `download-ci-llvm` in config.toml:
-
-[llvm]
-download-ci-llvm = false
-";
- builder.download_component(
- &format!("{base}/{llvm_sha}/{filename}"),
- &tarball,
- help_on_error,
- );
- }
- let llvm_root = builder.config.ci_llvm_root();
- builder.unpack(&tarball, &llvm_root, "rust-dev");
-}
-
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Llvm {
pub target: TargetSelection,
@@ -505,7 +431,7 @@ impl Step for Llvm {
// https://llvm.org/docs/HowToCrossCompileLLVM.html
if target != builder.config.build {
let llvm_config = builder.ensure(Llvm { target: builder.config.build });
- if !builder.config.dry_run {
+ if !builder.config.dry_run() {
let llvm_bindir = output(Command::new(&llvm_config).arg("--bindir"));
let host_bin = Path::new(llvm_bindir.trim());
cfg.define(
@@ -519,7 +445,7 @@ impl Step for Llvm {
if builder.config.llvm_clang {
let build_bin = builder.llvm_out(builder.config.build).join("build").join("bin");
let clang_tblgen = build_bin.join("clang-tblgen").with_extension(EXE_EXTENSION);
- if !builder.config.dry_run && !clang_tblgen.exists() {
+ if !builder.config.dry_run() && !clang_tblgen.exists() {
panic!("unable to find {}", clang_tblgen.display());
}
cfg.define("CLANG_TABLEGEN", clang_tblgen);
@@ -553,7 +479,7 @@ impl Step for Llvm {
// tools. Figure out how to filter them down and only build the right
// tools and libs on all platforms.
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return build_llvm_config;
}
@@ -611,7 +537,7 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
return;
}
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return;
}
@@ -872,7 +798,7 @@ impl Step for Lld {
/// Compile LLD for `target`.
fn run(self, builder: &Builder<'_>) -> PathBuf {
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return PathBuf::from("lld-out-dir-test-gen");
}
let target = self.target;
@@ -990,7 +916,7 @@ impl Step for TestHelpers {
/// Compiles the `rust_test_helpers.c` library which we used in various
/// `run-pass` tests for ABI testing.
fn run(self, builder: &Builder<'_>) {
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return;
}
// The x86_64-fortanix-unknown-sgx target doesn't have a working C
@@ -1066,7 +992,7 @@ impl Step for Sanitizers {
}
let llvm_config = builder.ensure(Llvm { target: builder.config.build });
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return runtimes;
}
@@ -1240,7 +1166,7 @@ impl Step for CrtBeginEnd {
fn run(self, builder: &Builder<'_>) -> Self::Output {
let out_dir = builder.native_dir(self.target).join("crt");
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return out_dir;
}
@@ -1304,7 +1230,7 @@ impl Step for Libunwind {
/// Build linunwind.a
fn run(self, builder: &Builder<'_>) -> Self::Output {
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return PathBuf::new();
}
diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs
index 511872903..05de51f8c 100644
--- a/src/bootstrap/run.rs
+++ b/src/bootstrap/run.rs
@@ -1,8 +1,13 @@
+use std::path::PathBuf;
+use std::process::Command;
+
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
+use crate::config::TargetSelection;
use crate::dist::distdir;
-use crate::tool::Tool;
+use crate::test;
+use crate::tool::{self, SourceType, Tool};
use crate::util::output;
-use std::process::Command;
+use crate::Mode;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct ExpandYamlAnchors;
@@ -125,3 +130,125 @@ impl Step for ReplaceVersionPlaceholder {
builder.run(&mut cmd);
}
}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct Miri {
+ stage: u32,
+ host: TargetSelection,
+ target: TargetSelection,
+}
+
+impl Step for Miri {
+ type Output = ();
+ const ONLY_HOSTS: bool = false;
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.path("src/tools/miri")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ run.builder.ensure(Miri {
+ stage: run.builder.top_stage,
+ host: run.build_triple(),
+ target: run.target,
+ });
+ }
+
+ fn run(self, builder: &Builder<'_>) {
+ let stage = self.stage;
+ let host = self.host;
+ let target = self.target;
+ let compiler = builder.compiler(stage, host);
+
+ let miri = builder
+ .ensure(tool::Miri { compiler, target: self.host, extra_features: Vec::new() })
+ .expect("in-tree tool");
+ let miri_sysroot = test::Miri::build_miri_sysroot(builder, compiler, &miri, target);
+
+ // # Run miri.
+ // Running it via `cargo run` as that figures out the right dylib path.
+ // add_rustc_lib_path does not add the path that contains librustc_driver-<...>.so.
+ let mut miri = tool::prepare_tool_cargo(
+ builder,
+ compiler,
+ Mode::ToolRustc,
+ host,
+ "run",
+ "src/tools/miri",
+ SourceType::InTree,
+ &[],
+ );
+ miri.add_rustc_lib_path(builder, compiler);
+ // Forward arguments.
+ miri.arg("--").arg("--target").arg(target.rustc_target_arg());
+ miri.args(builder.config.cmd.args());
+
+ // miri tests need to know about the stage sysroot
+ miri.env("MIRI_SYSROOT", &miri_sysroot);
+
+ let mut miri = Command::from(miri);
+ builder.run(&mut miri);
+ }
+}
+
+#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct CollectLicenseMetadata;
+
+impl Step for CollectLicenseMetadata {
+ type Output = PathBuf;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.path("src/tools/collect-license-metadata")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ run.builder.ensure(CollectLicenseMetadata);
+ }
+
+ fn run(self, builder: &Builder<'_>) -> Self::Output {
+ let Some(reuse) = &builder.config.reuse else {
+ panic!("REUSE is required to collect the license metadata");
+ };
+
+ // Temporary location, it will be moved to src/etc once it's accurate.
+ let dest = builder.out.join("license-metadata.json");
+
+ let mut cmd = builder.tool_cmd(Tool::CollectLicenseMetadata);
+ cmd.env("REUSE_EXE", reuse);
+ cmd.env("DEST", &dest);
+ builder.run(&mut cmd);
+
+ dest
+ }
+}
+
+#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct GenerateCopyright;
+
+impl Step for GenerateCopyright {
+ type Output = PathBuf;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.path("src/tools/generate-copyright")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ run.builder.ensure(GenerateCopyright);
+ }
+
+ fn run(self, builder: &Builder<'_>) -> Self::Output {
+ let license_metadata = builder.ensure(CollectLicenseMetadata);
+
+ // Temporary location, it will be moved to the proper one once it's accurate.
+ let dest = builder.out.join("COPYRIGHT.md");
+
+ let mut cmd = builder.tool_cmd(Tool::GenerateCopyright);
+ cmd.env("LICENSE_METADATA", &license_metadata);
+ cmd.env("DEST", &dest);
+ builder.run(&mut cmd);
+
+ dest
+ }
+}
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index e90551725..8a40b0f64 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -74,7 +74,7 @@ pub fn check(build: &mut Build) {
let mut cmd_finder = Finder::new();
// If we've got a git directory we're gonna need git to update
// submodules and learn about various other aspects.
- if build.rust_info.is_managed_git_subrepository() {
+ if build.rust_info().is_managed_git_subrepository() {
cmd_finder.must_have("git");
}
@@ -140,6 +140,13 @@ than building it.
.map(|p| cmd_finder.must_have(p))
.or_else(|| cmd_finder.maybe_have("gdb"));
+ build.config.reuse = build
+ .config
+ .reuse
+ .take()
+ .map(|p| cmd_finder.must_have(p))
+ .or_else(|| cmd_finder.maybe_have("reuse"));
+
// We're gonna build some custom C code here and there, host triples
// also build some C++ shims for LLVM so we need a C++ compiler.
for target in &build.targets {
@@ -155,7 +162,15 @@ than building it.
continue;
}
- if !build.config.dry_run {
+ // Some environments don't want or need these tools, such as when testing Miri.
+ // FIXME: it would be better to refactor this code to split necessary setup from pure sanity
+ // checks, and have a regular flag for skipping the latter. Also see
+ // <https://github.com/rust-lang/rust/pull/103569#discussion_r1008741742>.
+ if env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some() {
+ continue;
+ }
+
+ if !build.config.dry_run() {
cmd_finder.must_have(build.cc(*target));
if let Some(ar) = build.ar(*target) {
cmd_finder.must_have(ar);
@@ -164,7 +179,7 @@ than building it.
}
for host in &build.hosts {
- if !build.config.dry_run {
+ if !build.config.dry_run() {
cmd_finder.must_have(build.cxx(*host).unwrap());
}
}
@@ -212,6 +227,14 @@ than building it.
}
}
+ // Some environments don't want or need these tools, such as when testing Miri.
+ // FIXME: it would be better to refactor this code to split necessary setup from pure sanity
+ // checks, and have a regular flag for skipping the latter. Also see
+ // <https://github.com/rust-lang/rust/pull/103569#discussion_r1008741742>.
+ if env::var_os("BOOTSTRAP_SKIP_TARGET_SANITY").is_some() {
+ continue;
+ }
+
if need_cmake && target.contains("msvc") {
// There are three builds of cmake on windows: MSVC, MinGW, and
// Cygwin. The Cygwin build does not have generators for Visual
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
index eb7da1bda..c7f98a7d0 100644
--- a/src/bootstrap/setup.rs
+++ b/src/bootstrap/setup.rs
@@ -1,15 +1,13 @@
+use crate::Config;
use crate::{t, VERSION};
-use crate::{Config, TargetSelection};
use std::env::consts::EXE_SUFFIX;
use std::fmt::Write as _;
use std::fs::File;
+use std::io::Write;
use std::path::{Path, PathBuf, MAIN_SEPARATOR};
use std::process::Command;
use std::str::FromStr;
-use std::{
- env, fmt, fs,
- io::{self, Write},
-};
+use std::{fmt, fs, io};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Profile {
@@ -81,38 +79,10 @@ impl fmt::Display for Profile {
}
}
-pub fn setup(config: &Config, profile: Profile) {
- let path = &config.config;
-
- if path.exists() {
- eprintln!(
- "error: you asked `x.py` to setup a new config file, but one already exists at `{}`",
- path.display()
- );
- eprintln!("help: try adding `profile = \"{}\"` at the top of {}", profile, path.display());
- eprintln!(
- "note: this will use the configuration in {}",
- profile.include_path(&config.src).display()
- );
- crate::detail_exit(1);
- }
-
- let settings = format!(
- "# Includes one of the default files in src/bootstrap/defaults\n\
- profile = \"{}\"\n\
- changelog-seen = {}\n",
- profile, VERSION
- );
- t!(fs::write(path, settings));
-
- let include_path = profile.include_path(&config.src);
- println!("`x.py` will now use the configuration at {}", include_path.display());
-
- let build = TargetSelection::from_user(&env!("BUILD_TRIPLE"));
+pub fn setup(config: &Config, profile: Option<Profile>) {
+ let profile = profile.unwrap_or_else(|| t!(interactive_path()));
let stage_path =
- ["build", build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
-
- println!();
+ ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
if !rustup_installed() && profile != Profile::User {
eprintln!("`rustup` is not installed; cannot link `stage1` toolchain");
@@ -134,8 +104,6 @@ pub fn setup(config: &Config, profile: Profile) {
Profile::User => &["dist", "build"],
};
- println!();
-
t!(install_git_hook_maybe(&config));
println!();
@@ -150,6 +118,36 @@ pub fn setup(config: &Config, profile: Profile) {
"For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html"
);
}
+
+ let path = &config.config.clone().unwrap_or(PathBuf::from("config.toml"));
+ setup_config_toml(path, profile, config);
+}
+
+fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
+ if path.exists() {
+ eprintln!();
+ eprintln!(
+ "error: you asked `x.py` to setup a new config file, but one already exists at `{}`",
+ path.display()
+ );
+ eprintln!("help: try adding `profile = \"{}\"` at the top of {}", profile, path.display());
+ eprintln!(
+ "note: this will use the configuration in {}",
+ profile.include_path(&config.src).display()
+ );
+ crate::detail_exit(1);
+ }
+
+ let settings = format!(
+ "# Includes one of the default files in src/bootstrap/defaults\n\
+ profile = \"{}\"\n\
+ changelog-seen = {}\n",
+ profile, VERSION
+ );
+ t!(fs::write(path, settings));
+
+ let include_path = profile.include_path(&config.src);
+ println!("`x.py` will now use the configuration at {}", include_path.display());
}
fn rustup_installed() -> bool {
@@ -303,7 +301,18 @@ pub fn interactive_path() -> io::Result<Profile> {
// install a git hook to automatically run tidy --bless, if they want
fn install_git_hook_maybe(config: &Config) -> io::Result<()> {
+ let git = t!(config.git().args(&["rev-parse", "--git-common-dir"]).output().map(|output| {
+ assert!(output.status.success(), "failed to run `git`");
+ PathBuf::from(t!(String::from_utf8(output.stdout)).trim())
+ }));
+ let dst = git.join("hooks").join("pre-push");
+ if dst.exists() {
+ // The git hook has already been set up, or the user already has a custom hook.
+ return Ok(());
+ }
+
let mut input = String::new();
+ println!();
println!(
"Rust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality.
If you'd like, x.py can install a git hook for you that will automatically run `tidy --bless` before
@@ -329,12 +338,6 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
if should_install {
let src = config.src.join("src").join("etc").join("pre-push.sh");
- let git =
- t!(config.git().args(&["rev-parse", "--git-common-dir"]).output().map(|output| {
- assert!(output.status.success(), "failed to run `git`");
- PathBuf::from(t!(String::from_utf8(output.stdout)).trim())
- }));
- let dst = git.join("hooks").join("pre-push");
match fs::hard_link(src, &dst) {
Err(e) => eprintln!(
"error: could not create hook {}: do you already have the git hook installed?\n{}",
diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs
index d999b6c15..fc850a22b 100644
--- a/src/bootstrap/tarball.rs
+++ b/src/bootstrap/tarball.rs
@@ -298,7 +298,7 @@ impl<'a> Tarball<'a> {
fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut Command)) -> GeneratedTarball {
t!(std::fs::create_dir_all(&self.overlay_dir));
self.builder.create(&self.overlay_dir.join("version"), &self.overlay.version(self.builder));
- if let Some(info) = self.builder.rust_info.info() {
+ if let Some(info) = self.builder.rust_info().info() {
channel::write_commit_hash_file(&self.overlay_dir, &info.sha);
channel::write_commit_info_file(&self.overlay_dir, info);
}
@@ -323,7 +323,7 @@ impl<'a> Tarball<'a> {
// Ensure there are no symbolic links in the tarball. In particular,
// rustup-toolchain-install-master and most versions of Windows can't handle symbolic links.
let decompressed_output = self.temp_dir.join(&package_name);
- if !self.builder.config.dry_run && !self.permit_symlinks {
+ if !self.builder.config.dry_run() && !self.permit_symlinks {
for entry in walkdir::WalkDir::new(&decompressed_output) {
let entry = t!(entry);
if entry.path_is_symlink() {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 791c35c36..39cedfdac 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -16,6 +16,7 @@ use crate::cache::Interned;
use crate::compile;
use crate::config::TargetSelection;
use crate::dist;
+use crate::doc::DocumentationFormat;
use crate::flags::Subcommand;
use crate::native;
use crate::tool::{self, SourceType, Tool};
@@ -90,6 +91,42 @@ fn try_run_quiet(builder: &Builder<'_>, cmd: &mut Command) -> bool {
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CrateJsonDocLint {
+ host: TargetSelection,
+}
+
+impl Step for CrateJsonDocLint {
+ type Output = ();
+ const ONLY_HOSTS: bool = true;
+ const DEFAULT: bool = true;
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.path("src/tools/jsondoclint")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ run.builder.ensure(CrateJsonDocLint { host: run.target });
+ }
+
+ fn run(self, builder: &Builder<'_>) {
+ let bootstrap_host = builder.config.build;
+ let compiler = builder.compiler(0, bootstrap_host);
+
+ let cargo = tool::prepare_tool_cargo(
+ builder,
+ compiler,
+ Mode::ToolBootstrap,
+ bootstrap_host,
+ "test",
+ "src/tools/jsondoclint",
+ SourceType::InTree,
+ &[],
+ );
+ try_run(builder, &mut cargo.into());
+ }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Linkcheck {
host: TargetSelection,
}
@@ -464,52 +501,23 @@ pub struct Miri {
target: TargetSelection,
}
-impl Step for Miri {
- type Output = ();
- const ONLY_HOSTS: bool = false;
-
- fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("src/tools/miri")
- }
-
- fn make_run(run: RunConfig<'_>) {
- run.builder.ensure(Miri {
- stage: run.builder.top_stage,
- host: run.build_triple(),
- target: run.target,
- });
- }
-
- /// Runs `cargo test` for miri.
- fn run(self, builder: &Builder<'_>) {
- let stage = self.stage;
- let host = self.host;
- let target = self.target;
- let compiler = builder.compiler(stage, host);
- // We need the stdlib for the *next* stage, as it was built with this compiler that also built Miri.
- // Except if we are at stage 2, the bootstrap loop is complete and we can stick with our current stage.
- let compiler_std = builder.compiler(if stage < 2 { stage + 1 } else { stage }, host);
-
- let miri = builder
- .ensure(tool::Miri { compiler, target: self.host, extra_features: Vec::new() })
- .expect("in-tree tool");
- let _cargo_miri = builder
- .ensure(tool::CargoMiri { compiler, target: self.host, extra_features: Vec::new() })
- .expect("in-tree tool");
- // The stdlib we need might be at a different stage. And just asking for the
- // sysroot does not seem to populate it, so we do that first.
- builder.ensure(compile::Std::new(compiler_std, host));
- let sysroot = builder.sysroot(compiler_std);
-
- // # Run `cargo miri setup` for the given target.
+impl Miri {
+ /// Run `cargo miri setup` for the given target, return where the Miri sysroot was put.
+ pub fn build_miri_sysroot(
+ builder: &Builder<'_>,
+ compiler: Compiler,
+ miri: &Path,
+ target: TargetSelection,
+ ) -> String {
+ let miri_sysroot = builder.out.join(compiler.host.triple).join("miri-sysroot");
let mut cargo = tool::prepare_tool_cargo(
builder,
compiler,
Mode::ToolRustc,
- host,
+ compiler.host,
"run",
"src/tools/miri/cargo-miri",
- SourceType::Submodule,
+ SourceType::InTree,
&[],
);
cargo.add_rustc_lib_path(builder, compiler);
@@ -520,6 +528,8 @@ impl Step for Miri {
cargo.env("MIRI_LIB_SRC", builder.src.join("library"));
// Tell it where to find Miri.
cargo.env("MIRI", &miri);
+ // Tell it where to put the sysroot.
+ cargo.env("MIRI_SYSROOT", &miri_sysroot);
// Debug things.
cargo.env("RUST_BACKTRACE", "1");
@@ -534,7 +544,7 @@ impl Step for Miri {
cargo.arg("--print-sysroot");
// FIXME: Is there a way in which we can re-use the usual `run` helpers?
- let miri_sysroot = if builder.config.dry_run {
+ if builder.config.dry_run() {
String::new()
} else {
builder.verbose(&format!("running: {:?}", cargo));
@@ -547,7 +557,48 @@ impl Step for Miri {
let sysroot = stdout.trim_end();
builder.verbose(&format!("`cargo miri setup --print-sysroot` said: {:?}", sysroot));
sysroot.to_owned()
- };
+ }
+ }
+}
+
+impl Step for Miri {
+ type Output = ();
+ const ONLY_HOSTS: bool = false;
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.path("src/tools/miri")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ run.builder.ensure(Miri {
+ stage: run.builder.top_stage,
+ host: run.build_triple(),
+ target: run.target,
+ });
+ }
+
+ /// Runs `cargo test` for miri.
+ fn run(self, builder: &Builder<'_>) {
+ let stage = self.stage;
+ let host = self.host;
+ let target = self.target;
+ let compiler = builder.compiler(stage, host);
+ // We need the stdlib for the *next* stage, as it was built with this compiler that also built Miri.
+ // Except if we are at stage 2, the bootstrap loop is complete and we can stick with our current stage.
+ let compiler_std = builder.compiler(if stage < 2 { stage + 1 } else { stage }, host);
+
+ let miri = builder
+ .ensure(tool::Miri { compiler, target: self.host, extra_features: Vec::new() })
+ .expect("in-tree tool");
+ let _cargo_miri = builder
+ .ensure(tool::CargoMiri { compiler, target: self.host, extra_features: Vec::new() })
+ .expect("in-tree tool");
+ // The stdlib we need might be at a different stage. And just asking for the
+ // sysroot does not seem to populate it, so we do that first.
+ builder.ensure(compile::Std::new(compiler_std, host));
+ let sysroot = builder.sysroot(compiler_std);
+ // We also need a Miri sysroot.
+ let miri_sysroot = Miri::build_miri_sysroot(builder, compiler, &miri, target);
// # Run `cargo test`.
let mut cargo = tool::prepare_tool_cargo(
@@ -557,7 +608,7 @@ impl Step for Miri {
host,
"test",
"src/tools/miri",
- SourceType::Submodule,
+ SourceType::InTree,
&[],
);
cargo.add_rustc_lib_path(builder, compiler);
@@ -565,7 +616,6 @@ impl Step for Miri {
// miri tests need to know about the stage sysroot
cargo.env("MIRI_SYSROOT", &miri_sysroot);
cargo.env("MIRI_HOST_SYSROOT", sysroot);
- cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
cargo.env("MIRI", &miri);
// propagate --bless
if builder.config.cmd.bless() {
@@ -606,7 +656,6 @@ impl Step for Miri {
// Tell `cargo miri` where to find things.
cargo.env("MIRI_SYSROOT", &miri_sysroot);
cargo.env("MIRI_HOST_SYSROOT", sysroot);
- cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
cargo.env("MIRI", &miri);
// Debug things.
cargo.env("RUST_BACKTRACE", "1");
@@ -771,7 +820,10 @@ impl Step for RustdocTheme {
cmd.env("RUSTDOC_LINKER", linker);
}
if builder.is_fuse_ld_lld(self.compiler.host) {
- cmd.env("RUSTDOC_FUSE_LD_LLD", "1");
+ cmd.env(
+ "RUSTDOC_LLD_NO_THREADS",
+ util::lld_flag_no_threads(self.compiler.host.contains("windows")),
+ );
}
try_run(builder, &mut cmd);
}
@@ -819,7 +871,11 @@ impl Step for RustdocJSStd {
command.arg("--test-file").arg(path);
}
}
- builder.ensure(crate::doc::Std { target: self.target, stage: builder.top_stage });
+ builder.ensure(crate::doc::Std {
+ target: self.target,
+ stage: builder.top_stage,
+ format: DocumentationFormat::HTML,
+ });
builder.run(&mut command);
} else {
builder.info("No nodejs found, skipping \"src/test/rustdoc-js-std\" tests");
@@ -991,6 +1047,8 @@ impl Step for RustdocGUI {
// instead of hard-coding this test
if entry.file_name() == "link_to_definition" {
cargo.env("RUSTDOCFLAGS", "-Zunstable-options --generate-link-to-definition");
+ } else if entry.file_name() == "scrape_examples" {
+ cargo.arg("-Zrustdoc-scrape-examples=examples");
}
builder.run(&mut cargo);
}
@@ -1049,6 +1107,9 @@ impl Step for Tidy {
if builder.is_verbose() {
cmd.arg("--verbose");
}
+ if builder.config.cmd.bless() {
+ cmd.arg("--bless");
+ }
builder.info("tidy check");
try_run(builder, &mut cmd);
@@ -1378,6 +1439,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
cmd.arg("--src-base").arg(builder.src.join("src/test").join(suite));
cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite));
+ cmd.arg("--sysroot-base").arg(builder.sysroot(compiler));
cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
cmd.arg("--suite").arg(suite);
cmd.arg("--mode").arg(mode);
@@ -1514,7 +1576,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
let mut copts_passed = false;
if builder.config.llvm_enabled() {
let llvm_config = builder.ensure(native::Llvm { target: builder.config.build });
- if !builder.config.dry_run {
+ if !builder.config.dry_run() {
let llvm_version = output(Command::new(&llvm_config).arg("--version"));
let llvm_components = output(Command::new(&llvm_config).arg("--components"));
// Remove trailing newline from llvm-config output.
@@ -1532,14 +1594,14 @@ note: if you're sure you want to do this, please open an issue as to why. In the
// requirement, but the `-L` library path is not propagated across
// separate compilations. We can add LLVM's library path to the
// platform-specific environment variable as a workaround.
- if !builder.config.dry_run && suite.ends_with("fulldeps") {
+ if !builder.config.dry_run() && suite.ends_with("fulldeps") {
let llvm_libdir = output(Command::new(&llvm_config).arg("--libdir"));
add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd);
}
// Only pass correct values for these flags for the `run-make` suite as it
// requires that a C++ compiler was configured which isn't always the case.
- if !builder.config.dry_run && matches!(suite, "run-make" | "run-make-fulldeps") {
+ if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") {
// The llvm/bin directory contains many useful cross-platform
// tools. Pass the path to run-make tests so they can use them.
let llvm_bin_path = llvm_config
@@ -1567,7 +1629,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
// Only pass correct values for these flags for the `run-make` suite as it
// requires that a C++ compiler was configured which isn't always the case.
- if !builder.config.dry_run && matches!(suite, "run-make" | "run-make-fulldeps") {
+ if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") {
cmd.arg("--cc")
.arg(builder.cc(target))
.arg("--cxx")
@@ -1647,6 +1709,10 @@ note: if you're sure you want to do this, please open an issue as to why. In the
cmd.arg("--channel").arg(&builder.config.channel);
+ if let Some(commit) = builder.config.download_rustc_commit() {
+ cmd.env("FAKE_DOWNLOAD_RUSTC_PREFIX", format!("/rustc/{commit}"));
+ }
+
builder.ci_env.force_coloring_in_ci(&mut cmd);
builder.info(&format!(
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index eec74b267..e0be4c432 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -380,6 +380,8 @@ bootstrap_tool!(
HtmlChecker, "src/tools/html-checker", "html-checker";
BumpStage0, "src/tools/bump-stage0", "bump-stage0";
ReplaceVersionPlaceholder, "src/tools/replace-version-placeholder", "replace-version-placeholder";
+ CollectLicenseMetadata, "src/tools/collect-license-metadata", "collect-license-metadata";
+ GenerateCopyright, "src/tools/generate-copyright", "generate-copyright";
);
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
@@ -522,7 +524,7 @@ impl Step for Rustdoc {
builder.ensure(compile::Rustc::new(build_compiler, target_compiler.host));
// NOTE: this implies that `download-rustc` is pretty useless when compiling with the stage0
// compiler, since you do just as much work.
- if !builder.config.dry_run && builder.download_rustc() && build_compiler.stage == 0 {
+ if !builder.config.dry_run() && builder.download_rustc() && build_compiler.stage == 0 {
println!(
"warning: `download-rustc` does nothing when building stage1 tools; consider using `--stage 2` instead"
);
@@ -794,10 +796,9 @@ macro_rules! tool_extended {
$($name:ident,
$path:expr,
$tool_name:expr,
- stable = $stable:expr,
- $(in_tree = $in_tree:expr,)?
- $(tool_std = $tool_std:literal,)?
- $extra_deps:block;)+) => {
+ stable = $stable:expr
+ $(,tool_std = $tool_std:literal)?
+ ;)+) => {
$(
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct $name {
@@ -839,7 +840,6 @@ macro_rules! tool_extended {
#[allow(unused_mut)]
fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
- $extra_deps
$builder.ensure(ToolBuild {
compiler: $sel.compiler,
target: $sel.target,
@@ -848,11 +848,7 @@ macro_rules! tool_extended {
path: $path,
extra_features: $sel.extra_features,
is_optional_tool: true,
- source_type: if false $(|| $in_tree)* {
- SourceType::InTree
- } else {
- SourceType::Submodule
- },
+ source_type: SourceType::InTree,
})
}
}
@@ -865,17 +861,17 @@ macro_rules! tool_extended {
// Note: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to
// invoke Cargo to build bootstrap. See the comment there for more details.
tool_extended!((self, builder),
- Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {};
- CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {};
- Clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {};
- Miri, "src/tools/miri", "miri", stable=false, in_tree=true, {};
- CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, in_tree=true, {};
+ Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true;
+ CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true;
+ Clippy, "src/tools/clippy", "clippy-driver", stable=true;
+ Miri, "src/tools/miri", "miri", stable=false;
+ CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true;
// FIXME: tool_std is not quite right, we shouldn't allow nightly features.
// But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0,
// and this is close enough for now.
- Rls, "src/tools/rls", "rls", stable=true, in_tree=true, tool_std=true, {};
- RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {};
- Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {};
+ Rls, "src/tools/rls", "rls", stable=true, tool_std=true;
+ RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true;
+ Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true;
);
impl<'a> Builder<'a> {
diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs
index 1a1774432..1969e0b6f 100644
--- a/src/bootstrap/toolstate.rs
+++ b/src/bootstrap/toolstate.rs
@@ -158,7 +158,7 @@ impl Step for ToolStateCheck {
/// stable tool. That is, the status is not allowed to get worse
/// (test-pass to test-fail or build-fail).
fn run(self, builder: &Builder<'_>) {
- if builder.config.dry_run {
+ if builder.config.dry_run() {
return;
}
@@ -265,7 +265,7 @@ impl Builder<'_> {
// If we're in a dry run setting we don't want to save toolstates as
// that means if we e.g. panic down the line it'll look like we tested
// everything (but we actually haven't).
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
// Toolstate isn't tracked for clippy or rustfmt, but since most tools do, we avoid checking
diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs
index 0ebabbd5c..582207832 100644
--- a/src/bootstrap/util.rs
+++ b/src/bootstrap/util.rs
@@ -13,6 +13,7 @@ use std::time::{Instant, SystemTime, UNIX_EPOCH};
use crate::builder::Builder;
use crate::config::{Config, TargetSelection};
+use crate::OnceCell;
/// A helper macro to `unwrap` a result except also print out details like:
///
@@ -43,7 +44,13 @@ pub use t;
/// Given an executable called `name`, return the filename for the
/// executable for a particular target.
pub fn exe(name: &str, target: TargetSelection) -> String {
- if target.contains("windows") { format!("{}.exe", name) } else { name.to_string() }
+ if target.contains("windows") {
+ format!("{}.exe", name)
+ } else if target.contains("uefi") {
+ format!("{}.efi", name)
+ } else {
+ name.to_string()
+ }
}
/// Returns `true` if the file name given looks like a dynamic library.
@@ -104,7 +111,7 @@ pub struct TimeIt(bool, Instant);
/// Returns an RAII structure that prints out how long it took to drop.
pub fn timeit(builder: &Builder<'_>) -> TimeIt {
- TimeIt(builder.config.dry_run, Instant::now())
+ TimeIt(builder.config.dry_run(), Instant::now())
}
impl Drop for TimeIt {
@@ -127,7 +134,7 @@ pub(crate) fn program_out_of_date(stamp: &Path, key: &str) -> bool {
/// Symlinks two directories, using junctions on Windows and normal symlinks on
/// Unix.
pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
- if config.dry_run {
+ if config.dry_run() {
return Ok(());
}
let _ = fs::remove_dir(dest);
@@ -607,3 +614,16 @@ pub fn get_clang_cl_resource_dir(clang_cl_path: &str) -> PathBuf {
let clang_rt_dir = clang_rt_builtins.parent().expect("The clang lib folder should exist");
clang_rt_dir.to_path_buf()
}
+
+pub fn lld_flag_no_threads(is_windows: bool) -> &'static str {
+ static LLD_NO_THREADS: OnceCell<(&'static str, &'static str)> = OnceCell::new();
+ let (windows, other) = LLD_NO_THREADS.get_or_init(|| {
+ let out = output(Command::new("lld").arg("-flavor").arg("ld").arg("--version"));
+ let newer = match (out.find(char::is_numeric), out.find('.')) {
+ (Some(b), Some(e)) => out.as_str()[b..e].parse::<i32>().ok().unwrap_or(14) > 10,
+ _ => true,
+ };
+ if newer { ("/threads:1", "--threads=1") } else { ("/no-threads", "--no-threads") }
+ });
+ if is_windows { windows } else { other }
+}
diff --git a/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile b/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile
index e54d0eafb..699938c37 100644
--- a/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile
+++ b/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile
@@ -14,7 +14,8 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
gdb \
libssl-dev \
pkg-config \
- xz-utils
+ xz-utils \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
index 69f88e495..57e63cd39 100644
--- a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
@@ -9,7 +9,7 @@ RUN apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-
curl \
file \
g++ \
- gcc-arm-linux-gnueabihf \
+ g++-arm-linux-gnueabihf \
git \
libc6-dev \
libc6-dev-armhf-cross \
diff --git a/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile
index 637b5fa22..5ddd3f180 100644
--- a/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile
+++ b/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile
@@ -47,6 +47,4 @@ ENV RUST_CONFIGURE_ARGS --disable-jemalloc \
--set=$TARGET.cc=x86_64-unknown-haiku-gcc \
--set=$TARGET.cxx=x86_64-unknown-haiku-g++ \
--set=$TARGET.llvm-config=/bin/llvm-config-haiku
-ENV EXTERNAL_LLVM 1
-
ENV SCRIPT python3 ../x.py dist --host=$HOST --target=$HOST
diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
index cd86d9fb5..ea4a2a242 100644
--- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile
@@ -32,7 +32,8 @@ RUN yum upgrade -y && \
wget \
xz \
zlib-devel.i686 \
- zlib-devel.x86_64
+ zlib-devel.x86_64 \
+ && yum clean all
RUN mkdir -p /rustroot/bin && ln -s /usr/bin/cmake3 /rustroot/bin/cmake
diff --git a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile
index 9a290edd5..6b7b32a8b 100644
--- a/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux/Dockerfile
@@ -24,5 +24,5 @@ ENV \
ENV HOSTS=powerpc64le-unknown-linux-gnu
-ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile
index 88b8c7ea3..397f9538b 100644
--- a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile
@@ -27,5 +27,5 @@ ENV CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \
ENV HOSTS=riscv64gc-unknown-linux-gnu
-ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
+ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs
ENV SCRIPT python3 ../x.py dist --target $HOSTS --host $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile
index 7d77fdd30..43a449b3a 100644
--- a/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile
@@ -28,5 +28,5 @@ ENV \
ENV HOSTS=s390x-unknown-linux-gnu
-ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --disable-docs
+ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --enable-profiler --disable-docs
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index 8250ec0c3..93ef7dfcb 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -61,6 +61,12 @@ ENV \
AR_i686_unknown_freebsd=i686-unknown-freebsd12-ar \
CC_i686_unknown_freebsd=i686-unknown-freebsd12-clang \
CXX_i686_unknown_freebsd=i686-unknown-freebsd12-clang++ \
+ CC_aarch64_unknown_uefi=clang-11 \
+ CXX_aarch64_unknown_uefi=clang++-11 \
+ CC_i686_unknown_uefi=clang-11 \
+ CXX_i686_unknown_uefi=clang++-11 \
+ CC_x86_64_unknown_uefi=clang-11 \
+ CXX_x86_64_unknown_uefi=clang++-11 \
CC=gcc-8 \
CXX=g++-8
@@ -118,6 +124,9 @@ ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi
ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi
ENV TARGETS=$TARGETS,i686-unknown-freebsd
ENV TARGETS=$TARGETS,x86_64-unknown-none
+ENV TARGETS=$TARGETS,aarch64-unknown-uefi
+ENV TARGETS=$TARGETS,i686-unknown-uefi
+ENV TARGETS=$TARGETS,x86_64-unknown-uefi
# As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211
# we need asm in the search path for gcc-8 (for gnux32) but not in the search path of the
@@ -129,6 +138,4 @@ ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --disable-docs \
--set target.wasm32-wasi.wasi-root=/wasm32-wasi \
--musl-root-armv7=/musl-armv7
-ENV EXTERNAL_LLVM 1
-
ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS
diff --git a/src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh
index 36c94458d..67cee0148 100755
--- a/src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh
+++ b/src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh
@@ -2,15 +2,15 @@
set -ex
-# Originally from https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.0/clang+llvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz
-curl https://ci-mirrors.rust-lang.org/rustc/2022-05-10-clang%2Bllvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz | \
+# Originally from https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6/clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz
+curl https://ci-mirrors.rust-lang.org/rustc/2022-12-06-clang%2Bllvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz | \
tar xJf -
-bin="$PWD/clang+llvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04/bin"
+bin="$PWD/clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04/bin"
git clone https://github.com/WebAssembly/wasi-libc
cd wasi-libc
-git reset --hard 9886d3d6200fcc3726329966860fc058707406cd
+git reset --hard 8b7148f69ae241a2749b3defe4606da8143b72e0
make -j$(nproc) \
CC="$bin/clang" \
NM="$bin/llvm-nm" \
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
index f9b1fa895..377d4a9ce 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile
@@ -15,7 +15,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
xz-utils \
wget \
libssl-dev \
- pkg-config
+ pkg-config \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/freebsd-toolchain.sh /tmp/
RUN /tmp/freebsd-toolchain.sh x86_64
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile
index c2e44ead5..4e46bdee5 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile
@@ -11,7 +11,8 @@ RUN apt-get update && \
apt-get install -y --no-install-recommends \
libgmp-dev \
libmpfr-dev \
- libmpc-dev
+ libmpc-dev \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/illumos-toolchain.sh /tmp/
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index 423aba06c..6bdc88e18 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -32,7 +32,8 @@ RUN yum upgrade -y && \
wget \
xz \
zlib-devel.i686 \
- zlib-devel.x86_64
+ zlib-devel.x86_64 \
+ && yum clean all
RUN mkdir -p /rustroot/bin && ln -s /usr/bin/cmake3 /rustroot/bin/cmake
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
index 51645a818..13eaf7fce 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
@@ -16,7 +16,8 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
gdb \
patch \
libssl-dev \
- pkg-config
+ pkg-config \
+ && rm -rf /var/lib/apt/lists/*
WORKDIR /build/
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile
index fed4be4c3..d03c36454 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/Dockerfile
@@ -1,7 +1,8 @@
-FROM ubuntu:16.04
+FROM ubuntu:20.04
COPY scripts/cross-apt-packages.sh /scripts/
RUN sh /scripts/cross-apt-packages.sh
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y zlib1g-dev
COPY host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh /tmp/
RUN /tmp/build-netbsd-toolchain.sh
@@ -9,9 +10,6 @@ RUN /tmp/build-netbsd-toolchain.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
-COPY scripts/cmake.sh /scripts/
-RUN /scripts/cmake.sh
-
ENV PATH=$PATH:/x-tools/x86_64-unknown-netbsd/bin
ENV \
@@ -21,6 +19,5 @@ ENV \
ENV HOSTS=x86_64-unknown-netbsd
-ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs \
- --set llvm.allow-old-toolchain
+ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs
ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh
index 5dfa47b4e..e0c008b76 100755
--- a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh
@@ -25,19 +25,19 @@ cd netbsd
mkdir -p /x-tools/x86_64-unknown-netbsd/sysroot
-URL=https://ci-mirrors.rust-lang.org/rustc
-
-# Originally from ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-$BSD/source/sets/*.tgz
-curl $URL/2018-03-01-netbsd-src.tgz | tar xzf -
-curl $URL/2018-03-01-netbsd-gnusrc.tgz | tar xzf -
-curl $URL/2018-03-01-netbsd-sharesrc.tgz | tar xzf -
-curl $URL/2018-03-01-netbsd-syssrc.tgz | tar xzf -
-
-# Originally from ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-$BSD/amd64/binary/sets/*.tgz
-curl $URL/2018-03-01-netbsd-base.tgz | \
- tar xzf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib ./lib
-curl $URL/2018-03-01-netbsd-comp.tgz | \
- tar xzf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib
+# URL=https://ci-mirrors.rust-lang.org/rustc
+
+SOURCE_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/source/sets
+curl $SOURCE_URL/src.tgz | tar xzf -
+curl $SOURCE_URL/gnusrc.tgz | tar xzf -
+curl $SOURCE_URL/sharesrc.tgz | tar xzf -
+curl $SOURCE_URL/syssrc.tgz | tar xzf -
+
+BINARY_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/amd64/binary/sets
+curl $BINARY_URL/base.tar.xz | \
+ tar xJf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib ./lib
+curl $BINARY_URL/comp.tar.xz | \
+ tar xJf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib
cd usr/src
diff --git a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
index dd74726f8..e2b66c2cf 100644
--- a/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
+++ b/src/ci/docker/host-x86_64/i686-gnu-nopt/Dockerfile
@@ -15,7 +15,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
gdb \
zlib1g-dev \
lib32z1-dev \
- xz-utils
+ xz-utils \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
diff --git a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
index 0c36cfd66..cb6559707 100644
--- a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
@@ -15,7 +15,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
gdb \
zlib1g-dev \
lib32z1-dev \
- xz-utils
+ xz-utils \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index 52a777615..40caa7c50 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -20,20 +20,20 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
xz-utils \
libssl-dev \
pkg-config \
- mingw-w64
+ mingw-w64 \
+ && rm -rf /var/lib/apt/lists/*
RUN curl -sL https://nodejs.org/dist/v16.9.0/node-v16.9.0-linux-x64.tar.xz | tar -xJ
ENV PATH="/node-v16.9.0-linux-x64/bin:${PATH}"
# Install es-check
# Pin its version to prevent unrelated CI failures due to future es-check versions.
-RUN npm install es-check@6.1.1 -g
-RUN npm install eslint@8.6.0 -g
+RUN npm install es-check@6.1.1 eslint@8.6.0 -g
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
-RUN pip3 install --no-deps --require-hashes -r /tmp/reuse-requirements.txt
+RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt
COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile
index b75e2f085..cf4451f8b 100644
--- a/src/ci/docker/host-x86_64/test-various/Dockerfile
+++ b/src/ci/docker/host-x86_64/test-various/Dockerfile
@@ -1,6 +1,7 @@
FROM ubuntu:20.04
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+ clang-11 \
g++ \
make \
ninja-build \
@@ -16,11 +17,21 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
pkg-config \
xz-utils \
wget \
- patch
+ patch \
+ ovmf \
+ qemu-efi-aarch64 \
+ qemu-system-arm \
+ qemu-system-x86 \
+ && rm -rf /var/lib/apt/lists/*
RUN curl -sL https://nodejs.org/dist/v15.14.0/node-v15.14.0-linux-x64.tar.xz | \
tar -xJ
+# Install 32-bit OVMF files for the i686-unknown-uefi test. This package
+# is not available in ubuntu 20.04, so download a 22.04 package.
+RUN curl -sL --output ovmf-ia32.deb http://mirrors.kernel.org/ubuntu/pool/universe/e/edk2/ovmf-ia32_2022.02-3_all.deb
+RUN dpkg -i ovmf-ia32.deb && rm ovmf-ia32.deb
+
WORKDIR /build/
COPY scripts/musl-patch-configure.diff /build/
COPY scripts/musl-toolchain.sh /build/
@@ -64,4 +75,15 @@ ENV MUSL_TARGETS=x86_64-unknown-linux-musl \
CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++
ENV MUSL_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $MUSL_TARGETS
-ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT
+COPY host-x86_64/test-various/uefi_qemu_test /uefi_qemu_test
+ENV UEFI_TARGETS=aarch64-unknown-uefi,i686-unknown-uefi,x86_64-unknown-uefi \
+ CC_aarch64_unknown_uefi=clang-11 \
+ CXX_aarch64_unknown_uefi=clang++-11 \
+ CC_i686_unknown_uefi=clang-11 \
+ CXX_i686_unknown_uefi=clang++-11 \
+ CC_x86_64_unknown_uefi=clang-11 \
+ CXX_x86_64_unknown_uefi=clang++-11
+ENV UEFI_SCRIPT python3 /checkout/x.py --stage 2 build --host='' --target $UEFI_TARGETS && \
+ python3 -u /uefi_qemu_test/run.py
+
+ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT && $UEFI_SCRIPT
diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml
new file mode 100644
index 000000000..fa8e5b3d0
--- /dev/null
+++ b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "uefi_qemu_test"
+version = "0.0.0"
+edition = "2021"
+
+[workspace]
+
+[dependencies]
+r-efi = "4.1.0"
diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py
new file mode 100644
index 000000000..ffae7b0d4
--- /dev/null
+++ b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+
+from pathlib import Path
+
+TARGET_AARCH64 = 'aarch64-unknown-uefi'
+TARGET_I686 = 'i686-unknown-uefi'
+TARGET_X86_64 = 'x86_64-unknown-uefi'
+
+def run(*cmd, capture=False, check=True, env=None, timeout=None):
+ """Print and run a command, optionally capturing the output."""
+ cmd = [str(p) for p in cmd]
+ print(' '.join(cmd))
+ return subprocess.run(cmd,
+ capture_output=capture,
+ check=check,
+ env=env,
+ text=True,
+ timeout=timeout)
+
+def build_and_run(tmp_dir, target):
+ if target == TARGET_AARCH64:
+ boot_file_name = 'bootaa64.efi'
+ ovmf_dir = Path('/usr/share/AAVMF')
+ ovmf_code = 'AAVMF_CODE.fd'
+ ovmf_vars = 'AAVMF_VARS.fd'
+ qemu = 'qemu-system-aarch64'
+ machine = 'virt'
+ cpu = 'cortex-a72'
+ elif target == TARGET_I686:
+ boot_file_name = 'bootia32.efi'
+ ovmf_dir = Path('/usr/share/OVMF')
+ ovmf_code = 'OVMF32_CODE_4M.secboot.fd'
+ ovmf_vars = 'OVMF32_VARS_4M.fd'
+ # The i686 target intentionally uses 64-bit qemu; the important
+ # difference is that the OVMF code provides a 32-bit environment.
+ qemu = 'qemu-system-x86_64'
+ machine = 'q35'
+ cpu = 'qemu64'
+ elif target == TARGET_X86_64:
+ boot_file_name = 'bootx64.efi'
+ ovmf_dir = Path('/usr/share/OVMF')
+ ovmf_code = 'OVMF_CODE.fd'
+ ovmf_vars = 'OVMF_VARS.fd'
+ qemu = 'qemu-system-x86_64'
+ machine = 'q35'
+ cpu = 'qemu64'
+ else:
+ raise KeyError('invalid target')
+
+ host_artifacts = Path('/checkout/obj/build/x86_64-unknown-linux-gnu')
+ stage0 = host_artifacts / 'stage0/bin'
+ stage2 = host_artifacts / 'stage2/bin'
+
+ env = dict(os.environ)
+ env['PATH'] = '{}:{}:{}'.format(stage2, stage0, env['PATH'])
+
+ # Copy the test create into `tmp_dir`.
+ test_crate = Path(tmp_dir) / 'uefi_qemu_test'
+ shutil.copytree('/uefi_qemu_test', test_crate)
+
+ # Build the UEFI executable.
+ run('cargo',
+ 'build',
+ '--manifest-path',
+ test_crate / 'Cargo.toml',
+ '--target',
+ target,
+ env=env)
+
+ # Create a mock EFI System Partition in a subdirectory.
+ esp = test_crate / 'esp'
+ boot = esp / 'efi/boot'
+ os.makedirs(boot, exist_ok=True)
+
+ # Copy the executable into the ESP.
+ src_exe_path = test_crate / 'target' / target / 'debug/uefi_qemu_test.efi'
+ shutil.copy(src_exe_path, boot / boot_file_name)
+ print(src_exe_path, boot / boot_file_name)
+
+ # Select the appropriate EDK2 build.
+ ovmf_code = ovmf_dir / ovmf_code
+ ovmf_vars = ovmf_dir / ovmf_vars
+
+ # Make a writable copy of the vars file. aarch64 doesn't boot
+ # correctly with read-only vars.
+ ovmf_rw_vars = Path(tmp_dir) / 'vars.fd'
+ shutil.copy(ovmf_vars, ovmf_rw_vars)
+
+ # Run the executable in QEMU and capture the output.
+ output = run(qemu,
+ '-machine',
+ machine,
+ '-cpu',
+ cpu,
+ '-display',
+ 'none',
+ '-serial',
+ 'stdio',
+ '-drive',
+ f'if=pflash,format=raw,readonly=on,file={ovmf_code}',
+ '-drive',
+ f'if=pflash,format=raw,readonly=off,file={ovmf_rw_vars}',
+ '-drive',
+ f'format=raw,file=fat:rw:{esp}',
+ capture=True,
+ # Ubuntu 20.04 (which is what the Dockerfile currently
+ # uses) provides QEMU 4.2.1, which segfaults on
+ # shutdown under some circumstances. That has been
+ # fixed in newer versions of QEMU, but for now just
+ # don't check the exit status.
+ check=False,
+ # Set a timeout to kill the VM in case something goes wrong.
+ timeout=60).stdout
+
+ if 'Hello World!' in output:
+ print('VM produced expected output')
+ else:
+ print('unexpected VM output:')
+ print('---start---')
+ print(output)
+ print('---end---')
+ sys.exit(1)
+
+
+def main():
+ targets = [TARGET_AARCH64, TARGET_I686, TARGET_X86_64]
+
+ for target in targets:
+ # Create a temporary directory so that we have a writeable
+ # workspace.
+ with tempfile.TemporaryDirectory() as tmp_dir:
+ build_and_run(tmp_dir, target)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs
new file mode 100644
index 000000000..2ec554c14
--- /dev/null
+++ b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs
@@ -0,0 +1,45 @@
+// Code is adapted from this hello world example:
+// https://doc.rust-lang.org/nightly/rustc/platform-support/unknown-uefi.html
+
+#![no_main]
+#![no_std]
+
+use core::{panic, ptr};
+use r_efi::efi::{Char16, Handle, Status, SystemTable, RESET_SHUTDOWN};
+
+#[panic_handler]
+fn panic_handler(_info: &panic::PanicInfo) -> ! {
+ loop {}
+}
+
+#[export_name = "efi_main"]
+pub extern "C" fn main(_h: Handle, st: *mut SystemTable) -> Status {
+ let s = [
+ 0x0048u16, 0x0065u16, 0x006cu16, 0x006cu16, 0x006fu16, // "Hello"
+ 0x0020u16, // " "
+ 0x0057u16, 0x006fu16, 0x0072u16, 0x006cu16, 0x0064u16, // "World"
+ 0x0021u16, // "!"
+ 0x000au16, // "\n"
+ 0x0000u16, // NUL
+ ];
+
+ // Print "Hello World!".
+ let r = unsafe { ((*(*st).con_out).output_string)((*st).con_out, s.as_ptr() as *mut Char16) };
+ if r.is_error() {
+ return r;
+ }
+
+ // Shut down.
+ unsafe {
+ ((*((*st).runtime_services)).reset_system)(
+ RESET_SHUTDOWN,
+ Status::SUCCESS,
+ 0,
+ ptr::null_mut(),
+ );
+ }
+
+ // This should never be reached because `reset_system` should never
+ // return, so fail with an error if we get here.
+ Status::UNSUPPORTED
+}
diff --git a/src/ci/docker/host-x86_64/wasm32/Dockerfile b/src/ci/docker/host-x86_64/wasm32/Dockerfile
index 9e37c2822..ef1fde1c3 100644
--- a/src/ci/docker/host-x86_64/wasm32/Dockerfile
+++ b/src/ci/docker/host-x86_64/wasm32/Dockerfile
@@ -13,7 +13,8 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
sudo \
gdb \
xz-utils \
- bzip2
+ bzip2 \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/emscripten.sh /scripts/
RUN bash /scripts/emscripten.sh
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
index d55d5b56a..e08c4e1e8 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile
@@ -19,7 +19,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
llvm-dev \
libfreetype6-dev \
libexpat1-dev \
- tidy
+ tidy \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
index 739045248..c2b002055 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
@@ -23,7 +23,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config \
xz-utils \
lld \
- clang
+ clang \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
index 80a004501..7e640c49f 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-distcheck/Dockerfile
@@ -15,7 +15,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
gdb \
xz-utils \
libssl-dev \
- pkg-config
+ pkg-config \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
index 1289f116f..16976a942 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile
@@ -21,7 +21,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config \
zlib1g-dev \
xz-utils \
- nodejs
+ nodejs \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
@@ -29,7 +30,6 @@ RUN sh /scripts/sccache.sh
# We are disabling CI LLVM since this builder is intentionally using a host
# LLVM, rather than the typical src/llvm-project LLVM.
ENV NO_DOWNLOAD_CI_LLVM 1
-ENV EXTERNAL_LLVM 1
# Using llvm-link-shared due to libffi issues -- see #34486
ENV RUST_CONFIGURE_ARGS \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
index 4b89a72ba..06f15bd12 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile
@@ -24,15 +24,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config \
zlib1g-dev \
xz-utils \
- nodejs
-
+ nodejs \
+ \
# Install powershell so we can test x.ps1 on Linux
-RUN apt-get update && \
- apt-get install -y apt-transport-https software-properties-common && \
+ apt-transport-https software-properties-common && \
curl -s "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb" > packages-microsoft-prod.deb && \
dpkg -i packages-microsoft-prod.deb && \
apt-get update && \
- apt-get install -y powershell
+ apt-get install -y powershell \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
@@ -40,7 +40,6 @@ RUN sh /scripts/sccache.sh
# We are disabling CI LLVM since this builder is intentionally using a host
# LLVM, rather than the typical src/llvm-project LLVM.
ENV NO_DOWNLOAD_CI_LLVM 1
-ENV EXTERNAL_LLVM 1
# Using llvm-link-shared due to libffi issues -- see #34486
ENV RUST_CONFIGURE_ARGS \
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile
index 77510d7ac..9fdc78406 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-nopt/Dockerfile
@@ -15,7 +15,8 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins
gdb \
libssl-dev \
pkg-config \
- xz-utils
+ xz-utils \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
index 4350ca205..58c0c5db1 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
@@ -14,10 +14,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libssl-dev \
sudo \
xz-utils \
- tidy
-
+ tidy \
+ \
# Install dependencies for chromium browser
-RUN apt-get install -y \
gconf-service \
libasound2 \
libatk1.0-0 \
@@ -56,7 +55,8 @@ RUN apt-get install -y \
libnss3 \
lsb-release \
xdg-utils \
- wget
+ wget \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index cc96715b2..3f8dcd03d 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.12.7 \ No newline at end of file
+0.13.2 \ No newline at end of file
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
index 80a066cac..7dde63709 100755
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
@@ -27,6 +27,7 @@ python3 "$X_PY" test --stage 2 src/tools/rustfmt
python3 "$X_PY" test --stage 2 src/tools/miri
# We natively run this script on x86_64-unknown-linux-gnu and x86_64-pc-windows-msvc.
# Also cover some other targets (on both of these hosts) via cross-testing.
+export BOOTSTRAP_SKIP_TARGET_SANITY=1 # we don't need `cc` for these targets
python3 "$X_PY" test --stage 2 src/tools/miri --target i686-pc-windows-msvc
-#FIXME(https://github.com/rust-lang/rust/issues/103519): macOS testing is currently disabled
-# python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-apple-darwin
+python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-apple-darwin
+unset BOOTSTRAP_SKIP_TARGET_SANITY
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile
index 88c182a4d..5b9581f72 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile
@@ -15,7 +15,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
gdb \
libssl-dev \
pkg-config \
- xz-utils
+ xz-utils \
+ && rm -rf /var/lib/apt/lists/*
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh
index 4a4cac1b7..17cd456b9 100755
--- a/src/ci/docker/scripts/freebsd-toolchain.sh
+++ b/src/ci/docker/scripts/freebsd-toolchain.sh
@@ -53,7 +53,7 @@ files_to_extract=(
for lib in c cxxrt gcc_s m thr util; do
files_to_extract=("${files_to_extract[@]}" "./lib/lib${lib}.*" "./usr/lib/lib${lib}.*")
done
-for lib in c++ c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared procstat devstat kvm; do
+for lib in c++ c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared procstat devstat kvm memstat; do
files_to_extract=("${files_to_extract[@]}" "./usr/lib/lib${lib}.*")
done
diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py
new file mode 100755
index 000000000..a2708d169
--- /dev/null
+++ b/src/ci/docker/scripts/fuchsia-test-runner.py
@@ -0,0 +1,1041 @@
+#!/usr/bin/env python3
+
+"""
+The Rust toolchain test runner for Fuchsia.
+
+For instructions on running the compiler test suite, see
+https://doc.rust-lang.org/stable/rustc/platform-support/fuchsia.html#aarch64-fuchsia-and-x86_64-fuchsia
+"""
+
+import argparse
+from dataclasses import dataclass
+import glob
+import hashlib
+import json
+import os
+import platform
+import re
+import shutil
+import signal
+import subprocess
+import sys
+from typing import ClassVar, List
+
+
+@dataclass
+class TestEnvironment:
+ rust_dir: str
+ sdk_dir: str
+ target_arch: str
+ package_server_pid: int = None
+ emu_addr: str = None
+ libstd_name: str = None
+ libtest_name: str = None
+ verbose: bool = False
+
+ @staticmethod
+ def tmp_dir():
+ tmp_dir = os.environ.get("TEST_TOOLCHAIN_TMP_DIR")
+ if tmp_dir is not None:
+ return os.path.abspath(tmp_dir)
+ return os.path.join(os.path.dirname(__file__), "tmp~")
+
+ @classmethod
+ def env_file_path(cls):
+ return os.path.join(cls.tmp_dir(), "test_env.json")
+
+ @classmethod
+ def from_args(cls, args):
+ return cls(
+ os.path.abspath(args.rust),
+ os.path.abspath(args.sdk),
+ args.target_arch,
+ verbose=args.verbose,
+ )
+
+ @classmethod
+ def read_from_file(cls):
+ with open(cls.env_file_path(), encoding="utf-8") as f:
+ test_env = json.loads(f.read())
+ return cls(
+ test_env["rust_dir"],
+ test_env["sdk_dir"],
+ test_env["target_arch"],
+ libstd_name=test_env["libstd_name"],
+ libtest_name=test_env["libtest_name"],
+ emu_addr=test_env["emu_addr"],
+ package_server_pid=test_env["package_server_pid"],
+ verbose=test_env["verbose"],
+ )
+
+ def image_name(self):
+ if self.target_arch == "x64":
+ return "qemu-x64"
+ if self.target_arch == "arm64":
+ return "qemu-arm64"
+ raise Exception(f"Unrecognized target architecture {self.target_arch}")
+
+ def write_to_file(self):
+ with open(self.env_file_path(), "w", encoding="utf-8") as f:
+ f.write(json.dumps(self.__dict__))
+
+ def ssh_dir(self):
+ return os.path.join(self.tmp_dir(), "ssh")
+
+ def ssh_keyfile_path(self):
+ return os.path.join(self.ssh_dir(), "fuchsia_ed25519")
+
+ def ssh_authfile_path(self):
+ return os.path.join(self.ssh_dir(), "fuchsia_authorized_keys")
+
+ def vdl_output_path(self):
+ return os.path.join(self.tmp_dir(), "vdl_output")
+
+ def package_server_log_path(self):
+ return os.path.join(self.tmp_dir(), "package_server_log")
+
+ def emulator_log_path(self):
+ return os.path.join(self.tmp_dir(), "emulator_log")
+
+ def packages_dir(self):
+ return os.path.join(self.tmp_dir(), "packages")
+
+ def output_dir(self):
+ return os.path.join(self.tmp_dir(), "output")
+
+ TEST_REPO_NAME: ClassVar[str] = "rust-testing"
+
+ def repo_dir(self):
+ return os.path.join(self.tmp_dir(), self.TEST_REPO_NAME)
+
+ def rustlib_dir(self):
+ if self.target_arch == "x64":
+ return "x86_64-fuchsia"
+ if self.target_arch == "arm64":
+ return "aarch64-fuchsia"
+ raise Exception(f"Unrecognized target architecture {self.target_arch}")
+
+ def libs_dir(self):
+ return os.path.join(
+ self.rust_dir,
+ "lib",
+ )
+
+ def rustlibs_dir(self):
+ return os.path.join(
+ self.libs_dir(),
+ "rustlib",
+ self.rustlib_dir(),
+ "lib",
+ )
+
+ def sdk_arch(self):
+ machine = platform.machine()
+ if machine == "x86_64":
+ return "x64"
+ if machine == "arm":
+ return "a64"
+ raise Exception(f"Unrecognized host architecture {machine}")
+
+ def tool_path(self, tool):
+ return os.path.join(self.sdk_dir, "tools", self.sdk_arch(), tool)
+
+ def host_arch_triple(self):
+ machine = platform.machine()
+ if machine == "x86_64":
+ return "x86_64-unknown-linux-gnu"
+ if machine == "arm":
+ return "aarch64-unknown-linux-gnu"
+ raise Exception(f"Unrecognized host architecture {machine}")
+
+ def zxdb_script_path(self):
+ return os.path.join(self.tmp_dir(), "zxdb_script")
+
+ def log_info(self, msg):
+ print(msg)
+
+ def log_debug(self, msg):
+ if self.verbose:
+ print(msg)
+
+ def subprocess_output(self):
+ if self.verbose:
+ return sys.stdout
+ return subprocess.DEVNULL
+
+ def ffx_daemon_log_path(self):
+ return os.path.join(self.tmp_dir(), "ffx_daemon_log")
+
+ def ffx_isolate_dir(self):
+ return os.path.join(self.tmp_dir(), "ffx_isolate")
+
+ def ffx_home_dir(self):
+ return os.path.join(self.ffx_isolate_dir(), "user-home")
+
+ def ffx_tmp_dir(self):
+ return os.path.join(self.ffx_isolate_dir(), "tmp")
+
+ def ffx_log_dir(self):
+ return os.path.join(self.ffx_isolate_dir(), "log")
+
+ def ffx_user_config_dir(self):
+ return os.path.join(self.ffx_xdg_config_home(), "Fuchsia", "ffx", "config")
+
+ def ffx_user_config_path(self):
+ return os.path.join(self.ffx_user_config_dir(), "config.json")
+
+ def ffx_xdg_config_home(self):
+ if platform.system() == "Darwin":
+ return os.path.join(self.ffx_home_dir(), "Library", "Preferences")
+ return os.path.join(self.ffx_home_dir(), ".local", "share")
+
+ def ffx_ascendd_path(self):
+ return os.path.join(self.ffx_tmp_dir(), "ascendd")
+
+ def start_ffx_isolation(self):
+ # Most of this is translated directly from ffx's isolate library
+ os.mkdir(self.ffx_isolate_dir())
+ os.mkdir(self.ffx_home_dir())
+ os.mkdir(self.ffx_tmp_dir())
+ os.mkdir(self.ffx_log_dir())
+
+ fuchsia_dir = os.path.join(self.ffx_home_dir(), ".fuchsia")
+ os.mkdir(fuchsia_dir)
+
+ fuchsia_debug_dir = os.path.join(fuchsia_dir, "debug")
+ os.mkdir(fuchsia_debug_dir)
+
+ metrics_dir = os.path.join(fuchsia_dir, "metrics")
+ os.mkdir(metrics_dir)
+
+ analytics_path = os.path.join(metrics_dir, "analytics-status")
+ with open(analytics_path, "w", encoding="utf-8") as analytics_file:
+ print("0", file=analytics_file)
+
+ ffx_path = os.path.join(metrics_dir, "ffx")
+ with open(ffx_path, "w", encoding="utf-8") as ffx_file:
+ print("1", file=ffx_file)
+
+ os.makedirs(self.ffx_user_config_dir())
+
+ with open(
+ self.ffx_user_config_path(), "w", encoding="utf-8"
+ ) as config_json_file:
+ user_config_for_test = {
+ "log": {
+ "enabled": True,
+ "dir": self.ffx_log_dir(),
+ },
+ "overnet": {
+ "socket": self.ffx_ascendd_path(),
+ },
+ "ssh": {
+ "pub": self.ssh_authfile_path(),
+ "priv": self.ssh_keyfile_path(),
+ },
+ "test": {
+ "is_isolated": True,
+ "experimental_structured_output": True,
+ },
+ }
+ print(json.dumps(user_config_for_test), file=config_json_file)
+
+ ffx_env_path = os.path.join(self.ffx_user_config_dir(), ".ffx_env")
+ with open(ffx_env_path, "w", encoding="utf-8") as ffx_env_file:
+ ffx_env_config_for_test = {
+ "user": self.ffx_user_config_path(),
+ "build": None,
+ "global": None,
+ }
+ print(json.dumps(ffx_env_config_for_test), file=ffx_env_file)
+
+ # Start ffx daemon
+ # We want this to be a long-running process that persists after the script finishes
+ # pylint: disable=consider-using-with
+ with open(
+ self.ffx_daemon_log_path(), "w", encoding="utf-8"
+ ) as ffx_daemon_log_file:
+ subprocess.Popen(
+ [
+ self.tool_path("ffx"),
+ "--config",
+ self.ffx_user_config_path(),
+ "daemon",
+ "start",
+ ],
+ env=self.ffx_cmd_env(),
+ stdout=ffx_daemon_log_file,
+ stderr=ffx_daemon_log_file,
+ )
+
+ def ffx_cmd_env(self):
+ result = {
+ "HOME": self.ffx_home_dir(),
+ "XDG_CONFIG_HOME": self.ffx_xdg_config_home(),
+ "ASCENDD": self.ffx_ascendd_path(),
+ "FUCHSIA_SSH_KEY": self.ssh_keyfile_path(),
+ # We want to use our own specified temp directory
+ "TMP": self.tmp_dir(),
+ "TEMP": self.tmp_dir(),
+ "TMPDIR": self.tmp_dir(),
+ "TEMPDIR": self.tmp_dir(),
+ }
+
+ return result
+
+ def stop_ffx_isolation(self):
+ subprocess.check_call(
+ [
+ self.tool_path("ffx"),
+ "--config",
+ self.ffx_user_config_path(),
+ "daemon",
+ "stop",
+ ],
+ env=self.ffx_cmd_env(),
+ stdout=self.subprocess_output(),
+ stderr=self.subprocess_output(),
+ )
+
+ def start(self):
+ """Sets up the testing environment and prepares to run tests.
+
+ Args:
+ args: The command-line arguments to this command.
+
+ During setup, this function will:
+ - Locate necessary shared libraries
+ - Create a new temp directory (this is where all temporary files are stored)
+ - Start an emulator
+ - Start an update server
+ - Create a new package repo and register it with the emulator
+ - Write test environment settings to a temporary file
+ """
+
+ # Initialize temp directory
+ if not os.path.exists(self.tmp_dir()):
+ os.mkdir(self.tmp_dir())
+ elif len(os.listdir(self.tmp_dir())) != 0:
+ raise Exception(f"Temp directory is not clean (in {self.tmp_dir()})")
+
+ os.mkdir(self.ssh_dir())
+ os.mkdir(self.output_dir())
+
+ # Find libstd and libtest
+ libstd_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libstd-*.so"))
+ libtest_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libtest-*.so"))
+
+ if not libstd_paths:
+ raise Exception(f"Failed to locate libstd (in {self.rustlibs_dir()})")
+
+ if not libtest_paths:
+ raise Exception(f"Failed to locate libtest (in {self.rustlibs_dir()})")
+
+ self.libstd_name = os.path.basename(libstd_paths[0])
+ self.libtest_name = os.path.basename(libtest_paths[0])
+
+ # Generate SSH keys for the emulator to use
+ self.log_info("Generating SSH keys...")
+ subprocess.check_call(
+ [
+ "ssh-keygen",
+ "-N",
+ "",
+ "-t",
+ "ed25519",
+ "-f",
+ self.ssh_keyfile_path(),
+ "-C",
+ "Generated by test_toolchain.py",
+ ],
+ stdout=self.subprocess_output(),
+ stderr=self.subprocess_output(),
+ )
+ authfile_contents = subprocess.check_output(
+ [
+ "ssh-keygen",
+ "-y",
+ "-f",
+ self.ssh_keyfile_path(),
+ ],
+ stderr=self.subprocess_output(),
+ )
+ with open(self.ssh_authfile_path(), "wb") as authfile:
+ authfile.write(authfile_contents)
+
+ # Start ffx isolation
+ self.log_info("Starting ffx isolation...")
+ self.start_ffx_isolation()
+
+ # Start emulator (this will generate the vdl output)
+ self.log_info("Starting emulator...")
+ subprocess.check_call(
+ [
+ self.tool_path("fvdl"),
+ "--sdk",
+ "start",
+ "--tuntap",
+ "--headless",
+ "--nointeractive",
+ "--ssh",
+ self.ssh_dir(),
+ "--vdl-output",
+ self.vdl_output_path(),
+ "--emulator-log",
+ self.emulator_log_path(),
+ "--image-name",
+ self.image_name(),
+ ],
+ stdout=self.subprocess_output(),
+ stderr=self.subprocess_output(),
+ )
+
+ # Parse vdl output for relevant information
+ with open(self.vdl_output_path(), encoding="utf-8") as f:
+ vdl_content = f.read()
+ matches = re.search(
+ r'network_address:\s+"\[([0-9a-f]{1,4}:(:[0-9a-f]{1,4}){4}%qemu)\]"',
+ vdl_content,
+ )
+ self.emu_addr = matches.group(1)
+
+ # Create new package repo
+ self.log_info("Creating package repo...")
+ subprocess.check_call(
+ [
+ self.tool_path("pm"),
+ "newrepo",
+ "-repo",
+ self.repo_dir(),
+ ],
+ stdout=self.subprocess_output(),
+ stderr=self.subprocess_output(),
+ )
+
+ # Start package server
+ self.log_info("Starting package server...")
+ with open(
+ self.package_server_log_path(), "w", encoding="utf-8"
+ ) as package_server_log:
+ # We want this to be a long-running process that persists after the script finishes
+ # pylint: disable=consider-using-with
+ self.package_server_pid = subprocess.Popen(
+ [
+ self.tool_path("pm"),
+ "serve",
+ "-vt",
+ "-repo",
+ self.repo_dir(),
+ "-l",
+ ":8084",
+ ],
+ stdout=package_server_log,
+ stderr=package_server_log,
+ ).pid
+
+ # Register package server with emulator
+ self.log_info("Registering package server...")
+ ssh_client = subprocess.check_output(
+ [
+ "ssh",
+ "-i",
+ self.ssh_keyfile_path(),
+ "-o",
+ "StrictHostKeyChecking=accept-new",
+ self.emu_addr,
+ "-f",
+ "echo $SSH_CLIENT",
+ ],
+ text=True,
+ )
+ repo_addr = ssh_client.split()[0].replace("%", "%25")
+ repo_url = f"http://[{repo_addr}]:8084/config.json"
+ subprocess.check_call(
+ [
+ "ssh",
+ "-i",
+ self.ssh_keyfile_path(),
+ "-o",
+ "StrictHostKeyChecking=accept-new",
+ self.emu_addr,
+ "-f",
+ f"pkgctl repo add url -f 1 -n {self.TEST_REPO_NAME} {repo_url}",
+ ],
+ stdout=self.subprocess_output(),
+ stderr=self.subprocess_output(),
+ )
+
+ # Write to file
+ self.write_to_file()
+
+ self.log_info("Success! Your environment is ready to run tests.")
+
+ # FIXME: shardify this
+ # `facet` statement required for TCP testing via
+ # protocol `fuchsia.posix.socket.Provider`. See
+ # https://fuchsia.dev/fuchsia-src/development/testing/components/test_runner_framework?hl=en#legacy_non-hermetic_tests
+ CML_TEMPLATE: ClassVar[
+ str
+ ] = """
+ {{
+ program: {{
+ runner: "elf_test_runner",
+ binary: "bin/{exe_name}",
+ forward_stderr_to: "log",
+ forward_stdout_to: "log",
+ environ: [{env_vars}
+ ]
+ }},
+ capabilities: [
+ {{ protocol: "fuchsia.test.Suite" }},
+ ],
+ expose: [
+ {{
+ protocol: "fuchsia.test.Suite",
+ from: "self",
+ }},
+ ],
+ use: [
+ {{ storage: "data", path: "/data" }},
+ {{ protocol: [ "fuchsia.process.Launcher" ] }},
+ {{ protocol: [ "fuchsia.posix.socket.Provider" ] }}
+ ],
+ facets: {{
+ "fuchsia.test": {{ type: "system" }},
+ }},
+ }}
+ """
+
+ MANIFEST_TEMPLATE = """
+ meta/package={package_dir}/meta/package
+ meta/{package_name}.cm={package_dir}/meta/{package_name}.cm
+ bin/{exe_name}={bin_path}
+ lib/{libstd_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libstd_name}
+ lib/{libtest_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libtest_name}
+ lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/lib/libc.so
+ lib/libzircon.so={sdk_dir}/arch/{target_arch}/sysroot/lib/libzircon.so
+ lib/libfdio.so={sdk_dir}/arch/{target_arch}/lib/libfdio.so
+ """
+
+ TEST_ENV_VARS: ClassVar[List[str]] = [
+ "TEST_EXEC_ENV",
+ "RUST_MIN_STACK",
+ "RUST_BACKTRACE",
+ "RUST_NEWRT",
+ "RUST_LOG",
+ "RUST_TEST_THREADS",
+ ]
+
+ def run(self, args):
+ """Runs the requested test in the testing environment.
+
+ Args:
+ args: The command-line arguments to this command.
+ Returns:
+ The return code of the test (0 for success, else failure).
+
+ To run a test, this function will:
+ - Create, compile, archive, and publish a test package
+ - Run the test package on the emulator
+ - Forward the test's stdout and stderr as this script's stdout and stderr
+ """
+
+ bin_path = os.path.abspath(args.bin_path)
+
+ # Build a unique, deterministic name for the test using the name of the
+ # binary and the last 6 hex digits of the hash of the full path
+ def path_checksum(path):
+ m = hashlib.sha256()
+ m.update(path.encode("utf-8"))
+ return m.hexdigest()[0:6]
+
+ base_name = os.path.basename(os.path.dirname(args.bin_path))
+ exe_name = base_name.lower().replace(".", "_")
+ package_name = f"{exe_name}_{path_checksum(bin_path)}"
+
+ package_dir = os.path.join(self.packages_dir(), package_name)
+ cml_path = os.path.join(package_dir, "meta", f"{package_name}.cml")
+ cm_path = os.path.join(package_dir, "meta", f"{package_name}.cm")
+ manifest_path = os.path.join(package_dir, f"{package_name}.manifest")
+ far_path = os.path.join(package_dir, f"{package_name}-0.far")
+
+ shared_libs = args.shared_libs[: args.n]
+ arguments = args.shared_libs[args.n :]
+
+ test_output_dir = os.path.join(self.output_dir(), package_name)
+
+ # Clean and create temporary output directory
+ if os.path.exists(test_output_dir):
+ shutil.rmtree(test_output_dir)
+
+ os.mkdir(test_output_dir)
+
+ # Open log file
+ log_path = os.path.join(test_output_dir, "log")
+ with open(log_path, "w", encoding="utf-8") as log_file:
+
+ def log(msg):
+ print(msg, file=log_file)
+ log_file.flush()
+
+ log(f"Bin path: {bin_path}")
+
+ log("Setting up package...")
+
+ # Set up package
+ subprocess.check_call(
+ [
+ self.tool_path("pm"),
+ "-o",
+ package_dir,
+ "-n",
+ package_name,
+ "init",
+ ],
+ stdout=log_file,
+ stderr=log_file,
+ )
+
+ log("Writing CML...")
+
+ # Write and compile CML
+ with open(cml_path, "w", encoding="utf-8") as cml:
+ # Collect environment variables
+ env_vars = ""
+ for var_name in self.TEST_ENV_VARS:
+ var_value = os.getenv(var_name)
+ if var_value is not None:
+ env_vars += f'\n "{var_name}={var_value}",'
+
+ # Default to no backtrace for test suite
+ if os.getenv("RUST_BACKTRACE") == None:
+ env_vars += f'\n "RUST_BACKTRACE=0",'
+
+ cml.write(
+ self.CML_TEMPLATE.format(env_vars=env_vars, exe_name=exe_name)
+ )
+
+ log("Compiling CML...")
+
+ subprocess.check_call(
+ [
+ self.tool_path("cmc"),
+ "compile",
+ cml_path,
+ "--includepath",
+ ".",
+ "--output",
+ cm_path,
+ ],
+ stdout=log_file,
+ stderr=log_file,
+ )
+
+ log("Writing manifest...")
+
+ # Write, build, and archive manifest
+ with open(manifest_path, "w", encoding="utf-8") as manifest:
+ manifest.write(
+ self.MANIFEST_TEMPLATE.format(
+ bin_path=bin_path,
+ exe_name=exe_name,
+ package_dir=package_dir,
+ package_name=package_name,
+ rust_dir=self.rust_dir,
+ rustlib_dir=self.rustlib_dir(),
+ sdk_dir=self.sdk_dir,
+ libstd_name=self.libstd_name,
+ libtest_name=self.libtest_name,
+ target_arch=self.target_arch,
+ )
+ )
+ for shared_lib in shared_libs:
+ manifest.write(f"lib/{os.path.basename(shared_lib)}={shared_lib}\n")
+
+ log("Compiling and archiving manifest...")
+
+ subprocess.check_call(
+ [
+ self.tool_path("pm"),
+ "-o",
+ package_dir,
+ "-m",
+ manifest_path,
+ "build",
+ ],
+ stdout=log_file,
+ stderr=log_file,
+ )
+ subprocess.check_call(
+ [
+ self.tool_path("pm"),
+ "-o",
+ package_dir,
+ "-m",
+ manifest_path,
+ "archive",
+ ],
+ stdout=log_file,
+ stderr=log_file,
+ )
+
+ log("Publishing package to repo...")
+
+ # Publish package to repo
+ subprocess.check_call(
+ [
+ self.tool_path("pm"),
+ "publish",
+ "-a",
+ "-repo",
+ self.repo_dir(),
+ "-f",
+ far_path,
+ ],
+ stdout=log_file,
+ stderr=log_file,
+ )
+
+ log("Running ffx test...")
+
+ # Run test on emulator
+ subprocess.run(
+ [
+ self.tool_path("ffx"),
+ "--config",
+ self.ffx_user_config_path(),
+ "test",
+ "run",
+ f"fuchsia-pkg://{self.TEST_REPO_NAME}/{package_name}#meta/{package_name}.cm",
+ "--min-severity-logs",
+ "TRACE",
+ "--output-directory",
+ test_output_dir,
+ "--",
+ ]
+ + arguments,
+ env=self.ffx_cmd_env(),
+ check=False,
+ stdout=log_file,
+ stderr=log_file,
+ )
+
+ log("Reporting test suite output...")
+
+ # Read test suite output
+ run_summary_path = os.path.join(test_output_dir, "run_summary.json")
+ if os.path.exists(run_summary_path):
+ with open(run_summary_path, encoding="utf-8") as f:
+ run_summary = json.loads(f.read())
+
+ suite = run_summary["data"]["suites"][0]
+ case = suite["cases"][0]
+
+ return_code = 0 if case["outcome"] == "PASSED" else 1
+
+ artifacts = case["artifacts"]
+ artifact_dir = case["artifact_dir"]
+ stdout_path = None
+ stderr_path = None
+
+ for path, artifact in artifacts.items():
+ artifact_path = os.path.join(test_output_dir, artifact_dir, path)
+ artifact_type = artifact["artifact_type"]
+
+ if artifact_type == "STDERR":
+ stderr_path = artifact_path
+ elif artifact_type == "STDOUT":
+ stdout_path = artifact_path
+
+ if stdout_path is not None and os.path.exists(stdout_path):
+ with open(stdout_path, encoding="utf-8") as f:
+ print(f.read(), file=sys.stdout, end="")
+
+ if stderr_path is not None and os.path.exists(stderr_path):
+ with open(stderr_path, encoding="utf-8") as f:
+ print(f.read(), file=sys.stderr, end="")
+ else:
+ log("Failed to open test run summary")
+ return_code = 254
+
+ log("Done!")
+
+ return return_code
+
+ def stop(self):
+ """Shuts down and cleans up the testing environment.
+
+ Args:
+ args: The command-line arguments to this command.
+ Returns:
+ The return code of the test (0 for success, else failure).
+
+ During cleanup, this function will stop the emulator, package server, and
+ update server, then delete all temporary files. If an error is encountered
+ while stopping any running processes, the temporary files will not be deleted.
+ Passing --delete-tmp will force the process to delete the files anyway.
+ """
+
+ self.log_debug("Reporting logs...")
+
+ # Print test log files
+ for test_dir in os.listdir(self.output_dir()):
+ log_path = os.path.join(self.output_dir(), test_dir, "log")
+ self.log_debug(f"\n---- Logs for test '{test_dir}' ----\n")
+ if os.path.exists(log_path):
+ with open(log_path, encoding="utf-8") as log:
+ self.log_debug(log.read())
+ else:
+ self.log_debug("No logs found")
+
+ # Print the emulator log
+ self.log_debug("\n---- Emulator logs ----\n")
+ if os.path.exists(self.emulator_log_path()):
+ with open(self.emulator_log_path(), encoding="utf-8") as log:
+ self.log_debug(log.read())
+ else:
+ self.log_debug("No emulator logs found")
+
+ # Print the package server log
+ self.log_debug("\n---- Package server log ----\n")
+ if os.path.exists(self.package_server_log_path()):
+ with open(self.package_server_log_path(), encoding="utf-8") as log:
+ self.log_debug(log.read())
+ else:
+ self.log_debug("No package server log found")
+
+ # Print the ffx daemon log
+ self.log_debug("\n---- ffx daemon log ----\n")
+ if os.path.exists(self.ffx_daemon_log_path()):
+ with open(self.ffx_daemon_log_path(), encoding="utf-8") as log:
+ self.log_debug(log.read())
+ else:
+ self.log_debug("No ffx daemon log found")
+
+ # Stop package server
+ self.log_info("Stopping package server...")
+ os.kill(self.package_server_pid, signal.SIGTERM)
+
+ # Shut down the emulator
+ self.log_info("Stopping emulator...")
+ subprocess.check_call(
+ [
+ self.tool_path("fvdl"),
+ "--sdk",
+ "kill",
+ "--launched-proto",
+ self.vdl_output_path(),
+ ],
+ stdout=self.subprocess_output(),
+ stderr=self.subprocess_output(),
+ )
+
+ # Stop ffx isolation
+ self.log_info("Stopping ffx isolation...")
+ self.stop_ffx_isolation()
+
+ def delete_tmp(self):
+ # Remove temporary files
+ self.log_info("Deleting temporary files...")
+ shutil.rmtree(self.tmp_dir(), ignore_errors=True)
+
+ def debug(self, args):
+ command = [
+ self.tool_path("ffx"),
+ "--config",
+ self.ffx_user_config_path(),
+ "debug",
+ "connect",
+ "--",
+ "--build-id-dir",
+ os.path.join(self.sdk_dir, ".build-id"),
+ "--build-id-dir",
+ os.path.join(self.libs_dir(), ".build-id"),
+ ]
+
+ # Add rust source if it's available
+ if args.rust_src is not None:
+ command += [
+ "--build-dir",
+ args.rust_src,
+ ]
+
+ # Add fuchsia source if it's available
+ if args.fuchsia_src is not None:
+ command += [
+ "--build-dir",
+ os.path.join(args.fuchsia_src, "out", "default"),
+ ]
+
+ # Load debug symbols for the test binary and automatically attach
+ if args.test is not None:
+ if args.rust_src is None:
+ raise Exception(
+ "A Rust source path is required with the `test` argument"
+ )
+
+ test_name = os.path.splitext(os.path.basename(args.test))[0]
+
+ build_dir = os.path.join(
+ args.rust_src,
+ "fuchsia-build",
+ self.host_arch_triple(),
+ )
+ test_dir = os.path.join(
+ build_dir,
+ "test",
+ os.path.dirname(args.test),
+ test_name,
+ )
+
+ with open(self.zxdb_script_path(), mode="w", encoding="utf-8") as f:
+ print(f"attach {test_name[:31]}", file=f)
+
+ command += [
+ "--symbol-path",
+ test_dir,
+ "-S",
+ self.zxdb_script_path(),
+ ]
+
+ # Add any other zxdb arguments the user passed
+ if args.zxdb_args is not None:
+ command += args.zxdb_args
+
+ # Connect to the running emulator with zxdb
+ subprocess.run(command, env=self.ffx_cmd_env(), check=False)
+
+
+def start(args):
+ test_env = TestEnvironment.from_args(args)
+ test_env.start()
+ return 0
+
+
+def run(args):
+ test_env = TestEnvironment.read_from_file()
+ return test_env.run(args)
+
+
+def stop(args):
+ test_env = TestEnvironment.read_from_file()
+ test_env.stop()
+ if not args.no_delete:
+ test_env.delete_tmp()
+ return 0
+
+
+def delete_tmp(args):
+ del args
+ test_env = TestEnvironment.read_from_file()
+ test_env.delete_tmp()
+ return 0
+
+
+def debug(args):
+ test_env = TestEnvironment.read_from_file()
+ test_env.debug(args)
+ return 0
+
+
+def main():
+ parser = argparse.ArgumentParser()
+
+ def print_help(args):
+ del args
+ parser.print_help()
+ return 0
+
+ parser.set_defaults(func=print_help)
+
+ subparsers = parser.add_subparsers(help="valid sub-commands")
+
+ start_parser = subparsers.add_parser(
+ "start", help="initializes the testing environment"
+ )
+ start_parser.add_argument(
+ "--rust",
+ help="the directory of the installed Rust compiler for Fuchsia",
+ required=True,
+ )
+ start_parser.add_argument(
+ "--sdk",
+ help="the directory of the fuchsia SDK",
+ required=True,
+ )
+ start_parser.add_argument(
+ "--verbose",
+ help="prints more output from executed processes",
+ action="store_true",
+ )
+ start_parser.add_argument(
+ "--target-arch",
+ help="the architecture of the image to test",
+ required=True,
+ )
+ start_parser.set_defaults(func=start)
+
+ run_parser = subparsers.add_parser(
+ "run", help="run a test in the testing environment"
+ )
+ run_parser.add_argument(
+ "n", help="the number of shared libs passed along with the executable", type=int
+ )
+ run_parser.add_argument("bin_path", help="path to the binary to run")
+ run_parser.add_argument(
+ "shared_libs",
+ help="the shared libs passed along with the binary",
+ nargs=argparse.REMAINDER,
+ )
+ run_parser.set_defaults(func=run)
+
+ stop_parser = subparsers.add_parser(
+ "stop", help="shuts down and cleans up the testing environment"
+ )
+ stop_parser.add_argument(
+ "--no-delete",
+ default=False,
+ action="store_true",
+ help="don't delete temporary files after stopping",
+ )
+ stop_parser.set_defaults(func=stop)
+
+ delete_parser = subparsers.add_parser(
+ "delete-tmp",
+ help="deletes temporary files after the testing environment has been manually cleaned up",
+ )
+ delete_parser.set_defaults(func=delete_tmp)
+
+ debug_parser = subparsers.add_parser(
+ "debug",
+ help="connect to the active testing environment with zxdb",
+ )
+ debug_parser.add_argument(
+ "--rust-src",
+ default=None,
+ help="the path to the Rust source being tested",
+ )
+ debug_parser.add_argument(
+ "--fuchsia-src",
+ default=None,
+ help="the path to the Fuchsia source",
+ )
+ debug_parser.add_argument(
+ "--test",
+ default=None,
+ help="the path to the test to debug (e.g. ui/box/new.rs)",
+ )
+ debug_parser.add_argument(
+ "zxdb_args",
+ default=None,
+ nargs=argparse.REMAINDER,
+ help="any additional arguments to pass to zxdb",
+ )
+ debug_parser.set_defaults(func=debug)
+
+ args = parser.parse_args()
+ return args.func(args)
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 9d98ce224..7de06ec35 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -69,11 +69,6 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-units-std=1"
# space required for CI artifacts.
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --dist-compression-formats=xz"
-# Enable the `c` feature for compiler_builtins, but only when the `compiler-rt` source is available.
-if [ "$EXTERNAL_LLVM" = "" ]; then
- RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.optimized-compiler-builtins"
-fi
-
if [ "$DIST_SRC" = "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src"
fi
@@ -128,6 +123,10 @@ else
# (And PGO is its own can of worms).
if [ "$NO_DOWNLOAD_CI_LLVM" = "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.download-ci-llvm=if-available"
+ else
+ # When building for CI we want to use the static C++ Standard library
+ # included with LLVM, since a dynamic libstdcpp may not be available.
+ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.static-libstdcpp"
fi
fi
diff --git a/src/ci/scripts/checkout-submodules.sh b/src/ci/scripts/checkout-submodules.sh
index f6cb8f8a6..5bb343241 100755
--- a/src/ci/scripts/checkout-submodules.sh
+++ b/src/ci/scripts/checkout-submodules.sh
@@ -36,7 +36,8 @@ function fetch_github_commit_archive {
rm $cached
}
-included="src/llvm-project src/doc/book src/doc/rust-by-example"
+#included="src/llvm-project src/doc/book src/doc/rust-by-example"
+included=""
modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)"
modules=($modules)
use_git=""
@@ -60,9 +61,9 @@ done
retry sh -c "git submodule deinit -f $use_git && \
git submodule sync && \
git submodule update -j 16 --init --recursive --depth 1 $use_git"
-STATUS=0
-for pid in ${bg_pids[*]}
-do
- wait $pid || STATUS=1
-done
-exit ${STATUS}
+#STATUS=0
+#for pid in ${bg_pids[*]}
+#do
+# wait $pid || STATUS=1
+#done
+#exit ${STATUS}
diff --git a/src/doc/book/.github/ISSUE_TEMPLATE/bug_report.md b/src/doc/book/.github/ISSUE_TEMPLATE/bug_report.md
index c1157112f..2423c4cd4 100644
--- a/src/doc/book/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/src/doc/book/.github/ISSUE_TEMPLATE/bug_report.md
@@ -3,8 +3,12 @@ name: Bug report
about: Create a report to help us improve
---
-- [ ] I have checked the latest `main` branch to see if this has already been fixed
-- [ ] I have searched existing issues and pull requests for duplicates
+- I have searched open and closed issues and pull requests for duplicates, using these search terms:
+ -
+ -
+ -
+- I have checked the latest `main` branch to see if this has already been fixed, in this file:
+ -
URL to the section(s) of the book with this problem:
diff --git a/src/doc/book/.github/workflows/main.yml b/src/doc/book/.github/workflows/main.yml
index d5b3249be..64ab49c51 100644
--- a/src/doc/book/.github/workflows/main.yml
+++ b/src/doc/book/.github/workflows/main.yml
@@ -12,12 +12,12 @@ jobs:
- name: Install Rust
run: |
rustup set profile minimal
- rustup toolchain install 1.62 -c rust-docs
- rustup default 1.62
+ rustup toolchain install 1.65 -c rust-docs
+ rustup default 1.65
- name: Install mdbook
run: |
mkdir bin
- curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.14/mdbook-v0.4.14-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin
+ curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin
echo "$(pwd)/bin" >> ${GITHUB_PATH}
- name: Report versions
run: |
@@ -41,7 +41,7 @@ jobs:
- name: Install mdbook
run: |
mkdir bin
- curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.14/mdbook-v0.4.14-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin
+ curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin
echo "$(pwd)/bin" >> ${GITHUB_PATH}
- name: Install aspell
run: sudo apt-get install aspell
diff --git a/src/doc/book/README.md b/src/doc/book/README.md
index 91c64ce25..94e1a004a 100644
--- a/src/doc/book/README.md
+++ b/src/doc/book/README.md
@@ -30,7 +30,7 @@ rust-lang/rust uses in [this file][rust-mdbook]. To get it:
[rust-mdbook]: https://github.com/rust-lang/rust/blob/master/src/tools/rustbook/Cargo.toml
```bash
-$ cargo install mdbook --vers [version-num]
+$ cargo install mdbook --version <version_num>
```
## Building
diff --git a/src/doc/book/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt b/src/doc/book/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt
index fbc0cec33..70a0c930c 100644
--- a/src/doc/book/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt
+++ b/src/doc/book/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt
@@ -11,10 +11,13 @@ error[E0308]: mismatched types
--> src/main.rs:22:21
|
22 | match guess.cmp(&secret_number) {
- | ^^^^^^^^^^^^^^ expected struct `String`, found integer
+ | --- ^^^^^^^^^^^^^^ expected struct `String`, found integer
+ | |
+ | arguments to this function are incorrect
|
= note: expected reference `&String`
found reference `&{integer}`
+note: associated function defined here
For more information about this error, try `rustc --explain E0308`.
error: could not compile `guessing_game` due to previous error
diff --git a/src/doc/book/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt b/src/doc/book/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt
index a5a85f4f6..6ae56e09d 100644
--- a/src/doc/book/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt
+++ b/src/doc/book/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt
@@ -1,5 +1,11 @@
$ cargo run
Compiling functions v0.1.0 (file:///projects/functions)
+error: expected expression, found `let` statement
+ --> src/main.rs:2:14
+ |
+2 | let x = (let y = 6);
+ | ^^^
+
error: expected expression, found statement (`let`)
--> src/main.rs:2:14
|
@@ -27,8 +33,8 @@ help: remove these parentheses
|
2 - let x = (let y = 6);
2 + let x = let y = 6;
- |
+ |
For more information about this error, try `rustc --explain E0658`.
warning: `functions` (bin "functions") generated 1 warning
-error: could not compile `functions` due to 2 previous errors; 1 warning emitted
+error: could not compile `functions` due to 3 previous errors; 1 warning emitted
diff --git a/src/doc/book/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt b/src/doc/book/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt
index d9807cee0..8a11cccd5 100644
--- a/src/doc/book/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt
+++ b/src/doc/book/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt
@@ -4,7 +4,12 @@ error[E0282]: type annotations needed
--> src/main.rs:2:9
|
2 | let guess = "42".parse().expect("Not a number!");
- | ^^^^^ consider giving `guess` a type
+ | ^^^^^
+ |
+help: consider giving `guess` an explicit type
+ |
+2 | let guess: _ = "42".parse().expect("Not a number!");
+ | +++
For more information about this error, try `rustc --explain E0282`.
error: could not compile `no_type_annotations` due to previous error
diff --git a/src/doc/book/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt b/src/doc/book/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt
index 6435eeb44..05987f7c8 100644
--- a/src/doc/book/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt
+++ b/src/doc/book/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt
@@ -7,11 +7,11 @@ error[E0382]: borrow of moved value: `s1`
| -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
3 | let s2 = s1;
| -- value moved here
-4 |
+4 |
5 | println!("{}, world!", s1);
| ^^ value borrowed here after move
|
- = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0382`.
error: could not compile `ownership` due to previous error
diff --git a/src/doc/book/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt b/src/doc/book/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt
index 71c29f68f..8820d2d69 100644
--- a/src/doc/book/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt
+++ b/src/doc/book/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt
@@ -7,7 +7,7 @@ error[E0499]: cannot borrow `s` as mutable more than once at a time
| ------ first mutable borrow occurs here
5 | let r2 = &mut s;
| ^^^^^^ second mutable borrow occurs here
-6 |
+6 |
7 | println!("{}, {}", r1, r2);
| -- first borrow later used here
diff --git a/src/doc/book/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt b/src/doc/book/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt
index df94c30e9..d1e9db2c4 100644
--- a/src/doc/book/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt
+++ b/src/doc/book/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt
@@ -8,7 +8,7 @@ error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immuta
5 | let r2 = &s; // no problem
6 | let r3 = &mut s; // BIG PROBLEM
| ^^^^^^ mutable borrow occurs here
-7 |
+7 |
8 | println!("{}, {}, and {}", r1, r2, r3);
| -- immutable borrow later used here
diff --git a/src/doc/book/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt b/src/doc/book/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt
index fddca683b..b466a3dce 100644
--- a/src/doc/book/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt
+++ b/src/doc/book/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt
@@ -10,7 +10,7 @@ error[E0106]: missing lifetime specifier
help: consider using the `'static` lifetime
|
5 | fn dangle() -> &'static String {
- | ~~~~~~~~
+ | +++++++
For more information about this error, try `rustc --explain E0106`.
error: could not compile `ownership` due to previous error
diff --git a/src/doc/book/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt b/src/doc/book/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt
index 62dc4ad52..ab0c41f4d 100644
--- a/src/doc/book/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt
+++ b/src/doc/book/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt
@@ -5,10 +5,10 @@ error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immuta
|
16 | let word = first_word(&s);
| -- immutable borrow occurs here
-17 |
+17 |
18 | s.clear(); // error!
| ^^^^^^^^^ mutable borrow occurs here
-19 |
+19 |
20 | println!("the first word is: {}", word);
| ---- immutable borrow later used here
diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs
index e0f7a6cd3..122d25164 100644
--- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs
+++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs
@@ -8,9 +8,9 @@ struct User {
// ANCHOR: here
fn main() {
let user1 = User {
- email: String::from("someone@example.com"),
- username: String::from("someusername123"),
active: true,
+ username: String::from("someusername123"),
+ email: String::from("someone@example.com"),
sign_in_count: 1,
};
}
diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs
index 7a078e7e8..35eea8a9a 100644
--- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs
+++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs
@@ -8,9 +8,9 @@ struct User {
// ANCHOR: here
fn main() {
let mut user1 = User {
- email: String::from("someone@example.com"),
- username: String::from("someusername123"),
active: true,
+ username: String::from("someusername123"),
+ email: String::from("someone@example.com"),
sign_in_count: 1,
};
diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs
index aa7823af4..8614561c1 100644
--- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs
+++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs
@@ -8,9 +8,9 @@ struct User {
// ANCHOR: here
fn build_user(email: String, username: String) -> User {
User {
- email: email,
- username: username,
active: true,
+ username: username,
+ email: email,
sign_in_count: 1,
}
}
diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs
index 8d84a3060..c893c86a9 100644
--- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs
+++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs
@@ -8,9 +8,9 @@ struct User {
// ANCHOR: here
fn build_user(email: String, username: String) -> User {
User {
- email,
- username,
active: true,
+ username,
+ email,
sign_in_count: 1,
}
}
diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt
index b761fccd6..7d3bfcdac 100644
--- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt
+++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt
@@ -8,7 +8,7 @@ error[E0277]: `Rectangle` doesn't implement `std::fmt::Display`
|
= help: the trait `std::fmt::Display` is not implemented for `Rectangle`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
- = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0277`.
error: could not compile `rectangles` due to previous error
diff --git a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt
index 69c8b38a6..58cb842bf 100644
--- a/src/doc/book/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt
+++ b/src/doc/book/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt
@@ -8,7 +8,7 @@ error[E0277]: `Rectangle` doesn't implement `Debug`
|
= help: the trait `Debug` is not implemented for `Rectangle`
= note: add `#[derive(Debug)]` to `Rectangle` or manually `impl Debug for Rectangle`
- = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Rectangle` with `#[derive(Debug)]`
|
1 | #[derive(Debug)]
diff --git a/src/doc/book/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt b/src/doc/book/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt
index c5a6c51bb..bec72849a 100644
--- a/src/doc/book/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt
+++ b/src/doc/book/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt
@@ -1,18 +1,18 @@
$ cargo run
Compiling enums v0.1.0 (file:///projects/enums)
error[E0004]: non-exhaustive patterns: `None` not covered
- --> src/main.rs:3:15
- |
-3 | match x {
- | ^ pattern `None` not covered
- |
+ --> src/main.rs:3:15
+ |
+3 | match x {
+ | ^ pattern `None` not covered
+ |
note: `Option<i32>` defined here
- = note: the matched value is of type `Option<i32>`
+ = note: the matched value is of type `Option<i32>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
- |
-4 ~ Some(i) => Some(i + 1),
-5 ~ None => todo!(),
- |
+ |
+4 ~ Some(i) => Some(i + 1),
+5 ~ None => todo!(),
+ |
For more information about this error, try `rustc --explain E0004`.
error: could not compile `enums` due to previous error
diff --git a/src/doc/book/listings/ch08-common-collections/listing-08-06/output.txt b/src/doc/book/listings/ch08-common-collections/listing-08-06/output.txt
index ab512a9e6..3104205f3 100644
--- a/src/doc/book/listings/ch08-common-collections/listing-08-06/output.txt
+++ b/src/doc/book/listings/ch08-common-collections/listing-08-06/output.txt
@@ -5,12 +5,12 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immuta
|
4 | let first = &v[0];
| - immutable borrow occurs here
-5 |
+5 |
6 | v.push(6);
| ^^^^^^^^^ mutable borrow occurs here
-7 |
-8 | println!("The first element is: {}", first);
- | ----- immutable borrow later used here
+7 |
+8 | println!("The first element is: {first}");
+ | ----- immutable borrow later used here
For more information about this error, try `rustc --explain E0502`.
error: could not compile `collections` due to previous error
diff --git a/src/doc/book/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt b/src/doc/book/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt
index 98d1f183a..35db879c9 100644
--- a/src/doc/book/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt
+++ b/src/doc/book/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt
@@ -2,5 +2,5 @@ $ cargo run
Compiling collections v0.1.0 (file:///projects/collections)
Finished dev [unoptimized + debuginfo] target(s) in 0.43s
Running `target/debug/collections`
-thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside 'З' (bytes 0..2) of `ЗдравÑтвуйте`', library/core/src/str/mod.rs:127:5
+thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside 'З' (bytes 0..2) of `ЗдравÑтвуйте`', src/main.rs:4:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/src/doc/book/listings/ch09-error-handling/listing-09-10/output.txt b/src/doc/book/listings/ch09-error-handling/listing-09-10/output.txt
index 26e4ff8cc..75b9cf2e3 100644
--- a/src/doc/book/listings/ch09-error-handling/listing-09-10/output.txt
+++ b/src/doc/book/listings/ch09-error-handling/listing-09-10/output.txt
@@ -3,11 +3,10 @@ $ cargo run
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> src/main.rs:4:48
|
-3 | / fn main() {
-4 | | let greeting_file = File::open("hello.txt")?;
- | | ^ cannot use the `?` operator in a function that returns `()`
-5 | | }
- | |_- this function should return `Result` or `Option` to accept `?`
+3 | fn main() {
+ | --------- this function should return `Result` or `Option` to accept `?`
+4 | let greeting_file = File::open("hello.txt")?;
+ | ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
diff --git a/src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt b/src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt
index b63bf83a1..ad7327209 100644
--- a/src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt
+++ b/src/doc/book/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt
@@ -7,7 +7,7 @@ error[E0597]: `x` does not live long enough
| ^^ borrowed value does not live long enough
7 | }
| - `x` dropped here while still borrowed
-8 |
+8 |
9 | println!("r: {}", r);
| - borrow later used here
diff --git a/src/doc/book/listings/ch11-writing-automated-tests/listing-11-03/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/listing-11-03/output.txt
index 0c2fd0327..2fa5cf077 100644
--- a/src/doc/book/listings/ch11-writing-automated-tests/listing-11-03/output.txt
+++ b/src/doc/book/listings/ch11-writing-automated-tests/listing-11-03/output.txt
@@ -19,4 +19,4 @@ failures:
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch11-writing-automated-tests/listing-11-10/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/listing-11-10/output.txt
index 0512cd59f..681cfbb81 100644
--- a/src/doc/book/listings/ch11-writing-automated-tests/listing-11-10/output.txt
+++ b/src/doc/book/listings/ch11-writing-automated-tests/listing-11-10/output.txt
@@ -22,4 +22,4 @@ failures:
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt
index fdeb597e3..7c62822f7 100644
--- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt
+++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt
@@ -19,4 +19,4 @@ failures:
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt
index 0af0401e3..28e2414be 100644
--- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt
+++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt
@@ -20,4 +20,4 @@ failures:
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt
index 3049543a7..3366e3ace 100644
--- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt
+++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt
@@ -18,4 +18,4 @@ failures:
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt
index d2ba1961b..cebebdaee 100644
--- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt
+++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt
@@ -18,4 +18,4 @@ failures:
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt
index f59dddec4..9318d4ce0 100644
--- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt
+++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt
@@ -16,4 +16,4 @@ failures:
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt
index c8cba98fe..c176e88b8 100644
--- a/src/doc/book/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt
+++ b/src/doc/book/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt
@@ -20,4 +20,4 @@ failures:
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt b/src/doc/book/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt
index 8caaeda06..4ececf245 100644
--- a/src/doc/book/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt
+++ b/src/doc/book/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt
@@ -31,4 +31,4 @@ failures:
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch12-an-io-project/listing-12-16/output.txt b/src/doc/book/listings/ch12-an-io-project/listing-12-16/output.txt
index d0cda6024..3c34e3945 100644
--- a/src/doc/book/listings/ch12-an-io-project/listing-12-16/output.txt
+++ b/src/doc/book/listings/ch12-an-io-project/listing-12-16/output.txt
@@ -20,4 +20,4 @@ failures:
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch13-functional-features/listing-13-03/output.txt b/src/doc/book/listings/ch13-functional-features/listing-13-03/output.txt
index 37d83618a..68838deff 100644
--- a/src/doc/book/listings/ch13-functional-features/listing-13-03/output.txt
+++ b/src/doc/book/listings/ch13-functional-features/listing-13-03/output.txt
@@ -4,9 +4,16 @@ error[E0308]: mismatched types
--> src/main.rs:5:29
|
5 | let n = example_closure(5);
- | ^- help: try using a conversion method: `.to_string()`
- | |
- | expected struct `String`, found integer
+ | --------------- ^- help: try using a conversion method: `.to_string()`
+ | | |
+ | | expected struct `String`, found integer
+ | arguments to this function are incorrect
+ |
+note: closure parameter defined here
+ --> src/main.rs:2:28
+ |
+2 | let example_closure = |x| x;
+ | ^
For more information about this error, try `rustc --explain E0308`.
error: could not compile `closure-example` due to previous error
diff --git a/src/doc/book/listings/ch13-functional-features/listing-13-08/output.txt b/src/doc/book/listings/ch13-functional-features/listing-13-08/output.txt
index 7a39ac618..a91053766 100644
--- a/src/doc/book/listings/ch13-functional-features/listing-13-08/output.txt
+++ b/src/doc/book/listings/ch13-functional-features/listing-13-08/output.txt
@@ -3,16 +3,13 @@ $ cargo run
error[E0507]: cannot move out of `value`, a captured variable in an `FnMut` closure
--> src/main.rs:18:30
|
-15 | let value = String::from("by key called");
- | ----- captured outer variable
-16 |
-17 | list.sort_by_key(|r| {
- | ______________________-
-18 | | sort_operations.push(value);
- | | ^^^^^ move occurs because `value` has type `String`, which does not implement the `Copy` trait
-19 | | r.width
-20 | | });
- | |_____- captured by this `FnMut` closure
+15 | let value = String::from("by key called");
+ | ----- captured outer variable
+16 |
+17 | list.sort_by_key(|r| {
+ | --- captured by this `FnMut` closure
+18 | sort_operations.push(value);
+ | ^^^^^ move occurs because `value` has type `String`, which does not implement the `Copy` trait
For more information about this error, try `rustc --explain E0507`.
error: could not compile `rectangles` due to previous error
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt
index 437d74b5c..d5522cd53 100644
--- a/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-03/output.txt
@@ -13,15 +13,5 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` repre
2 | Cons(i32, Box<List>),
| ++++ +
-error[E0391]: cycle detected when computing drop-check constraints for `List`
- --> src/main.rs:1:1
- |
-1 | enum List {
- | ^^^^^^^^^
- |
- = note: ...which immediately requires computing drop-check constraints for `List` again
- = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, constness: NotConst }, value: List } }`
-
-Some errors have detailed explanations: E0072, E0391.
-For more information about an error, try `rustc --explain E0072`.
-error: could not compile `cons-list` due to 2 previous errors
+For more information about this error, try `rustc --explain E0072`.
+error: could not compile `cons-list` due to previous error
diff --git a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt
index c44e69f13..3749c845c 100644
--- a/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt
+++ b/src/doc/book/listings/ch15-smart-pointers/listing-15-23/output.txt
@@ -18,4 +18,4 @@ failures:
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
-error: test failed, to rerun pass '--lib'
+error: test failed, to rerun pass `--lib`
diff --git a/src/doc/book/listings/ch16-fearless-concurrency/listing-16-09/output.txt b/src/doc/book/listings/ch16-fearless-concurrency/listing-16-09/output.txt
index 0795a3a4f..db8518537 100644
--- a/src/doc/book/listings/ch16-fearless-concurrency/listing-16-09/output.txt
+++ b/src/doc/book/listings/ch16-fearless-concurrency/listing-16-09/output.txt
@@ -10,7 +10,7 @@ error[E0382]: borrow of moved value: `val`
10 | println!("val is {}", val);
| ^^^ value borrowed here after move
|
- = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0382`.
error: could not compile `message-passing` due to previous error
diff --git a/src/doc/book/listings/ch16-fearless-concurrency/listing-16-14/output.txt b/src/doc/book/listings/ch16-fearless-concurrency/listing-16-14/output.txt
index 9546e1e48..0634b86e5 100644
--- a/src/doc/book/listings/ch16-fearless-concurrency/listing-16-14/output.txt
+++ b/src/doc/book/listings/ch16-fearless-concurrency/listing-16-14/output.txt
@@ -1,20 +1,26 @@
$ cargo run
Compiling shared-state v0.1.0 (file:///projects/shared-state)
error[E0277]: `Rc<Mutex<i32>>` cannot be sent between threads safely
- --> src/main.rs:11:22
- |
-11 | let handle = thread::spawn(move || {
- | ______________________^^^^^^^^^^^^^_-
- | | |
- | | `Rc<Mutex<i32>>` cannot be sent between threads safely
-12 | | let mut num = counter.lock().unwrap();
-13 | |
-14 | | *num += 1;
-15 | | });
- | |_________- within this `[closure@src/main.rs:11:36: 15:10]`
- |
- = help: within `[closure@src/main.rs:11:36: 15:10]`, the trait `Send` is not implemented for `Rc<Mutex<i32>>`
- = note: required because it appears within the type `[closure@src/main.rs:11:36: 15:10]`
+ --> src/main.rs:11:36
+ |
+11 | let handle = thread::spawn(move || {
+ | ------------- ^------
+ | | |
+ | ______________________|_____________within this `[closure@src/main.rs:11:36: 11:43]`
+ | | |
+ | | required by a bound introduced by this call
+12 | | let mut num = counter.lock().unwrap();
+13 | |
+14 | | *num += 1;
+15 | | });
+ | |_________^ `Rc<Mutex<i32>>` cannot be sent between threads safely
+ |
+ = help: within `[closure@src/main.rs:11:36: 11:43]`, the trait `Send` is not implemented for `Rc<Mutex<i32>>`
+note: required because it's used within this closure
+ --> src/main.rs:11:36
+ |
+11 | let handle = thread::spawn(move || {
+ | ^^^^^^^
note: required by a bound in `spawn`
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/doc/book/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt b/src/doc/book/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt
index f7be53b9a..301a9a44a 100644
--- a/src/doc/book/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt
+++ b/src/doc/book/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt
@@ -5,7 +5,7 @@ error[E0382]: use of moved value: `v`
|
4 | let v = vec![1, 2, 3];
| - move occurs because `v` has type `Vec<i32>`, which does not implement the `Copy` trait
-5 |
+5 |
6 | let handle = thread::spawn(move || {
| ------- value moved into closure here
7 | println!("Here's a vector: {:?}", v);
diff --git a/src/doc/book/listings/ch17-oop/listing-17-10/output.txt b/src/doc/book/listings/ch17-oop/listing-17-10/output.txt
index 74330fa0a..e0a455f3b 100644
--- a/src/doc/book/listings/ch17-oop/listing-17-10/output.txt
+++ b/src/doc/book/listings/ch17-oop/listing-17-10/output.txt
@@ -7,7 +7,7 @@ error[E0277]: the trait bound `String: Draw` is not satisfied
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Draw` is not implemented for `String`
|
= help: the trait `Draw` is implemented for `Button`
- = note: required for the cast to the object type `dyn Draw`
+ = note: required for the cast from `String` to the object type `dyn Draw`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `gui` due to previous error
diff --git a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-08/output.txt b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-08/output.txt
index 72274d07c..0fd5373b8 100644
--- a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-08/output.txt
+++ b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-08/output.txt
@@ -1,19 +1,19 @@
$ cargo run
Compiling patterns v0.1.0 (file:///projects/patterns)
error[E0005]: refutable pattern in local binding: `None` not covered
- --> src/main.rs:3:9
- |
-3 | let Some(x) = some_option_value;
- | ^^^^^^^ pattern `None` not covered
- |
- = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
- = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+ --> src/main.rs:3:9
+ |
+3 | let Some(x) = some_option_value;
+ | ^^^^^^^ pattern `None` not covered
+ |
+ = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+ = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Option<i32>` defined here
- = note: the matched value is of type `Option<i32>`
+ = note: the matched value is of type `Option<i32>`
help: you might want to use `if let` to ignore the variant that isn't matched
- |
-3 | let x = if let Some(x) = some_option_value { x } else { todo!() };
- | ++++++++++ ++++++++++++++++++++++
+ |
+3 | let x = if let Some(x) = some_option_value { x } else { todo!() };
+ | ++++++++++ ++++++++++++++++++++++
For more information about this error, try `rustc --explain E0005`.
error: could not compile `patterns` due to previous error
diff --git a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs
index 4ddef0aaf..a3138b227 100644
--- a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs
+++ b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs
@@ -13,15 +13,13 @@ fn main() {
println!("The Quit variant has no data to destructure.");
}
Message::Move { x, y } => {
- println!(
- "Move in the x direction {x} and in the y direction {y}"
- );
+ println!("Move in the x direction {x} and in the y direction {y}");
}
Message::Write(text) => {
println!("Text message: {text}");
}
- Message::ChangeColor(r, g, b) => println!(
- "Change the color to red {r}, green {g}, and blue {b}",
- ),
+ Message::ChangeColor(r, g, b) => {
+ println!("Change the color to red {r}, green {g}, and blue {b}",)
+ }
}
}
diff --git a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs
index 4c958601b..1e7ad5f19 100644
--- a/src/doc/book/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs
+++ b/src/doc/book/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs
@@ -17,9 +17,9 @@ fn main() {
Message::ChangeColor(Color::Rgb(r, g, b)) => {
println!("Change color to red {r}, green {g}, and blue {b}");
}
- Message::ChangeColor(Color::Hsv(h, s, v)) => println!(
- "Change color to hue {h}, saturation {s}, value {v}"
- ),
+ Message::ChangeColor(Color::Hsv(h, s, v)) => {
+ println!("Change color to hue {h}, saturation {s}, value {v}")
+ }
_ => (),
}
}
diff --git a/src/doc/book/listings/ch19-advanced-features/listing-19-20/output.txt b/src/doc/book/listings/ch19-advanced-features/listing-19-20/output.txt
index 684508245..a3b281e3f 100644
--- a/src/doc/book/listings/ch19-advanced-features/listing-19-20/output.txt
+++ b/src/doc/book/listings/ch19-advanced-features/listing-19-20/output.txt
@@ -1,12 +1,18 @@
$ cargo run
Compiling traits-example v0.1.0 (file:///projects/traits-example)
-error[E0283]: type annotations needed
+error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
--> src/main.rs:20:43
|
+2 | fn baby_name() -> String;
+ | ------------------------- `Animal::baby_name` defined here
+...
20 | println!("A baby dog is called a {}", Animal::baby_name());
- | ^^^^^^^^^^^^^^^^^ cannot infer type
+ | ^^^^^^^^^^^^^^^^^ cannot call associated function of trait
|
- = note: cannot satisfy `_: Animal`
+help: use the fully-qualified path to the only available implementation
+ |
+20 | println!("A baby dog is called a {}", <::Dog as Animal>::baby_name());
+ | +++++++++ +
-For more information about this error, try `rustc --explain E0283`.
+For more information about this error, try `rustc --explain E0790`.
error: could not compile `traits-example` due to previous error
diff --git a/src/doc/book/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt b/src/doc/book/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt
index d6fffc967..104f2cf0f 100644
--- a/src/doc/book/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt
+++ b/src/doc/book/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt
@@ -7,7 +7,7 @@ error[E0746]: return type cannot have an unboxed trait object
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
-help: use `impl Fn(i32) -> i32` as the return type, as all return paths are of type `[closure@src/lib.rs:2:5: 2:14]`, which implements `Fn(i32) -> i32`
+help: use `impl Fn(i32) -> i32` as the return type, as all return paths are of type `[closure@src/lib.rs:2:5: 2:8]`, which implements `Fn(i32) -> i32`
|
1 | fn returns_closure() -> impl Fn(i32) -> i32 {
| ~~~~~~~~~~~~~~~~~~~
diff --git a/src/doc/book/listings/ch20-web-server/listing-20-22/output.txt b/src/doc/book/listings/ch20-web-server/listing-20-22/output.txt
index 4402092e9..a6c9e8d3b 100644
--- a/src/doc/book/listings/ch20-web-server/listing-20-22/output.txt
+++ b/src/doc/book/listings/ch20-web-server/listing-20-22/output.txt
@@ -1,13 +1,13 @@
$ cargo check
Checking hello v0.1.0 (file:///projects/hello)
error[E0507]: cannot move out of `worker.thread` which is behind a mutable reference
- --> src/lib.rs:52:13
- |
-52 | worker.thread.join().unwrap();
- | ^^^^^^^^^^^^^ ------ `worker.thread` moved due to this method call
- | |
- | move occurs because `worker.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait
- |
+ --> src/lib.rs:52:13
+ |
+52 | worker.thread.join().unwrap();
+ | ^^^^^^^^^^^^^ ------ `worker.thread` moved due to this method call
+ | |
+ | move occurs because `worker.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait
+ |
note: this function takes ownership of the receiver `self`, which moves `worker.thread`
For more information about this error, try `rustc --explain E0507`.
diff --git a/src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt b/src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt
index 34d30fe05..e4c0eeb2a 100644
--- a/src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt
+++ b/src/doc/book/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt
@@ -5,6 +5,12 @@ error[E0599]: no method named `join` found for enum `Option` in the current scop
|
52 | worker.thread.join().unwrap();
| ^^^^ method not found in `Option<JoinHandle<()>>`
+ |
+note: the method `join` exists on the type `JoinHandle<()>`
+help: consider using `Option::expect` to unwrap the `JoinHandle<()>` value, panicking if the value is an `Option::None`
+ |
+52 | worker.thread.expect("REASON").join().unwrap();
+ | +++++++++++++++++
error[E0308]: mismatched types
--> src/lib.rs:72:22
diff --git a/src/doc/book/rust-toolchain b/src/doc/book/rust-toolchain
index 0a03ace41..5b6cd6b3c 100644
--- a/src/doc/book/rust-toolchain
+++ b/src/doc/book/rust-toolchain
@@ -1 +1 @@
-1.62
+1.65
diff --git a/src/doc/book/src/ch05-00-structs.md b/src/doc/book/src/ch05-00-structs.md
index ff540b77d..d41482579 100644
--- a/src/doc/book/src/ch05-00-structs.md
+++ b/src/doc/book/src/ch05-00-structs.md
@@ -11,4 +11,4 @@ We’ll demonstrate how to define and instantiate structs. We’ll discuss how t
define associated functions, especially the kind of associated functions called
*methods*, to specify behavior associated with a struct type. Structs and enums
(discussed in Chapter 6) are the building blocks for creating new types in your
-program’s domain to take full advantage of Rust’s compile time type checking.
+program’s domain to take full advantage of Rust’s compile-time type checking.
diff --git a/src/doc/book/src/ch05-01-defining-structs.md b/src/doc/book/src/ch05-01-defining-structs.md
index 7a50f99a5..d258d89cc 100644
--- a/src/doc/book/src/ch05-01-defining-structs.md
+++ b/src/doc/book/src/ch05-01-defining-structs.md
@@ -13,6 +13,8 @@ grouped together. Then, inside curly brackets, we define the names and types of
the pieces of data, which we call *fields*. For example, Listing 5-1 shows a
struct that stores information about a user account.
+<span class="filename">Filename: src/main.rs</span>
+
```rust
{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs:here}}
```
@@ -21,14 +23,16 @@ struct that stores information about a user account.
To use a struct after we’ve defined it, we create an *instance* of that struct
by specifying concrete values for each of the fields. We create an instance by
-stating the name of the struct and then add curly brackets containing `key:
-value` pairs, where the keys are the names of the fields and the values are the
+stating the name of the struct and then add curly brackets containing *key:
+value* pairs, where the keys are the names of the fields and the values are the
data we want to store in those fields. We don’t have to specify the fields in
the same order in which we declared them in the struct. In other words, the
struct definition is like a general template for the type, and instances fill
in that template with particular data to create values of the type. For
example, we can declare a particular user as shown in Listing 5-2.
+<span class="filename">Filename: src/main.rs</span>
+
```rust
{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs:here}}
```
@@ -42,6 +46,8 @@ mutable, we can change a value by using the dot notation and assigning into a
particular field. Listing 5-3 shows how to change the value in the `email`
field of a mutable `User` instance.
+<span class="filename">Filename: src/main.rs</span>
+
```rust
{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs:here}}
```
@@ -58,6 +64,8 @@ Listing 5-4 shows a `build_user` function that returns a `User` instance with
the given email and username. The `active` field gets the value of `true`, and
the `sign_in_count` gets a value of `1`.
+<span class="filename">Filename: src/main.rs</span>
+
```rust
{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs:here}}
```
@@ -70,20 +78,24 @@ fields, but having to repeat the `email` and `username` field names and
variables is a bit tedious. If the struct had more fields, repeating each name
would get even more annoying. Luckily, there’s a convenient shorthand!
+<!-- Old heading. Do not remove or links may break. -->
<a id="using-the-field-init-shorthand-when-variables-and-fields-have-the-same-name"></a>
+
### Using the Field Init Shorthand
Because the parameter names and the struct field names are exactly the same in
Listing 5-4, we can use the *field init shorthand* syntax to rewrite
-`build_user` so that it behaves exactly the same but doesn’t have the
-repetition of `email` and `username`, as shown in Listing 5-5.
+`build_user` so it behaves exactly the same but doesn’t have the repetition of
+`username` and `email`, as shown in Listing 5-5.
+
+<span class="filename">Filename: src/main.rs</span>
```rust
{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs:here}}
```
<span class="caption">Listing 5-5: A `build_user` function that uses field init
-shorthand because the `email` and `username` parameters have the same name as
+shorthand because the `username` and `email` parameters have the same name as
struct fields</span>
Here, we’re creating a new instance of the `User` struct, which has a field
@@ -92,7 +104,7 @@ named `email`. We want to set the `email` field’s value to the value in the
the `email` parameter have the same name, we only need to write `email` rather
than `email: email`.
-### Creating Instances From Other Instances With Struct Update Syntax
+### Creating Instances from Other Instances with Struct Update Syntax
It’s often useful to create a new instance of a struct that includes most of
the values from another instance, but changes some. You can do this using
@@ -102,6 +114,8 @@ First, in Listing 5-6 we show how to create a new `User` instance in `user2`
regularly, without the update syntax. We set a new value for `email` but
otherwise use the same values from `user1` that we created in Listing 5-2.
+<span class="filename">Filename: src/main.rs</span>
+
```rust
{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs:here}}
```
@@ -113,12 +127,14 @@ Using struct update syntax, we can achieve the same effect with less code, as
shown in Listing 5-7. The syntax `..` specifies that the remaining fields not
explicitly set should have the same value as the fields in the given instance.
+<span class="filename">Filename: src/main.rs</span>
+
```rust
{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs:here}}
```
<span class="caption">Listing 5-7: Using struct update syntax to set a new
-`email` value for a `User` instance but use the rest of the values from
+`email` value for a `User` instance but to use the rest of the values from
`user1`</span>
The code in Listing 5-7 also creates an instance in `user2` that has a
@@ -129,35 +145,37 @@ corresponding fields in `user1`, but we can choose to specify values for as
many fields as we want in any order, regardless of the order of the fields in
the struct’s definition.
-Note that the struct update syntax uses `=` like an assignment; this is
-because it moves the data, just as we saw in the [“Ways Variables and Data
-Interact: Moveâ€][move]<!-- ignore --> section. In this example, we can no
-longer use `user1` after creating `user2` because the `String` in the
+Note that the struct update syntax uses `=` like an assignment; this is because
+it moves the data, just as we saw in the [“Variables and Data Interacting with
+Moveâ€][move]<!-- ignore --> section. In this example, we can no longer use
+`user1` as a whole after creating `user2` because the `String` in the
`username` field of `user1` was moved into `user2`. If we had given `user2` new
`String` values for both `email` and `username`, and thus only used the
`active` and `sign_in_count` values from `user1`, then `user1` would still be
-valid after creating `user2`. The types of `active` and `sign_in_count` are
-types that implement the `Copy` trait, so the behavior we discussed in the
-[“Stack-Only Data: Copyâ€][copy]<!-- ignore --> section would apply.
+valid after creating `user2`. Both `active` and `sign_in_count` are types that
+implement the `Copy` trait, so the behavior we discussed in the [“Stack-Only
+Data: Copyâ€][copy]<!-- ignore --> section would apply.
-### Using Tuple Structs without Named Fields to Create Different Types
+### Using Tuple Structs Without Named Fields to Create Different Types
-Rust also supports structs that look similar to tuples, called *tuple
-structs*. Tuple structs have the added meaning the struct name provides but
-don’t have names associated with their fields; rather, they just have the types
-of the fields. Tuple structs are useful when you want to give the whole tuple a
-name and make the tuple a different type from other tuples, and when naming each
+Rust also supports structs that look similar to tuples, called *tuple structs*.
+Tuple structs have the added meaning the struct name provides but don’t have
+names associated with their fields; rather, they just have the types of the
+fields. Tuple structs are useful when you want to give the whole tuple a name
+and make the tuple a different type from other tuples, and when naming each
field as in a regular struct would be verbose or redundant.
To define a tuple struct, start with the `struct` keyword and the struct name
-followed by the types in the tuple. For example, here we define and use
-two tuple structs named `Color` and `Point`:
+followed by the types in the tuple. For example, here we define and use two
+tuple structs named `Color` and `Point`:
+
+<span class="filename">Filename: src/main.rs</span>
```rust
{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs}}
```
-Note that the `black` and `origin` values are different types, because they’re
+Note that the `black` and `origin` values are different types because they’re
instances of different tuple structs. Each struct you define is its own type,
even though the fields within the struct might have the same types. For
example, a function that takes a parameter of type `Color` cannot take a
@@ -176,12 +194,14 @@ have any data that you want to store in the type itself. We’ll discuss traits
in Chapter 10. Here’s an example of declaring and instantiating a unit struct
named `AlwaysEqual`:
+<span class="filename">Filename: src/main.rs</span>
+
```rust
{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/src/main.rs}}
```
-To define `AlwaysEqual`, we use the `struct` keyword, the name we want, then a
-semicolon. No need for curly brackets or parentheses! Then we can get an
+To define `AlwaysEqual`, we use the `struct` keyword, the name we want, and
+then a semicolon. No need for curly brackets or parentheses! Then we can get an
instance of `AlwaysEqual` in the `subject` variable in a similar way: using the
name we defined, without any curly brackets or parentheses. Imagine that later
we’ll implement behavior for this type such that every instance of
@@ -217,9 +237,9 @@ implement them on any type, including unit-like structs.
>
> fn main() {
> let user1 = User {
-> email: "someone@example.com",
-> username: "someusername123",
> active: true,
+> username: "someusername123",
+> email: "someone@example.com",
> sign_in_count: 1,
> };
> }
@@ -273,5 +293,5 @@ paste above
add `> ` before every line -->
[tuples]: ch03-02-data-types.html#the-tuple-type
-[move]: ch04-01-what-is-ownership.html#ways-variables-and-data-interact-move
+[move]: ch04-01-what-is-ownership.html#variables-and-data-interacting-with-move
[copy]: ch04-01-what-is-ownership.html#stack-only-data-copy
diff --git a/src/doc/book/src/ch05-02-example-structs.md b/src/doc/book/src/ch05-02-example-structs.md
index 5d33d9cb1..b2416b743 100644
--- a/src/doc/book/src/ch05-02-example-structs.md
+++ b/src/doc/book/src/ch05-02-example-structs.md
@@ -82,8 +82,8 @@ parts, as shown in Listing 5-10.
Here we’ve defined a struct and named it `Rectangle`. Inside the curly
brackets, we defined the fields as `width` and `height`, both of which have
-type `u32`. Then in `main`, we created a particular instance of `Rectangle`
-that has a width of 30 and a height of 50.
+type `u32`. Then, in `main`, we created a particular instance of `Rectangle`
+that has a width of `30` and a height of `50`.
Our `area` function is now defined with one parameter, which we’ve named
`rectangle`, whose type is an immutable borrow of a struct `Rectangle`
@@ -126,7 +126,7 @@ When we compile this code, we get an error with this core message:
The `println!` macro can do many kinds of formatting, and by default, the curly
brackets tell `println!` to use formatting known as `Display`: output intended
for direct end user consumption. The primitive types we’ve seen so far
-implement `Display` by default, because there’s only one way you’d want to show
+implement `Display` by default because there’s only one way you’d want to show
a `1` or any other primitive type to a user. But with structs, the way
`println!` should format the output is less clear because there are more
display possibilities: Do you want commas or not? Do you want to print the
@@ -182,8 +182,8 @@ following output:
Nice! It’s not the prettiest output, but it shows the values of all the fields
for this instance, which would definitely help during debugging. When we have
larger structs, it’s useful to have output that’s a bit easier to read; in
-those cases, we can use `{:#?}` instead of `{:?}` in the `println!` string.
-In this example, using the `{:#?}` style will output:
+those cases, we can use `{:#?}` instead of `{:?}` in the `println!` string. In
+this example, using the `{:#?}` style will output the following:
```console
{{#include ../listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/output.txt}}
@@ -191,15 +191,15 @@ In this example, using the `{:#?}` style will output:
Another way to print out a value using the `Debug` format is to use the [`dbg!`
macro][dbg]<!-- ignore -->, which takes ownership of an expression (as opposed
-to `println!` that takes a reference), prints the file and line number of where
-that `dbg!` macro call occurs in your code along with the resulting value of
-that expression, and returns ownership of the value.
+to `println!`, which takes a reference), prints the file and line number of
+where that `dbg!` macro call occurs in your code along with the resultant value
+of that expression, and returns ownership of the value.
> Note: Calling the `dbg!` macro prints to the standard error console stream
-> (`stderr`), as opposed to `println!` which prints to the standard output
+> (`stderr`), as opposed to `println!`, which prints to the standard output
> console stream (`stdout`). We’ll talk more about `stderr` and `stdout` in the
-> [“Writing Error Messages to Standard Error Instead of Standard
-> Output†section in Chapter 12][err]<!-- ignore -->.
+> [“Writing Error Messages to Standard Error Instead of Standard Outputâ€
+> section in Chapter 12][err]<!-- ignore -->.
Here’s an example where we’re interested in the value that gets assigned to the
`width` field, as well as the value of the whole struct in `rect1`:
@@ -218,8 +218,8 @@ Here’s what the output of this example looks like:
{{#include ../listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/output.txt}}
```
-We can see the first bit of output came from *src/main.rs* line 10, where we’re
-debugging the expression `30 * scale`, and its resulting value is 60 (the
+We can see the first bit of output came from *src/main.rs* line 10 where we’re
+debugging the expression `30 * scale`, and its resultant value is `60` (the
`Debug` formatting implemented for integers is to print only their value). The
`dbg!` call on line 14 of *src/main.rs* outputs the value of `&rect1`, which is
the `Rectangle` struct. This output uses the pretty `Debug` formatting of the
@@ -235,10 +235,10 @@ attributes other than `derive`; for more information, see [the “Attributesâ€
section of the Rust Reference][attributes].
Our `area` function is very specific: it only computes the area of rectangles.
-It would be helpful to tie this behavior more closely to our `Rectangle`
-struct, because it won’t work with any other type. Let’s look at how we can
-continue to refactor this code by turning the `area` function into an `area`
-*method* defined on our `Rectangle` type.
+It would be helpful to tie this behavior more closely to our `Rectangle` struct
+because it won’t work with any other type. Let’s look at how we can continue to
+refactor this code by turning the `area` function into an `area` *method*
+defined on our `Rectangle` type.
[the-tuple-type]: ch03-02-data-types.html#the-tuple-type
[app-c]: appendix-03-derivable-traits.md
diff --git a/src/doc/book/src/ch05-03-method-syntax.md b/src/doc/book/src/ch05-03-method-syntax.md
index e300d0104..d25e55b18 100644
--- a/src/doc/book/src/ch05-03-method-syntax.md
+++ b/src/doc/book/src/ch05-03-method-syntax.md
@@ -4,9 +4,10 @@
name, they can have parameters and a return value, and they contain some code
that’s run when the method is called from somewhere else. Unlike functions,
methods are defined within the context of a struct (or an enum or a trait
-object, which we cover in Chapters 6 and 17, respectively), and their first
-parameter is always `self`, which represents the instance of the struct the
-method is being called on.
+object, which we cover in [Chapter 6][enums]<!-- ignore --> and [Chapter
+17][trait-objects]<!-- ignore -->, respectively), and their first parameter is
+always `self`, which represents the instance of the struct the method is being
+called on.
### Defining Methods
@@ -39,28 +40,30 @@ type `Self` is an alias for the type that the `impl` block is for. Methods must
have a parameter named `self` of type `Self` for their first parameter, so Rust
lets you abbreviate this with only the name `self` in the first parameter spot.
Note that we still need to use the `&` in front of the `self` shorthand to
-indicate this method borrows the `Self` instance, just as we did in `rectangle:
-&Rectangle`. Methods can take ownership of `self`, borrow `self` immutably as
-we’ve done here, or borrow `self` mutably, just as they can any other parameter.
-
-We’ve chosen `&self` here for the same reason we used `&Rectangle` in the
-function version: we don’t want to take ownership, and we just want to read the
-data in the struct, not write to it. If we wanted to change the instance that
-we’ve called the method on as part of what the method does, we’d use `&mut
-self` as the first parameter. Having a method that takes ownership of the
-instance by using just `self` as the first parameter is rare; this technique is
-usually used when the method transforms `self` into something else and you want
-to prevent the caller from using the original instance after the transformation.
-
-The main reason for using methods instead of functions, in addition to providing
-method syntax and not having to repeat the type of `self` in every method’s
-signature, is for organization. We’ve put all the things we can do with an
-instance of a type in one `impl` block rather than making future users of our
-code search for capabilities of `Rectangle` in various places in the library we
-provide.
+indicate that this method borrows the `Self` instance, just as we did in
+`rectangle: &Rectangle`. Methods can take ownership of `self`, borrow `self`
+immutably, as we’ve done here, or borrow `self` mutably, just as they can any
+other parameter.
+
+We chose `&self` here for the same reason we used `&Rectangle` in the function
+version: we don’t want to take ownership, and we just want to read the data in
+the struct, not write to it. If we wanted to change the instance that we’ve
+called the method on as part of what the method does, we’d use `&mut self` as
+the first parameter. Having a method that takes ownership of the instance by
+using just `self` as the first parameter is rare; this technique is usually
+used when the method transforms `self` into something else and you want to
+prevent the caller from using the original instance after the transformation.
+
+The main reason for using methods instead of functions, in addition to
+providing method syntax and not having to repeat the type of `self` in every
+method’s signature, is for organization. We’ve put all the things we can do
+with an instance of a type in one `impl` block rather than making future users
+of our code search for capabilities of `Rectangle` in various places in the
+library we provide.
Note that we can choose to give a method the same name as one of the struct’s
-fields. For example, we can define a method on `Rectangle` also named `width`:
+fields. For example, we can define a method on `Rectangle` that is also named
+`width`:
<span class="filename">Filename: src/main.rs</span>
@@ -69,19 +72,20 @@ fields. For example, we can define a method on `Rectangle` also named `width`:
```
Here, we’re choosing to make the `width` method return `true` if the value in
-the instance’s `width` field is greater than 0, and `false` if the value is 0:
-we can use a field within a method of the same name for any purpose. In `main`,
-when we follow `rect1.width` with parentheses, Rust knows we mean the method
-`width`. When we don’t use parentheses, Rust knows we mean the field `width`.
-
-Often, but not always, when we give methods with the same name as a field we
-want it to only return the value in the field and do nothing else. Methods like
-this are called *getters*, and Rust does not implement them automatically for
-struct fields as some other languages do. Getters are useful because you can
-make the field private but the method public and thus enable read-only access
-to that field as part of the type’s public API. We will be discussing what
-public and private are and how to designate a field or method as public or
-private in Chapter 7.
+the instance’s `width` field is greater than `0` and `false` if the value is
+`0`: we can use a field within a method of the same name for any purpose. In
+`main`, when we follow `rect1.width` with parentheses, Rust knows we mean the
+method `width`. When we don’t use parentheses, Rust knows we mean the field
+`width`.
+
+Often, but not always, when we give a method the same name as a field we want
+it to only return the value in the field and do nothing else. Methods like this
+are called *getters*, and Rust does not implement them automatically for struct
+fields as some other languages do. Getters are useful because you can make the
+field private but the method public, and thus enable read-only access to that
+field as part of the type’s public API. We will discuss what public and private
+are and how to designate a field or method as public or private in [Chapter
+7][public]<!-- ignore -->.
> ### Where’s the `->` Operator?
>
@@ -131,11 +135,11 @@ private in Chapter 7.
### Methods with More Parameters
Let’s practice using methods by implementing a second method on the `Rectangle`
-struct. This time, we want an instance of `Rectangle` to take another instance
+struct. This time we want an instance of `Rectangle` to take another instance
of `Rectangle` and return `true` if the second `Rectangle` can fit completely
-within `self` (the first `Rectangle`); otherwise it should return `false`. That
-is, once we’ve defined the `can_hold` method, we want to be able to write the
-program shown in Listing 5-14.
+within `self` (the first `Rectangle`); otherwise, it should return `false`.
+That is, once we’ve defined the `can_hold` method, we want to be able to write
+the program shown in Listing 5-14.
<span class="filename">Filename: src/main.rs</span>
@@ -146,8 +150,8 @@ program shown in Listing 5-14.
<span class="caption">Listing 5-14: Using the as-yet-unwritten `can_hold`
method</span>
-And the expected output would look like the following, because both dimensions
-of `rect2` are smaller than the dimensions of `rect1` but `rect3` is wider than
+The expected output would look like the following because both dimensions of
+`rect2` are smaller than the dimensions of `rect1`, but `rect3` is wider than
`rect1`:
```text
@@ -165,7 +169,7 @@ read `rect2` (rather than write, which would mean we’d need a mutable borrow),
and we want `main` to retain ownership of `rect2` so we can use it again after
calling the `can_hold` method. The return value of `can_hold` will be a
Boolean, and the implementation will check whether the width and height of
-`self` are both greater than the width and height of the other `Rectangle`,
+`self` are greater than the width and height of the other `Rectangle`,
respectively. Let’s add the new `can_hold` method to the `impl` block from
Listing 5-13, shown in Listing 5-15.
@@ -213,13 +217,14 @@ is `Rectangle`.
To call this associated function, we use the `::` syntax with the struct name;
`let sq = Rectangle::square(3);` is an example. This function is namespaced by
the struct: the `::` syntax is used for both associated functions and
-namespaces created by modules. We’ll discuss modules in Chapter 7.
+namespaces created by modules. We’ll discuss modules in [Chapter
+7][modules]<!-- ignore -->.
### Multiple `impl` Blocks
Each struct is allowed to have multiple `impl` blocks. For example, Listing
-5-15 is equivalent to the code shown in Listing 5-16, which has each method
-in its own `impl` block.
+5-15 is equivalent to the code shown in Listing 5-16, which has each method in
+its own `impl` block.
```rust
{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs:here}}
@@ -243,3 +248,8 @@ structs have.
But structs aren’t the only way you can create custom types: let’s turn to
Rust’s enum feature to add another tool to your toolbox.
+
+[enums]: ch06-00-enums.html
+[trait-objects]: ch17-02-trait-objects.md
+[public]: ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html#exposing-paths-with-the-pub-keyword
+[modules]: ch07-02-defining-modules-to-control-scope-and-privacy.html
diff --git a/src/doc/book/src/ch06-00-enums.md b/src/doc/book/src/ch06-00-enums.md
index e207aa7bd..8a7faa9f3 100644
--- a/src/doc/book/src/ch06-00-enums.md
+++ b/src/doc/book/src/ch06-00-enums.md
@@ -1,7 +1,7 @@
# Enums and Pattern Matching
-In this chapter we’ll look at *enumerations*, also referred to as *enums*.
-Enums allow you to define a type by enumerating its possible *variants*. First,
+In this chapter, we’ll look at *enumerations*, also referred to as *enums*.
+Enums allow you to define a type by enumerating its possible *variants*. First
we’ll define and use an enum to show how an enum can encode meaning along with
data. Next, we’ll explore a particularly useful enum, called `Option`, which
expresses that a value can be either something or nothing. Then we’ll look at
diff --git a/src/doc/book/src/ch06-01-defining-an-enum.md b/src/doc/book/src/ch06-01-defining-an-enum.md
index cb5d73097..eacd091bd 100644
--- a/src/doc/book/src/ch06-01-defining-an-enum.md
+++ b/src/doc/book/src/ch06-01-defining-an-enum.md
@@ -15,7 +15,7 @@ variants, which is where enumeration gets its name.
Any IP address can be either a version four or a version six address, but not
both at the same time. That property of IP addresses makes the enum data
-structure appropriate, because an enum value can only be one of its variants.
+structure appropriate because an enum value can only be one of its variants.
Both version four and version six addresses are still fundamentally IP
addresses, so they should be treated as the same type when the code is handling
situations that apply to any kind of IP address.
@@ -85,7 +85,7 @@ variants will have associated `String` values:
```
We attach data to each variant of the enum directly, so there is no need for an
-extra struct. Here it’s also easier to see another detail of how enums work:
+extra struct. Here, it’s also easier to see another detail of how enums work:
the name of each enum variant that we define also becomes a function that
constructs an instance of the enum. That is, `IpAddr::V4()` is a function call
that takes a `String` argument and returns an instance of the `IpAddr` type. We
@@ -93,7 +93,7 @@ automatically get this constructor function defined as a result of defining the
enum.
There’s another advantage to using an enum rather than a struct: each variant
-can have different types and amounts of associated data. Version four type IP
+can have different types and amounts of associated data. Version four IP
addresses will always have four numeric components that will have values
between 0 and 255. If we wanted to store `V4` addresses as four `u8` values but
still express `V6` addresses as one `String` value, we wouldn’t be able to with
@@ -150,7 +150,7 @@ different amounts and types of values</span>
This enum has four variants with different types:
* `Quit` has no data associated with it at all.
-* `Move` has named fields like a struct does.
+* `Move` has named fields, like a struct does.
* `Write` includes a single `String`.
* `ChangeColor` includes three `i32` values.
@@ -164,7 +164,7 @@ variants hold:
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs:here}}
```
-But if we used the different structs, which each have their own type, we
+But if we used the different structs, each of which has its own type, we
couldn’t as easily define a function to take any of these kinds of messages as
we could with the `Message` enum defined in Listing 6-2, which is a single type.
@@ -190,8 +190,8 @@ This section explores a case study of `Option`, which is another enum defined
by the standard library. The `Option` type encodes the very common scenario in
which a value could be something or it could be nothing.
-For example, if you request the first of a list containing items, you would get
-a value. If you request the first item of an empty list, you would get nothing.
+For example, if you request the first item in a non-empty list, you would get
+a value. If you request the first item in an empty list, you would get nothing.
Expressing this concept in terms of the type system means the compiler can
check whether you’ve handled all the cases you should be handling; this
functionality can prevent bugs that are extremely common in other programming
@@ -243,11 +243,11 @@ prefix. The `Option<T>` enum is still just a regular enum, and `Some(T)` and
The `<T>` syntax is a feature of Rust we haven’t talked about yet. It’s a
generic type parameter, and we’ll cover generics in more detail in Chapter 10.
-For now, all you need to know is that `<T>` means the `Some` variant of the
-`Option` enum can hold one piece of data of any type, and that each concrete
-type that gets used in place of `T` makes the overall `Option<T>` type a
-different type. Here are some examples of using `Option` values to hold number
-types and string types:
+For now, all you need to know is that `<T>` means that the `Some` variant of
+the `Option` enum can hold one piece of data of any type, and that each
+concrete type that gets used in place of `T` makes the overall `Option<T>` type
+a different type. Here are some examples of using `Option` values to hold
+number types and string types:
```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs:here}}
@@ -262,20 +262,20 @@ type that the corresponding `Some` variant will hold by looking only at a
`Option<i32>`.
When we have a `Some` value, we know that a value is present and the value is
-held within the `Some`. When we have a `None` value, in some sense, it means
-the same thing as null: we don’t have a valid value. So why is having
-`Option<T>` any better than having null?
+held within the `Some`. When we have a `None` value, in some sense it means the
+same thing as null: we don’t have a valid value. So why is having `Option<T>`
+any better than having null?
In short, because `Option<T>` and `T` (where `T` can be any type) are different
types, the compiler won’t let us use an `Option<T>` value as if it were
-definitely a valid value. For example, this code won’t compile because it’s
+definitely a valid value. For example, this code won’t compile, because it’s
trying to add an `i8` to an `Option<i8>`:
```rust,ignore,does_not_compile
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/src/main.rs:here}}
```
-If we run this code, we get an error message like this:
+If we run this code, we get an error message like this one:
```console
{{#include ../listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt}}
@@ -292,8 +292,7 @@ using the value.
In other words, you have to convert an `Option<T>` to a `T` before you can
perform `T` operations with it. Generally, this helps catch one of the most
-common issues with null: assuming that something isn’t null when it actually
-is.
+common issues with null: assuming that something isn’t null when it actually is.
Eliminating the risk of incorrectly assuming a not-null value helps you to be
more confident in your code. In order to have a value that can possibly be
@@ -304,20 +303,21 @@ when the value is null. Everywhere that a value has a type that isn’t an
deliberate design decision for Rust to limit null’s pervasiveness and increase
the safety of Rust code.
-So, how do you get the `T` value out of a `Some` variant when you have a value
-of type `Option<T>` so you can use that value? The `Option<T>` enum has a large
-number of methods that are useful in a variety of situations; you can check
-them out in [its documentation][docs]<!-- ignore -->. Becoming familiar with
-the methods on `Option<T>` will be extremely useful in your journey with Rust.
+So how do you get the `T` value out of a `Some` variant when you have a value
+of type `Option<T>` so that you can use that value? The `Option<T>` enum has a
+large number of methods that are useful in a variety of situations; you can
+check them out in [its documentation][docs]<!-- ignore -->. Becoming familiar
+with the methods on `Option<T>` will be extremely useful in your journey with
+Rust.
In general, in order to use an `Option<T>` value, you want to have code that
will handle each variant. You want some code that will run only when you have a
`Some(T)` value, and this code is allowed to use the inner `T`. You want some
-other code to run if you have a `None` value, and that code doesn’t have a `T`
-value available. The `match` expression is a control flow construct that does
-just this when used with enums: it will run different code depending on which
-variant of the enum it has, and that code can use the data inside the matching
-value.
+other code to run only if you have a `None` value, and that code doesn’t have a
+`T` value available. The `match` expression is a control flow construct that
+does just this when used with enums: it will run different code depending on
+which variant of the enum it has, and that code can use the data inside the
+matching value.
[IpAddr]: ../std/net/enum.IpAddr.html
[option]: ../std/option/enum.Option.html
diff --git a/src/doc/book/src/ch06-02-match.md b/src/doc/book/src/ch06-02-match.md
index 2dfe6c34b..6a510df40 100644
--- a/src/doc/book/src/ch06-02-match.md
+++ b/src/doc/book/src/ch06-02-match.md
@@ -1,13 +1,15 @@
+<!-- Old heading. Do not remove or links may break. -->
<a id="the-match-control-flow-operator"></a>
## The `match` Control Flow Construct
-Rust has an extremely powerful control flow construct called `match` that allows
-you to compare a value against a series of patterns and then execute code based
-on which pattern matches. Patterns can be made up of literal values, variable
-names, wildcards, and many other things; Chapter 18 covers all the different
-kinds of patterns and what they do. The power of `match` comes from the
-expressiveness of the patterns and the fact that the compiler confirms that all
-possible cases are handled.
+Rust has an extremely powerful control flow construct called `match` that
+allows you to compare a value against a series of patterns and then execute
+code based on which pattern matches. Patterns can be made up of literal values,
+variable names, wildcards, and many other things; [Chapter
+18][ch18-00-patterns]<!-- ignore --> covers all the different kinds of patterns
+and what they do. The power of `match` comes from the expressiveness of the
+patterns and the fact that the compiler confirms that all possible cases are
+handled.
Think of a `match` expression as being like a coin-sorting machine: coins slide
down a track with variously sized holes along it, and each coin falls through
@@ -16,9 +18,9 @@ through each pattern in a `match`, and at the first pattern the value “fits,â€
the value falls into the associated code block to be used during execution.
Speaking of coins, let’s use them as an example using `match`! We can write a
-function that takes an unknown United States coin and, in a similar way as the
-counting machine, determines which coin it is and returns its value in cents, as
-shown here in Listing 6-3.
+function that takes an unknown US coin and, in a similar way as the counting
+machine, determines which coin it is and returns its value in cents, as shown
+in Listing 6-3.
```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs:here}}
@@ -27,25 +29,25 @@ shown here in Listing 6-3.
<span class="caption">Listing 6-3: An enum and a `match` expression that has
the variants of the enum as its patterns</span>
-Let’s break down the `match` in the `value_in_cents` function. First, we list
+Let’s break down the `match` in the `value_in_cents` function. First we list
the `match` keyword followed by an expression, which in this case is the value
-`coin`. This seems very similar to an expression used with `if`, but there’s a
-big difference: with `if`, the expression needs to return a Boolean value, but
-here, it can return any type. The type of `coin` in this example is the `Coin`
-enum that we defined on the first line.
+`coin`. This seems very similar to a conditional expression used with `if`, but
+there’s a big difference: with `if`, the condition needs to evaluate to a
+Boolean value, but here it can be any type. The type of `coin` in this example
+is the `Coin` enum that we defined on the first line.
Next are the `match` arms. An arm has two parts: a pattern and some code. The
first arm here has a pattern that is the value `Coin::Penny` and then the `=>`
operator that separates the pattern and the code to run. The code in this case
is just the value `1`. Each arm is separated from the next with a comma.
-When the `match` expression executes, it compares the resulting value against
+When the `match` expression executes, it compares the resultant value against
the pattern of each arm, in order. If a pattern matches the value, the code
associated with that pattern is executed. If that pattern doesn’t match the
value, execution continues to the next arm, much as in a coin-sorting machine.
We can have as many arms as we need: in Listing 6-3, our `match` has four arms.
-The code associated with each arm is an expression, and the resulting value of
+The code associated with each arm is an expression, and the resultant value of
the expression in the matching arm is the value that gets returned for the
entire `match` expression.
@@ -60,7 +62,7 @@ returns the last value of the block, `1`:
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs:here}}
```
-### Patterns that Bind to Values
+### Patterns That Bind to Values
Another useful feature of match arms is that they can bind to the parts of the
values that match the pattern. This is how we can extract values out of enum
@@ -70,8 +72,8 @@ As an example, let’s change one of our enum variants to hold data inside it.
From 1999 through 2008, the United States minted quarters with different
designs for each of the 50 states on one side. No other coins got state
designs, so only quarters have this extra value. We can add this information to
-our `enum` by changing the `Quarter` variant to include a `UsState` value stored
-inside it, which we’ve done here in Listing 6-4.
+our `enum` by changing the `Quarter` variant to include a `UsState` value
+stored inside it, which we’ve done in Listing 6-4.
```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs:here}}
@@ -82,8 +84,8 @@ also holds a `UsState` value</span>
Let’s imagine that a friend is trying to collect all 50 state quarters. While
we sort our loose change by coin type, we’ll also call out the name of the
-state associated with each quarter so if it’s one our friend doesn’t have, they
-can add it to their collection.
+state associated with each quarter so that if it’s one our friend doesn’t have,
+they can add it to their collection.
In the match expression for this code, we add a variable called `state` to the
pattern that matches values of the variant `Coin::Quarter`. When a
@@ -104,10 +106,10 @@ state value out of the `Coin` enum variant for `Quarter`.
### Matching with `Option<T>`
In the previous section, we wanted to get the inner `T` value out of the `Some`
-case when using `Option<T>`; we can also handle `Option<T>` using `match` as we
-did with the `Coin` enum! Instead of comparing coins, we’ll compare the
-variants of `Option<T>`, but the way that the `match` expression works remains
-the same.
+case when using `Option<T>`; we can also handle `Option<T>` using `match`, as
+we did with the `Coin` enum! Instead of comparing coins, we’ll compare the
+variants of `Option<T>`, but the way the `match` expression works remains the
+same.
Let’s say we want to write a function that takes an `Option<i32>` and, if
there’s a value inside, adds 1 to that value. If there isn’t a value inside,
@@ -126,26 +128,26 @@ an `Option<i32>`</span>
Let’s examine the first execution of `plus_one` in more detail. When we call
`plus_one(five)`, the variable `x` in the body of `plus_one` will have the
-value `Some(5)`. We then compare that against each match arm.
+value `Some(5)`. We then compare that against each match arm:
```rust,ignore
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:first_arm}}
```
The `Some(5)` value doesn’t match the pattern `None`, so we continue to the
-next arm.
+next arm:
```rust,ignore
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:second_arm}}
```
-Does `Some(5)` match `Some(i)`? Why yes it does! We have the same variant. The
-`i` binds to the value contained in `Some`, so `i` takes the value `5`. The
-code in the match arm is then executed, so we add 1 to the value of `i` and
-create a new `Some` value with our total `6` inside.
+Does `Some(5)` match `Some(i)`? It does! We have the same variant. The `i`
+binds to the value contained in `Some`, so `i` takes the value `5`. The code in
+the match arm is then executed, so we add 1 to the value of `i` and create a
+new `Some` value with our total `6` inside.
Now let’s consider the second call of `plus_one` in Listing 6-5, where `x` is
-`None`. We enter the `match` and compare to the first arm.
+`None`. We enter the `match` and compare to the first arm:
```rust,ignore
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:first_arm}}
@@ -179,7 +181,7 @@ error:
{{#include ../listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt}}
```
-Rust knows that we didn’t cover every possible case and even knows which
+Rust knows that we didn’t cover every possible case, and even knows which
pattern we forgot! Matches in Rust are *exhaustive*: we must exhaust every last
possibility in order for the code to be valid. Especially in the case of
`Option<T>`, when Rust prevents us from forgetting to explicitly handle the
@@ -202,10 +204,10 @@ this example:
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs:here}}
```
-For the first two arms, the patterns are the literal values 3 and 7. For the
-last arm that covers every other possible value, the pattern is the variable
-we’ve chosen to name `other`. The code that runs for the `other` arm uses the
-variable by passing it to the `move_player` function.
+For the first two arms, the patterns are the literal values `3` and `7`. For
+the last arm that covers every other possible value, the pattern is the
+variable we’ve chosen to name `other`. The code that runs for the `other` arm
+uses the variable by passing it to the `move_player` function.
This code compiles, even though we haven’t listed all the possible values a
`u8` can have, because the last pattern will match all values not specifically
@@ -230,7 +232,7 @@ can change our code to use `_` instead of the variable named `other`:
This example also meets the exhaustiveness requirement because we’re explicitly
ignoring all other values in the last arm; we haven’t forgotten anything.
-Finally, we’ll change the rules of the game one more time, so that nothing else
+Finally, we’ll change the rules of the game one more time so that nothing else
happens on your turn if you roll anything other than a 3 or a 7. We can express
that by using the unit value (the empty tuple type we mentioned in [“The Tuple
Typeâ€][tuples]<!-- ignore --> section) as the code that goes with the `_` arm:
diff --git a/src/doc/book/src/ch06-03-if-let.md b/src/doc/book/src/ch06-03-if-let.md
index 07634e162..c9bfbf3c7 100644
--- a/src/doc/book/src/ch06-03-if-let.md
+++ b/src/doc/book/src/ch06-03-if-let.md
@@ -2,8 +2,9 @@
The `if let` syntax lets you combine `if` and `let` into a less verbose way to
handle values that match one pattern while ignoring the rest. Consider the
-program in Listing 6-6 that matches on an `Option<u8>` value in the `config_max`
-variable but only wants to execute code if the value is the `Some` variant.
+program in Listing 6-6 that matches on an `Option<u8>` value in the
+`config_max` variable but only wants to execute code if the value is the `Some`
+variant.
```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-06/src/main.rs:here}}
@@ -29,7 +30,7 @@ The syntax `if let` takes a pattern and an expression separated by an equal
sign. It works the same way as a `match`, where the expression is given to the
`match` and the pattern is its first arm. In this case, the pattern is
`Some(max)`, and the `max` binds to the value inside the `Some`. We can then
-use `max` in the body of the `if let` block in the same way as we used `max` in
+use `max` in the body of the `if let` block in the same way we used `max` in
the corresponding `match` arm. The code in the `if let` block isn’t run if the
value doesn’t match the pattern.
@@ -48,13 +49,13 @@ We can include an `else` with an `if let`. The block of code that goes with the
`Coin` enum definition in Listing 6-4, where the `Quarter` variant also held a
`UsState` value. If we wanted to count all non-quarter coins we see while also
announcing the state of the quarters, we could do that with a `match`
-expression like this:
+expression, like this:
```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/src/main.rs:here}}
```
-Or we could use an `if let` and `else` expression like this:
+Or we could use an `if let` and `else` expression, like this:
```rust
{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/src/main.rs:here}}
@@ -73,9 +74,10 @@ values, depending on how many cases you need to handle.
Your Rust programs can now express concepts in your domain using structs and
enums. Creating custom types to use in your API ensures type safety: the
-compiler will make certain your functions get only values of the type each
+compiler will make certain your functions only get values of the type each
function expects.
In order to provide a well-organized API to your users that is straightforward
to use and only exposes exactly what your users will need, let’s now turn to
Rust’s modules.
+
diff --git a/src/doc/book/src/title-page.md b/src/doc/book/src/title-page.md
index ed55a6839..12d1a6598 100644
--- a/src/doc/book/src/title-page.md
+++ b/src/doc/book/src/title-page.md
@@ -2,7 +2,7 @@
*by Steve Klabnik and Carol Nichols, with contributions from the Rust Community*
-This version of the text assumes you’re using Rust 1.62 (released 2022-06-30)
+This version of the text assumes you’re using Rust 1.65 (released 2022-11-03)
or later. See the [“Installation†section of Chapter 1][install]<!-- ignore -->
to install or update Rust.
diff --git a/src/doc/embedded-book/src/intro/install/linux.md b/src/doc/embedded-book/src/intro/install/linux.md
index f8684d0a8..1c0b0edfa 100644
--- a/src/doc/embedded-book/src/intro/install/linux.md
+++ b/src/doc/embedded-book/src/intro/install/linux.md
@@ -39,16 +39,13 @@ sudo apt install gdb-arm-none-eabi openocd qemu-system-arm
- Fedora 27 or newer
-> **NOTE** `arm-none-eabi-gdb` is the GDB command you'll use to debug your ARM
-> Cortex-M programs
-
<!-- Fedora 27 -->
<!-- GDB 7.6 (!) -->
<!-- OpenOCD 0.10.0 -->
<!-- QEMU 2.10.2 -->
``` console
-sudo dnf install arm-none-eabi-gdb openocd qemu-system-arm
+sudo dnf install gdb openocd qemu-system-arm
```
- Arch Linux
diff --git a/src/doc/embedded-book/src/intro/no-std.md b/src/doc/embedded-book/src/intro/no-std.md
index 35bfc1adc..93aadf65d 100644
--- a/src/doc/embedded-book/src/intro/no-std.md
+++ b/src/doc/embedded-book/src/intro/no-std.md
@@ -47,7 +47,7 @@ bootstrapping (stage 0) code like bootloaders, firmware or kernels.
| feature | no\_std | std |
|-----------------------------------------------------------|--------|-----|
| heap (dynamic memory) | * | ✓ |
-| collections (Vec, HashMap, etc) | ** | ✓ |
+| collections (Vec, BTreeMap, etc) | ** | ✓ |
| stack overflow protection | ✘ | ✓ |
| runs init code before main | ✘ | ✓ |
| libstd available | ✘ | ✓ |
@@ -58,6 +58,8 @@ bootstrapping (stage 0) code like bootloaders, firmware or kernels.
\** Only if you use the `collections` crate and configure a global default allocator.
+\** HashMap and HashSet are not available due to a lack of a secure random number generator.
+
[alloc-cortex-m]: https://github.com/rust-embedded/alloc-cortex-m
## See Also
diff --git a/src/doc/embedded-book/src/peripherals/singletons.md b/src/doc/embedded-book/src/peripherals/singletons.md
index 840a98665..3f04aa170 100644
--- a/src/doc/embedded-book/src/peripherals/singletons.md
+++ b/src/doc/embedded-book/src/peripherals/singletons.md
@@ -25,7 +25,7 @@ But this has a few problems. It is a mutable global variable, and in Rust, these
## How do we do this in Rust?
-Instead of just making our peripheral a global variable, we might instead decide to make a global variable, in this case called `PERIPHERALS`, which contains an `Option<T>` for each of our peripherals.
+Instead of just making our peripheral a global variable, we might instead decide to make a structure, in this case called `PERIPHERALS`, which contains an `Option<T>` for each of our peripherals.
```rust,ignore
struct Peripherals {
diff --git a/src/doc/embedded-book/src/start/hardware.md b/src/doc/embedded-book/src/start/hardware.md
index f1eee3163..8166e62e5 100644
--- a/src/doc/embedded-book/src/start/hardware.md
+++ b/src/doc/embedded-book/src/start/hardware.md
@@ -272,7 +272,7 @@ Quit anyway? (y or n)
```
Debugging now requires a few more steps so we have packed all those steps into a
-single GDB script named `openocd.gdb`. The file was created during the `cargo generate` step, and should work without any modifications. Let's have a peak:
+single GDB script named `openocd.gdb`. The file was created during the `cargo generate` step, and should work without any modifications. Let's have a peek:
``` console
cat openocd.gdb
diff --git a/src/doc/nomicon/src/lifetime-mismatch.md b/src/doc/nomicon/src/lifetime-mismatch.md
index 1da2d285c..bc53f06f8 100644
--- a/src/doc/nomicon/src/lifetime-mismatch.md
+++ b/src/doc/nomicon/src/lifetime-mismatch.md
@@ -74,7 +74,7 @@ care about, but the lifetime system is too coarse-grained to handle that.
## Improperly reduced borrows
The following code fails to compile, because Rust sees that a variable, `map`,
-is borrowed twice, and can not infer that the first borrow stops to be needed
+is borrowed twice, and can not infer that the first borrow ceases to be needed
before the second one occurs. This is caused by Rust conservatively falling back
to using a whole scope for the first borrow. This will eventually get fixed.
diff --git a/src/doc/nomicon/src/unchecked-uninit.md b/src/doc/nomicon/src/unchecked-uninit.md
index c61415c97..b3dd31cf1 100644
--- a/src/doc/nomicon/src/unchecked-uninit.md
+++ b/src/doc/nomicon/src/unchecked-uninit.md
@@ -11,7 +11,7 @@ Unsafe Rust gives us a powerful tool to handle this problem:
[`MaybeUninit`]. This type can be used to handle memory that has not been fully
initialized yet.
-With `MaybeUninit`, we can initialize an array element-for-element as follows:
+With `MaybeUninit`, we can initialize an array element by element as follows:
```rust
use std::mem::{self, MaybeUninit};
@@ -79,8 +79,7 @@ This code proceeds in three steps:
acknowledge that by providing appropriate methods).
It's worth spending a bit more time on the loop in the middle, and in particular
-the assignment operator and its interaction with `drop`. If we would have
-written something like:
+the assignment operator and its interaction with `drop`. If we wrote something like:
<!-- ignore: simplified code -->
```rust,ignore
@@ -88,7 +87,7 @@ written something like:
```
we would actually overwrite a `Box<u32>`, leading to `drop` of uninitialized
-data, which will cause much sadness and pain.
+data, which would cause much sadness and pain.
The correct alternative, if for some reason we cannot use `MaybeUninit::new`, is
to use the [`ptr`] module. In particular, it provides three functions that allow
@@ -97,7 +96,7 @@ us to assign bytes to a location in memory without dropping the old value:
* `ptr::write(ptr, val)` takes a `val` and moves it into the address pointed
to by `ptr`.
-* `ptr::copy(src, dest, count)` copies the bits that `count` T's would occupy
+* `ptr::copy(src, dest, count)` copies the bits that `count` T items would occupy
from src to dest. (this is equivalent to C's memmove -- note that the argument
order is reversed!)
* `ptr::copy_nonoverlapping(src, dest, count)` does what `copy` does, but a
@@ -105,8 +104,8 @@ us to assign bytes to a location in memory without dropping the old value:
(this is equivalent to C's memcpy -- note that the argument order is reversed!)
It should go without saying that these functions, if misused, will cause serious
-havoc or just straight up Undefined Behavior. The only things that these
-functions *themselves* require is that the locations you want to read and write
+havoc or just straight up Undefined Behavior. The only requirement of these
+functions *themselves* is that the locations you want to read and write
are allocated and properly aligned. However, the ways writing arbitrary bits to
arbitrary locations of memory can break things are basically uncountable!
diff --git a/src/doc/nomicon/src/vec/vec-alloc.md b/src/doc/nomicon/src/vec/vec-alloc.md
index 6c69c9379..249547339 100644
--- a/src/doc/nomicon/src/vec/vec-alloc.md
+++ b/src/doc/nomicon/src/vec/vec-alloc.md
@@ -28,7 +28,6 @@ impl<T> Vec<T> {
ptr: NonNull::dangling(),
len: 0,
cap: 0,
- _marker: PhantomData,
}
}
}
diff --git a/src/doc/nomicon/src/vec/vec-final.md b/src/doc/nomicon/src/vec/vec-final.md
index 1f8af37ad..696391d10 100644
--- a/src/doc/nomicon/src/vec/vec-final.md
+++ b/src/doc/nomicon/src/vec/vec-final.md
@@ -10,7 +10,6 @@ use std::ptr::{self, NonNull};
struct RawVec<T> {
ptr: NonNull<T>,
cap: usize,
- _marker: PhantomData<T>,
}
unsafe impl<T: Send> Send for RawVec<T> {}
@@ -25,7 +24,6 @@ impl<T> RawVec<T> {
RawVec {
ptr: NonNull::dangling(),
cap: cap,
- _marker: PhantomData,
}
}
diff --git a/src/doc/nomicon/src/vec/vec-insert-remove.md b/src/doc/nomicon/src/vec/vec-insert-remove.md
index 57283f990..722e20c45 100644
--- a/src/doc/nomicon/src/vec/vec-insert-remove.md
+++ b/src/doc/nomicon/src/vec/vec-insert-remove.md
@@ -22,9 +22,11 @@ pub fn insert(&mut self, index: usize, elem: T) {
unsafe {
// ptr::copy(src, dest, len): "copy from src to dest len elems"
- ptr::copy(self.ptr.as_ptr().add(index),
- self.ptr.as_ptr().add(index + 1),
- self.len - index);
+ ptr::copy(
+ self.ptr.as_ptr().add(index),
+ self.ptr.as_ptr().add(index + 1),
+ self.len - index,
+ );
ptr::write(self.ptr.as_ptr().add(index), elem);
self.len += 1;
}
@@ -42,9 +44,11 @@ pub fn remove(&mut self, index: usize) -> T {
unsafe {
self.len -= 1;
let result = ptr::read(self.ptr.as_ptr().add(index));
- ptr::copy(self.ptr.as_ptr().add(index + 1),
- self.ptr.as_ptr().add(index),
- self.len - index);
+ ptr::copy(
+ self.ptr.as_ptr().add(index + 1),
+ self.ptr.as_ptr().add(index),
+ self.len - index,
+ );
result
}
}
diff --git a/src/doc/nomicon/src/vec/vec-into-iter.md b/src/doc/nomicon/src/vec/vec-into-iter.md
index 61782e3b8..a3a3c8cb9 100644
--- a/src/doc/nomicon/src/vec/vec-into-iter.md
+++ b/src/doc/nomicon/src/vec/vec-into-iter.md
@@ -49,7 +49,6 @@ pub struct IntoIter<T> {
cap: usize,
start: *const T,
end: *const T,
- _marker: PhantomData<T>,
}
```
@@ -61,13 +60,13 @@ impl<T> IntoIterator for Vec<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
- // Can't destructure Vec since it's Drop
- let ptr = self.ptr;
- let cap = self.cap;
- let len = self.len;
-
// Make sure not to drop Vec since that would free the buffer
- mem::forget(self);
+ let vec = ManuallyDrop::new(self);
+
+ // Can't destructure Vec since it's Drop
+ let ptr = vec.ptr;
+ let cap = vec.cap;
+ let len = vec.len;
unsafe {
IntoIter {
@@ -80,7 +79,6 @@ impl<T> IntoIterator for Vec<T> {
} else {
ptr.as_ptr().add(len)
},
- _marker: PhantomData,
}
}
}
diff --git a/src/doc/nomicon/src/vec/vec-layout.md b/src/doc/nomicon/src/vec/vec-layout.md
index c1c1afcc7..9129952a5 100644
--- a/src/doc/nomicon/src/vec/vec-layout.md
+++ b/src/doc/nomicon/src/vec/vec-layout.md
@@ -15,13 +15,10 @@ pub struct Vec<T> {
}
```
-And indeed this would compile. Unfortunately, it would be incorrect. First, the
+And indeed this would compile. Unfortunately, it would be too strict. The
compiler will give us too strict variance. So a `&Vec<&'static str>`
-couldn't be used where an `&Vec<&'a str>` was expected. More importantly, it
-will give incorrect ownership information to the drop checker, as it will
-conservatively assume we don't own any values of type `T`. See [the chapter
-on ownership and lifetimes][ownership] for all the details on variance and
-drop check.
+couldn't be used where a `&Vec<&'a str>` was expected. See [the chapter
+on ownership and lifetimes][ownership] for all the details on variance.
As we saw in the ownership chapter, the standard library uses `Unique<T>` in place of
`*mut T` when it has a raw pointer to an allocation that it owns. Unique is unstable,
@@ -30,16 +27,16 @@ so we'd like to not use it if possible, though.
As a recap, Unique is a wrapper around a raw pointer that declares that:
* We are covariant over `T`
-* We may own a value of type `T` (for drop check)
+* We may own a value of type `T` (this is not relevant for our example here, but see
+ [the chapter on PhantomData][phantom-data] on why the real `std::vec::Vec<T>` needs this)
* We are Send/Sync if `T` is Send/Sync
* Our pointer is never null (so `Option<Vec<T>>` is null-pointer-optimized)
We can implement all of the above requirements in stable Rust. To do this, instead
of using `Unique<T>` we will use [`NonNull<T>`][NonNull], another wrapper around a
raw pointer, which gives us two of the above properties, namely it is covariant
-over `T` and is declared to never be null. By adding a `PhantomData<T>` (for drop
-check) and implementing Send/Sync if `T` is, we get the same results as using
-`Unique<T>`:
+over `T` and is declared to never be null. By implementing Send/Sync if `T` is,
+we get the same results as using `Unique<T>`:
```rust
use std::ptr::NonNull;
@@ -49,7 +46,6 @@ pub struct Vec<T> {
ptr: NonNull<T>,
cap: usize,
len: usize,
- _marker: PhantomData<T>,
}
unsafe impl<T: Send> Send for Vec<T> {}
@@ -58,4 +54,5 @@ unsafe impl<T: Sync> Sync for Vec<T> {}
```
[ownership]: ../ownership.html
+[phantom-data]: ../phantom-data.md
[NonNull]: ../../std/ptr/struct.NonNull.html
diff --git a/src/doc/nomicon/src/vec/vec-raw.md b/src/doc/nomicon/src/vec/vec-raw.md
index e86537b81..728feaa58 100644
--- a/src/doc/nomicon/src/vec/vec-raw.md
+++ b/src/doc/nomicon/src/vec/vec-raw.md
@@ -13,7 +13,6 @@ allocating, growing, and freeing:
struct RawVec<T> {
ptr: NonNull<T>,
cap: usize,
- _marker: PhantomData<T>,
}
unsafe impl<T: Send> Send for RawVec<T> {}
@@ -25,7 +24,6 @@ impl<T> RawVec<T> {
RawVec {
ptr: NonNull::dangling(),
cap: 0,
- _marker: PhantomData,
}
}
diff --git a/src/doc/nomicon/src/vec/vec-zsts.md b/src/doc/nomicon/src/vec/vec-zsts.md
index 73a97ba49..8f2529727 100644
--- a/src/doc/nomicon/src/vec/vec-zsts.md
+++ b/src/doc/nomicon/src/vec/vec-zsts.md
@@ -33,14 +33,13 @@ method of `RawVec`.
```rust,ignore
impl<T> RawVec<T> {
fn new() -> Self {
- // !0 is usize::MAX. This branch should be stripped at compile time.
- let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
+ // This branch should be stripped at compile time.
+ let cap = if mem::size_of::<T>() == 0 { usize::MAX } else { 0 };
// `NonNull::dangling()` doubles as "unallocated" and "zero-sized allocation"
RawVec {
ptr: NonNull::dangling(),
cap: cap,
- _marker: PhantomData,
}
}
diff --git a/src/doc/reference/src/attributes.md b/src/doc/reference/src/attributes.md
index b7c1ef609..5d619c990 100644
--- a/src/doc/reference/src/attributes.md
+++ b/src/doc/reference/src/attributes.md
@@ -248,6 +248,7 @@ The following is an index of all built-in attributes.
- [`no_builtins`] — Disables use of certain built-in functions.
- [`target_feature`] — Configure platform-specific code generation.
- [`track_caller`] - Pass the parent call location to `std::panic::Location::caller()`.
+ - [`instruction_set`] - Specify the instruction set used to generate a functions code
- Documentation
- `doc` — Specifies documentation. See [The Rustdoc Book] for more
information. [Doc comments] are transformed into `doc` attributes.
@@ -298,6 +299,7 @@ The following is an index of all built-in attributes.
[`global_allocator`]: runtime.md#the-global_allocator-attribute
[`ignore`]: attributes/testing.md#the-ignore-attribute
[`inline`]: attributes/codegen.md#the-inline-attribute
+[`instruction_set`]: attributes/codegen.md#the-instruction_set-attribute
[`link_name`]: items/external-blocks.md#the-link_name-attribute
[`link_ordinal`]: items/external-blocks.md#the-link_ordinal-attribute
[`link_section`]: abi.md#the-link_section-attribute
diff --git a/src/doc/reference/src/attributes/codegen.md b/src/doc/reference/src/attributes/codegen.md
index 3a36a10ca..69ad341d1 100644
--- a/src/doc/reference/src/attributes/codegen.md
+++ b/src/doc/reference/src/attributes/codegen.md
@@ -352,3 +352,26 @@ trait object whose methods are attributed.
[`core::intrinsics::caller_location`]: ../../core/intrinsics/fn.caller_location.html
[`core::panic::Location::caller`]: ../../core/panic/struct.Location.html#method.caller
[`Location`]: ../../core/panic/struct.Location.html
+
+## The `instruction_set` attribute
+
+The *`instruction_set` attribute* may be applied to a function to enable code generation for a specific
+instruction set supported by the target architecture. It uses the [_MetaListPath_] syntax and a path
+comprised of the architecture and instruction set to specify how to generate the code for
+architectures where a single program may utilize multiple instruction sets.
+
+The following values are available on targets for the `ARMv4` and `ARMv5te` architectures:
+
+* `arm::a32` - Uses ARM code.
+* `arm::t32` - Uses Thumb code.
+
+<!-- ignore: arm-only -->
+```rust,ignore
+#[instruction_set(arm::a32)]
+fn foo_arm_code() {}
+
+#[instruction_set(arm::t32)]
+fn bar_thumb_code() {}
+```
+
+[_MetaListPath_]: ../attributes.md#meta-item-attribute-syntax
diff --git a/src/doc/reference/src/behavior-considered-undefined.md b/src/doc/reference/src/behavior-considered-undefined.md
index e810e8c0d..f8bffd13e 100644
--- a/src/doc/reference/src/behavior-considered-undefined.md
+++ b/src/doc/reference/src/behavior-considered-undefined.md
@@ -26,8 +26,22 @@ code.
* Evaluating a [dereference expression] (`*expr`) on a raw pointer that is
[dangling] or unaligned, even in [place expression context]
(e.g. `addr_of!(&*expr)`).
-* Breaking the [pointer aliasing rules]. `&mut T` and `&T` follow LLVM’s scoped
- [noalias] model, except if the `&T` contains an [`UnsafeCell<U>`].
+* Breaking the [pointer aliasing rules]. `Box<T>`, `&mut T` and `&T` follow
+ LLVM’s scoped [noalias] model, except if the `&T` contains an
+ [`UnsafeCell<U>`]. References and boxes must not be [dangling] while they are
+ live. The exact liveness duration is not specified, but some bounds exist:
+ * For references, the liveness duration is upper-bounded by the syntactic
+ lifetime assigned by the borrow checker; it cannot be live any *longer* than
+ that lifetime.
+ * Each time a reference or box is passed to or returned from a function, it is
+ considered live.
+ * When a reference (but not a `Box`!) is passed to a function, it is live at
+ least as long as that function call, again except if the `&T` contains an
+ [`UnsafeCell<U>`].
+
+ All this also applies when values of these
+ types are passed in a (nested) field of a compound type, but not behind
+ pointer indirections.
* Mutating immutable data. All data inside a [`const`] item is immutable. Moreover, all
data reached through a shared reference or data owned by an immutable binding
is immutable, unless that data is contained within an [`UnsafeCell<U>`].
diff --git a/src/doc/reference/src/comments.md b/src/doc/reference/src/comments.md
index 46074b45c..ad29c58e5 100644
--- a/src/doc/reference/src/comments.md
+++ b/src/doc/reference/src/comments.md
@@ -2,7 +2,7 @@
> **<sup>Lexer</sup>**\
> LINE_COMMENT :\
-> &nbsp;&nbsp; &nbsp;&nbsp; `//` (~\[`/` `!`] | `//`) ~`\n`<sup>\*</sup>\
+> &nbsp;&nbsp; &nbsp;&nbsp; `//` (~\[`/` `!` `\n`] | `//`) ~`\n`<sup>\*</sup>\
> &nbsp;&nbsp; | `//`
>
> BLOCK_COMMENT :\
diff --git a/src/doc/reference/src/expressions/literal-expr.md b/src/doc/reference/src/expressions/literal-expr.md
index 4eec37dcb..e5bc2dff4 100644
--- a/src/doc/reference/src/expressions/literal-expr.md
+++ b/src/doc/reference/src/expressions/literal-expr.md
@@ -8,11 +8,9 @@
> &nbsp;&nbsp; | [BYTE_LITERAL]\
> &nbsp;&nbsp; | [BYTE_STRING_LITERAL]\
> &nbsp;&nbsp; | [RAW_BYTE_STRING_LITERAL]\
-> &nbsp;&nbsp; | [INTEGER_LITERAL][^out-of-range]\
+> &nbsp;&nbsp; | [INTEGER_LITERAL]\
> &nbsp;&nbsp; | [FLOAT_LITERAL]\
> &nbsp;&nbsp; | `true` | `false`
->
-> [^out-of-range]: A value ≥ 2<sup>128</sup> is not allowed.
A _literal expression_ is an expression consisting of a single token, rather than a sequence of tokens, that immediately and directly denotes the value it evaluates to, rather than referring to it by name or some other evaluation rule.
@@ -54,7 +52,7 @@ A string literal expression consists of a single [BYTE_STRING_LITERAL] or [RAW_B
An integer literal expression consists of a single [INTEGER_LITERAL] token.
-If the token has a [suffix], the suffix will be the name of one of the [primitive integer types][numeric types]: `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`, `usize`, or `isize`, and the expression has that type.
+If the token has a [suffix], the suffix must be the name of one of the [primitive integer types][numeric types]: `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`, `usize`, or `isize`, and the expression has that type.
If the token has no suffix, the expression's type is determined by type inference:
@@ -96,10 +94,12 @@ The value of the expression is determined from the string representation of the
* If the radix is not 10, the first two characters are removed from the string.
+* Any suffix is removed from the string.
+
* Any underscores are removed from the string.
* The string is converted to a `u128` value as if by [`u128::from_str_radix`] with the chosen radix.
-If the value does not fit in `u128`, the expression is rejected by the parser.
+If the value does not fit in `u128`, it is a compiler error.
* The `u128` value is converted to the expression's type via a [numeric cast].
@@ -111,9 +111,11 @@ If the value does not fit in `u128`, the expression is rejected by the parser.
## Floating-point literal expressions
-A floating-point literal expression consists of a single [FLOAT_LITERAL] token.
+A floating-point literal expression has one of two forms:
+ * a single [FLOAT_LITERAL] token
+ * a single [INTEGER_LITERAL] token which has a suffix and no radix indicator
-If the token has a [suffix], the suffix will be the name of one of the [primitive floating-point types][floating-point types]: `f32` or `f64`, and the expression has that type.
+If the token has a [suffix], the suffix must be the name of one of the [primitive floating-point types][floating-point types]: `f32` or `f64`, and the expression has that type.
If the token has no suffix, the expression's type is determined by type inference:
@@ -136,6 +138,8 @@ let x: f64 = 2.; // type f64
The value of the expression is determined from the string representation of the token as follows:
+* Any suffix is removed from the string.
+
* Any underscores are removed from the string.
* The string is converted to the expression's type as if by [`f32::from_str`] or [`f64::from_str`].
diff --git a/src/doc/reference/src/items/extern-crates.md b/src/doc/reference/src/items/extern-crates.md
index f4dc735b0..d6b3a9aae 100644
--- a/src/doc/reference/src/items/extern-crates.md
+++ b/src/doc/reference/src/items/extern-crates.md
@@ -20,9 +20,9 @@ clause can be used to bind the imported crate to a different name.
The external crate is resolved to a specific `soname` at compile time, and a
runtime linkage requirement to that `soname` is passed to the linker for
loading at runtime. The `soname` is resolved at compile time by scanning the
-compiler's library path and matching the optional `crateid` provided against
-the `crateid` attributes that were declared on the external crate when it was
-compiled. If no `crateid` is provided, a default `name` attribute is assumed,
+compiler's library path and matching the optional `crate_name` provided against
+the [`crate_name` attributes] that were declared on the external crate when it was
+compiled. If no `crate_name` is provided, a default `name` attribute is assumed,
equal to the [identifier] given in the `extern crate` declaration.
The `self` crate may be imported which creates a binding to the current crate.
@@ -78,6 +78,7 @@ crate to access only its macros.
[`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute
[extern prelude]: ../names/preludes.md#extern-prelude
[`macro_use` prelude]: ../names/preludes.md#macro_use-prelude
+[`crate_name` attributes]: ../crates-and-source-files.md#the-crate_name-attribute
<script>
(function() {
diff --git a/src/doc/reference/src/items/external-blocks.md b/src/doc/reference/src/items/external-blocks.md
index c91e1d10c..d89536968 100644
--- a/src/doc/reference/src/items/external-blocks.md
+++ b/src/doc/reference/src/items/external-blocks.md
@@ -201,6 +201,22 @@ The default for this modifier is `-whole-archive`.
More implementation details about this modifier can be found in
[`whole-archive` documentation for rustc].
+### Linking modifiers: `verbatim`
+
+This modifier is compatible with all linking kinds.
+
+`+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes
+(like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the
+linker.
+
+`-verbatim` means that rustc will either add a target-specific prefix and suffix to the library
+name before passing it to linker, or won't prevent linker from implicitly adding it.
+
+The default for this modifier is `-verbatim`.
+
+More implementation details about this modifier can be found in
+[`verbatim` documentation for rustc].
+
#### `dylib` versus `raw-dylib`
On Windows, linking against a dynamic library requires that an import library
@@ -288,4 +304,5 @@ restrictions as [regular function parameters].
[regular function parameters]: functions.md#attributes-on-function-parameters
[`bundle` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-bundle
[`whole-archive` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive
+[`verbatim` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-verbatim
[`dylib` versus `raw-dylib`]: #dylib-versus-raw-dylib
diff --git a/src/doc/reference/src/items/generics.md b/src/doc/reference/src/items/generics.md
index 5ffcd1580..5b7170726 100644
--- a/src/doc/reference/src/items/generics.md
+++ b/src/doc/reference/src/items/generics.md
@@ -51,7 +51,7 @@ instances of the item must be instantiated with a value of the given type.
<!-- TODO: update above to say "introduces a name in the [value namespace]"
once namespaces are added. -->
-The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`, `usize`
+The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`, `usize`,
`i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `char` and `bool`.
Const parameters can be used anywhere a [const item] can be used, with the
diff --git a/src/doc/reference/src/macros-by-example.md b/src/doc/reference/src/macros-by-example.md
index 2c49300cd..cd9dc3402 100644
--- a/src/doc/reference/src/macros-by-example.md
+++ b/src/doc/reference/src/macros-by-example.md
@@ -76,6 +76,8 @@ delimiters for the matcher will match any pair of delimiters. Thus, for
instance, the matcher `(())` will match `{()}` but not `{{}}`. The character
`$` cannot be matched or transcribed literally.
+### Forwarding a matched fragment
+
When forwarding a matched fragment to another macro-by-example, matchers in
the second macro will see an opaque AST of the fragment type. The second macro
can't use literal tokens to match the fragments in the matcher, only a
diff --git a/src/doc/reference/src/special-types-and-traits.md b/src/doc/reference/src/special-types-and-traits.md
index ca53b3c9a..6355f3fb2 100644
--- a/src/doc/reference/src/special-types-and-traits.md
+++ b/src/doc/reference/src/special-types-and-traits.md
@@ -135,7 +135,7 @@ UnwindSafe>` is a valid type.
## `Sized`
The [`Sized`] trait indicates that the size of this type is known at compile-time; that is, it's not a [dynamically sized type].
-[Type parameters] are `Sized` by default, as are [associated types].
+[Type parameters] (except `Self` in traits) are `Sized` by default, as are [associated types].
`Sized` is always implemented automatically by the compiler, not by [implementation items].
These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound.
diff --git a/src/doc/reference/src/tokens.md b/src/doc/reference/src/tokens.md
index 8f9bcb1f7..0067b647d 100644
--- a/src/doc/reference/src/tokens.md
+++ b/src/doc/reference/src/tokens.md
@@ -72,13 +72,13 @@ Literals are tokens used in [literal expressions].
#### Numbers
-| [Number literals](#number-literals)`*` | Example | Exponentiation | Suffixes |
-|----------------------------------------|---------|----------------|----------|
-| Decimal integer | `98_222` | `N/A` | Integer suffixes |
-| Hex integer | `0xff` | `N/A` | Integer suffixes |
-| Octal integer | `0o77` | `N/A` | Integer suffixes |
-| Binary integer | `0b1111_0000` | `N/A` | Integer suffixes |
-| Floating-point | `123.0E+77` | `Optional` | Floating-point suffixes |
+| [Number literals](#number-literals)`*` | Example | Exponentiation |
+|----------------------------------------|---------|----------------|
+| Decimal integer | `98_222` | `N/A` |
+| Hex integer | `0xff` | `N/A` |
+| Octal integer | `0o77` | `N/A` |
+| Binary integer | `0b1111_0000` | `N/A` |
+| Floating-point | `123.0E+77` | `Optional` |
`*` All number literals allow `_` as a visual separator: `1_234.0E+18f64`
@@ -86,17 +86,26 @@ Literals are tokens used in [literal expressions].
A suffix is a sequence of characters following the primary part of a literal (without intervening whitespace), of the same form as a non-raw identifier or keyword.
-Any kind of literal (string, integer, etc) with any suffix is valid as a token,
-and can be passed to a macro without producing an error.
+
+> **<sup>Lexer</sup>**\
+> SUFFIX : IDENTIFIER_OR_KEYWORD\
+> SUFFIX_NO_E : SUFFIX <sub>_not beginning with `e` or `E`_</sub>
+
+Any kind of literal (string, integer, etc) with any suffix is valid as a token.
+
+A literal token with any suffix can be passed to a macro without producing an error.
The macro itself will decide how to interpret such a token and whether to produce an error or not.
+In particular, the `literal` fragment specifier for by-example macros matches literal tokens with arbitrary suffixes.
```rust
macro_rules! blackhole { ($tt:tt) => () }
+macro_rules! blackhole_lit { ($l:literal) => () }
blackhole!("string"suffix); // OK
+blackhole_lit!(1suffix); // OK
```
-However, suffixes on literal tokens parsed as Rust code are restricted.
+However, suffixes on literal tokens which are interpreted as literal expressions or patterns are restricted.
Any suffixes are rejected on non-numeric literal tokens,
and numeric literal tokens are accepted only with suffixes from the list below.
@@ -110,7 +119,7 @@ and numeric literal tokens are accepted only with suffixes from the list below.
> **<sup>Lexer</sup>**\
> CHAR_LITERAL :\
-> &nbsp;&nbsp; `'` ( ~\[`'` `\` \\n \\r \\t] | QUOTE_ESCAPE | ASCII_ESCAPE | UNICODE_ESCAPE ) `'`
+> &nbsp;&nbsp; `'` ( ~\[`'` `\` \\n \\r \\t] | QUOTE_ESCAPE | ASCII_ESCAPE | UNICODE_ESCAPE ) `'` SUFFIX<sup>?</sup>
>
> QUOTE_ESCAPE :\
> &nbsp;&nbsp; `\'` | `\"`
@@ -136,7 +145,7 @@ which must be _escaped_ by a preceding `U+005C` character (`\`).
> &nbsp;&nbsp; &nbsp;&nbsp; | ASCII_ESCAPE\
> &nbsp;&nbsp; &nbsp;&nbsp; | UNICODE_ESCAPE\
> &nbsp;&nbsp; &nbsp;&nbsp; | STRING_CONTINUE\
-> &nbsp;&nbsp; )<sup>\*</sup> `"`
+> &nbsp;&nbsp; )<sup>\*</sup> `"` SUFFIX<sup>?</sup>
>
> STRING_CONTINUE :\
> &nbsp;&nbsp; `\` _followed by_ \\n
@@ -196,7 +205,7 @@ following forms:
> **<sup>Lexer</sup>**\
> RAW_STRING_LITERAL :\
-> &nbsp;&nbsp; `r` RAW_STRING_CONTENT
+> &nbsp;&nbsp; `r` RAW_STRING_CONTENT SUFFIX<sup>?</sup>
>
> RAW_STRING_CONTENT :\
> &nbsp;&nbsp; &nbsp;&nbsp; `"` ( ~ _IsolatedCR_ )<sup>* (non-greedy)</sup> `"`\
@@ -233,7 +242,7 @@ r##"foo #"# bar"##; // foo #"# bar
> **<sup>Lexer</sup>**\
> BYTE_LITERAL :\
-> &nbsp;&nbsp; `b'` ( ASCII_FOR_CHAR | BYTE_ESCAPE ) `'`
+> &nbsp;&nbsp; `b'` ( ASCII_FOR_CHAR | BYTE_ESCAPE ) `'` SUFFIX<sup>?</sup>
>
> ASCII_FOR_CHAR :\
> &nbsp;&nbsp; _any ASCII (i.e. 0x00 to 0x7F), except_ `'`, `\`, \\n, \\r or \\t
@@ -253,7 +262,7 @@ _number literal_.
> **<sup>Lexer</sup>**\
> BYTE_STRING_LITERAL :\
-> &nbsp;&nbsp; `b"` ( ASCII_FOR_STRING | BYTE_ESCAPE | STRING_CONTINUE )<sup>\*</sup> `"`
+> &nbsp;&nbsp; `b"` ( ASCII_FOR_STRING | BYTE_ESCAPE | STRING_CONTINUE )<sup>\*</sup> `"` SUFFIX<sup>?</sup>
>
> ASCII_FOR_STRING :\
> &nbsp;&nbsp; _any ASCII (i.e 0x00 to 0x7F), except_ `"`, `\` _and IsolatedCR_
@@ -284,7 +293,7 @@ following forms:
> **<sup>Lexer</sup>**\
> RAW_BYTE_STRING_LITERAL :\
-> &nbsp;&nbsp; `br` RAW_BYTE_STRING_CONTENT
+> &nbsp;&nbsp; `br` RAW_BYTE_STRING_CONTENT SUFFIX<sup>?</sup>
>
> RAW_BYTE_STRING_CONTENT :\
> &nbsp;&nbsp; &nbsp;&nbsp; `"` ASCII<sup>* (non-greedy)</sup> `"`\
@@ -329,7 +338,7 @@ literal_. The grammar for recognizing the two kinds of literals is mixed.
> **<sup>Lexer</sup>**\
> INTEGER_LITERAL :\
> &nbsp;&nbsp; ( DEC_LITERAL | BIN_LITERAL | OCT_LITERAL | HEX_LITERAL )
-> INTEGER_SUFFIX<sup>?</sup>
+> SUFFIX_NO_E<sup>?</sup>
>
> DEC_LITERAL :\
> &nbsp;&nbsp; DEC_DIGIT (DEC_DIGIT|`_`)<sup>\*</sup>
@@ -350,10 +359,6 @@ literal_. The grammar for recognizing the two kinds of literals is mixed.
> DEC_DIGIT : \[`0`-`9`]
>
> HEX_DIGIT : \[`0`-`9` `a`-`f` `A`-`F`]
->
-> INTEGER_SUFFIX :\
-> &nbsp;&nbsp; &nbsp;&nbsp; `u8` | `u16` | `u32` | `u64` | `u128` | `usize`\
-> &nbsp;&nbsp; | `i8` | `i16` | `i32` | `i64` | `i128` | `isize`
An _integer literal_ has one of four forms:
@@ -369,11 +374,11 @@ An _integer literal_ has one of four forms:
(`0b`) and continues as any mixture (with at least one digit) of binary digits
and underscores.
-Like any literal, an integer literal may be followed (immediately, without any spaces) by an _integer suffix_, which must be the name of one of the [primitive integer types][numeric types]:
-`u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`, `usize`, or `isize`.
+Like any literal, an integer literal may be followed (immediately, without any spaces) by a suffix as described above.
+The suffix may not begin with `e` or `E`, as that would be interpreted as the exponent of a floating-point literal.
See [literal expressions] for the effect of these suffixes.
-Examples of integer literals of various forms:
+Examples of integer literals which are accepted as literal expressions:
```rust
# #![allow(overflowing_literals)]
@@ -396,27 +401,27 @@ Examples of integer literals of various forms:
0usize;
-// These are too big for their type, but are still valid tokens
-
+// These are too big for their type, but are accepted as literal expressions.
128_i8;
256_u8;
+// This is an integer literal, accepted as a floating-point literal expression.
+5f32;
```
Note that `-1i8`, for example, is analyzed as two tokens: `-` followed by `1i8`.
-Examples of invalid integer literals:
-```rust,compile_fail
-// uses numbers of the wrong base
+Examples of integer literals which are not accepted as literal expressions:
-0b0102;
-0o0581;
-
-// bin, hex, and octal literals must have at least one digit
-
-0b_;
-0b____;
+```rust
+# #[cfg(FALSE)] {
+0invalidSuffix;
+123AFB43;
+0b010a;
+0xAB_CD_EF_GH;
+0b1111_f32;
+# }
```
#### Tuple index
@@ -442,9 +447,8 @@ let cat = example.01; // ERROR no field named `01`
let horse = example.0b10; // ERROR no field named `0b10`
```
-> **Note**: The tuple index may include an `INTEGER_SUFFIX`, but this is not
-> intended to be valid, and may be removed in a future version. See
-> <https://github.com/rust-lang/rust/issues/60210> for more information.
+> **Note**: Tuple indices may include certain suffixes, but this is not intended to be valid, and may be removed in a future version.
+> See <https://github.com/rust-lang/rust/issues/60210> for more information.
#### Floating-point literals
@@ -452,38 +456,32 @@ let horse = example.0b10; // ERROR no field named `0b10`
> FLOAT_LITERAL :\
> &nbsp;&nbsp; &nbsp;&nbsp; DEC_LITERAL `.`
> _(not immediately followed by `.`, `_` or an XID_Start character)_\
-> &nbsp;&nbsp; | DEC_LITERAL FLOAT_EXPONENT\
-> &nbsp;&nbsp; | DEC_LITERAL `.` DEC_LITERAL FLOAT_EXPONENT<sup>?</sup>\
-> &nbsp;&nbsp; | DEC_LITERAL (`.` DEC_LITERAL)<sup>?</sup>
-> FLOAT_EXPONENT<sup>?</sup> FLOAT_SUFFIX
+> &nbsp;&nbsp; | DEC_LITERAL `.` DEC_LITERAL SUFFIX_NO_E<sup>?</sup>\
+> &nbsp;&nbsp; | DEC_LITERAL (`.` DEC_LITERAL)<sup>?</sup> FLOAT_EXPONENT SUFFIX<sup>?</sup>\
>
> FLOAT_EXPONENT :\
> &nbsp;&nbsp; (`e`|`E`) (`+`|`-`)<sup>?</sup>
> (DEC_DIGIT|`_`)<sup>\*</sup> DEC_DIGIT (DEC_DIGIT|`_`)<sup>\*</sup>
>
-> FLOAT_SUFFIX :\
-> &nbsp;&nbsp; `f32` | `f64`
-A _floating-point literal_ has one of three forms:
+A _floating-point literal_ has one of two forms:
* A _decimal literal_ followed by a period character `U+002E` (`.`). This is
optionally followed by another decimal literal, with an optional _exponent_.
* A single _decimal literal_ followed by an _exponent_.
-* A single _decimal literal_ (in which case a suffix is required).
Like integer literals, a floating-point literal may be followed by a
suffix, so long as the pre-suffix part does not end with `U+002E` (`.`).
-There are two valid _floating-point suffixes_: `f32` and `f64` (the names of the 32-bit and 64-bit [primitive floating-point types][floating-point types]).
+The suffix may not begin with `e` or `E` if the literal does not include an exponent.
See [literal expressions] for the effect of these suffixes.
-Examples of floating-point literals of various forms:
+Examples of floating-point literals which are accepted as literal expressions:
```rust
123.0f64;
0.1f64;
0.1f32;
12E+99_f64;
-5f32;
let x: f64 = 2.;
```
@@ -493,39 +491,16 @@ to call a method named `f64` on `2`.
Note that `-1.0`, for example, is analyzed as two tokens: `-` followed by `1.0`.
-#### Number pseudoliterals
-
-> **<sup>Lexer</sup>**\
-> NUMBER_PSEUDOLITERAL :\
-> &nbsp;&nbsp; &nbsp;&nbsp; DEC_LITERAL ( . DEC_LITERAL )<sup>?</sup> FLOAT_EXPONENT\
-> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; ( NUMBER_PSEUDOLITERAL_SUFFIX | INTEGER_SUFFIX )\
-> &nbsp;&nbsp; | DEC_LITERAL . DEC_LITERAL\
-> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; ( NUMBER_PSEUDOLITERAL_SUFFIX_NO_E | INTEGER SUFFIX )\
-> &nbsp;&nbsp; | DEC_LITERAL NUMBER_PSEUDOLITERAL_SUFFIX_NO_E\
-> &nbsp;&nbsp; | ( BIN_LITERAL | OCT_LITERAL | HEX_LITERAL )\
-> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; ( NUMBER_PSEUDOLITERAL_SUFFIX_NO_E | FLOAT_SUFFIX )
->
-> NUMBER_PSEUDOLITERAL_SUFFIX :\
-> &nbsp;&nbsp; IDENTIFIER_OR_KEYWORD <sub>_not matching INTEGER_SUFFIX or FLOAT_SUFFIX_</sub>
->
-> NUMBER_PSEUDOLITERAL_SUFFIX_NO_E :\
-> &nbsp;&nbsp; NUMBER_PSEUDOLITERAL_SUFFIX <sub>_not beginning with `e` or `E`_</sub>
-
-Tokenization of numeric literals allows arbitrary suffixes as described in the grammar above.
-These values generate valid tokens, but are not valid [literal expressions], so are usually an error except as macro arguments.
+Examples of floating-point literals which are not accepted as literal expressions:
-Examples of such tokens:
-```rust,compile_fail
-0invalidSuffix;
-123AFB43;
-0b010a;
-0xAB_CD_EF_GH;
+```rust
+# #[cfg(FALSE)] {
2.0f80;
2e5f80;
2e5e6;
2.0e5e6;
1.3e10u64;
-0b1111_f32;
+# }
```
#### Reserved forms similar to number literals
@@ -536,7 +511,7 @@ Examples of such tokens:
> &nbsp;&nbsp; | OCT_LITERAL \[`8`-`9`&ZeroWidthSpace;]\
> &nbsp;&nbsp; | ( BIN_LITERAL | OCT_LITERAL | HEX_LITERAL ) `.` \
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; _(not immediately followed by `.`, `_` or an XID_Start character)_\
-> &nbsp;&nbsp; | ( BIN_LITERAL | OCT_LITERAL ) `e`\
+> &nbsp;&nbsp; | ( BIN_LITERAL | OCT_LITERAL ) (`e`|`E`)\
> &nbsp;&nbsp; | `0b` `_`<sup>\*</sup> _end of input or not BIN_DIGIT_\
> &nbsp;&nbsp; | `0o` `_`<sup>\*</sup> _end of input or not OCT_DIGIT_\
> &nbsp;&nbsp; | `0x` `_`<sup>\*</sup> _end of input or not HEX_DIGIT_\
@@ -549,7 +524,7 @@ Due to the possible ambiguity these raise, they are rejected by the tokenizer in
* An unsuffixed binary, octal, or hexadecimal literal followed, without intervening whitespace, by a period character (with the same restrictions on what follows the period as for floating-point literals).
-* An unsuffixed binary or octal literal followed, without intervening whitespace, by the character `e`.
+* An unsuffixed binary or octal literal followed, without intervening whitespace, by the character `e` or `E`.
* Input which begins with one of the radix prefixes but is not a valid binary, octal, or hexadecimal literal (because it contains no digits).
@@ -561,13 +536,13 @@ Examples of reserved forms:
0b0102; // this is not `0b010` followed by `2`
0o1279; // this is not `0o127` followed by `9`
0x80.0; // this is not `0x80` followed by `.` and `0`
-0b101e; // this is not a pseudoliteral, or `0b101` followed by `e`
-0b; // this is not a pseudoliteral, or `0` followed by `b`
-0b_; // this is not a pseudoliteral, or `0` followed by `b_`
-2e; // this is not a pseudoliteral, or `2` followed by `e`
-2.0e; // this is not a pseudoliteral, or `2.0` followed by `e`
-2em; // this is not a pseudoliteral, or `2` followed by `em`
-2.0em; // this is not a pseudoliteral, or `2.0` followed by `em`
+0b101e; // this is not a suffixed literal, or `0b101` followed by `e`
+0b; // this is not an integer literal, or `0` followed by `b`
+0b_; // this is not an integer literal, or `0` followed by `b_`
+2e; // this is not a floating-point literal, or `2` followed by `e`
+2.0e; // this is not a floating-point literal, or `2.0` followed by `e`
+2em; // this is not a suffixed literal, or `2` followed by `em`
+2.0em; // this is not a suffixed literal, or `2.0` followed by `em`
```
## Lifetimes and loop labels
diff --git a/src/doc/reference/src/trait-bounds.md b/src/doc/reference/src/trait-bounds.md
index f284ca4eb..c8dab3f1c 100644
--- a/src/doc/reference/src/trait-bounds.md
+++ b/src/doc/reference/src/trait-bounds.md
@@ -121,7 +121,7 @@ For example, if `'a` is an unconstrained lifetime parameter, then `i32: 'static`
> _ForLifetimes_ :\
> &nbsp;&nbsp; `for` [_GenericParams_]
-Type bounds may be *higher ranked* over lifetimes. These bounds specify a bound
+Trait bounds may be *higher ranked* over lifetimes. These bounds specify a bound
that is true *for all* lifetimes. For example, a bound such as `for<'a> &'a T:
PartialEq<i32>` would require an implementation like
diff --git a/src/doc/rust-by-example/.github/workflows/rbe.yml b/src/doc/rust-by-example/.github/workflows/rbe.yml
index 94b7cdc95..76b127b96 100644
--- a/src/doc/rust-by-example/.github/workflows/rbe.yml
+++ b/src/doc/rust-by-example/.github/workflows/rbe.yml
@@ -42,7 +42,7 @@ jobs:
sh linkcheck.sh --all rust-by-example
- name: Upload Artifact
- uses: actions/upload-artifact@v1
+ uses: actions/upload-artifact@v3
with:
name: rust-by-example
path: book
diff --git a/src/doc/rust-by-example/src/crates/using_lib.md b/src/doc/rust-by-example/src/crates/using_lib.md
index 102080700..8bd0feb94 100644
--- a/src/doc/rust-by-example/src/crates/using_lib.md
+++ b/src/doc/rust-by-example/src/crates/using_lib.md
@@ -20,7 +20,7 @@ fn main() {
```txt
# Where library.rlib is the path to the compiled library, assumed that it's
# in the same directory here:
-$ rustc executable.rs --extern rary=library.rlib --edition=2018 && ./executable
+$ rustc executable.rs --extern rary=library.rlib && ./executable
called rary's `public_function()`
called rary's `indirect_access()`, that
> called rary's `private_function()`
diff --git a/src/doc/rust-by-example/src/fn/closures.md b/src/doc/rust-by-example/src/fn/closures.md
index 0c1b999ef..82286003b 100644
--- a/src/doc/rust-by-example/src/fn/closures.md
+++ b/src/doc/rust-by-example/src/fn/closures.md
@@ -19,21 +19,23 @@ Other characteristics of closures include:
```rust,editable
fn main() {
- // Increment via closures and functions.
- fn function(i: i32) -> i32 { i + 1 }
+ let outer_var = 42;
+
+ // A regular function can't refer to variables in the enclosing environment
+ //fn function(i: i32) -> i32 { i + outer_var }
+ // TODO: uncomment the line above and see the compiler error. The compiler
+ // suggests that we define a closure instead.
// Closures are anonymous, here we are binding them to references
// Annotation is identical to function annotation but is optional
// as are the `{}` wrapping the body. These nameless functions
// are assigned to appropriately named variables.
- let closure_annotated = |i: i32| -> i32 { i + 1 };
- let closure_inferred = |i | i + 1 ;
-
- let i = 1;
- // Call the function and closures.
- println!("function: {}", function(i));
- println!("closure_annotated: {}", closure_annotated(i));
- println!("closure_inferred: {}", closure_inferred(i));
+ let closure_annotated = |i: i32| -> i32 { i + outer_var };
+ let closure_inferred = |i | i + outer_var ;
+
+ // Call the closures.
+ println!("closure_annotated: {}", closure_annotated(1));
+ println!("closure_inferred: {}", closure_inferred(1));
// Once closure's type has been inferred, it cannot be inferred again with another type.
//println!("cannot reuse closure_inferred with another type: {}", closure_inferred(42i64));
// TODO: uncomment the line above and see the compiler error.
diff --git a/src/doc/rust-by-example/src/fn/closures/input_parameters.md b/src/doc/rust-by-example/src/fn/closures/input_parameters.md
index 8f4307ff5..41497179f 100644
--- a/src/doc/rust-by-example/src/fn/closures/input_parameters.md
+++ b/src/doc/rust-by-example/src/fn/closures/input_parameters.md
@@ -22,7 +22,7 @@ closure.
This is because if a move is possible, then any type of borrow should also
be possible. Note that the reverse is not true. If the parameter is
annotated as `Fn`, then capturing variables by `&mut T` or `T` are not
-allowed.
+allowed. However, `&T` is allowed.
In the following example, try swapping the usage of `Fn`, `FnMut`, and
`FnOnce` to see what happens:
diff --git a/src/doc/rust-by-example/src/hello/print.md b/src/doc/rust-by-example/src/hello/print.md
index c28dd9125..cce838fc2 100644
--- a/src/doc/rust-by-example/src/hello/print.md
+++ b/src/doc/rust-by-example/src/hello/print.md
@@ -68,7 +68,7 @@ fn main() {
// For Rust 1.58 and above, you can directly capture the argument from a
// surrounding variable. Just like the above, this will output
- // " 1". 5 white spaces and a "1".
+ // " 1". 4 white spaces and a "1".
let number: f64 = 1.0;
let width: usize = 5;
println!("{number:>width$}");
diff --git a/src/doc/rust-by-example/src/scope/lifetime.md b/src/doc/rust-by-example/src/scope/lifetime.md
index 33ffcae71..01c4bf405 100644
--- a/src/doc/rust-by-example/src/scope/lifetime.md
+++ b/src/doc/rust-by-example/src/scope/lifetime.md
@@ -26,7 +26,7 @@ fn main() {
let borrow1 = &i; // `borrow1` lifetime starts. ──â”│
// ││
println!("borrow1: {}", borrow1); // ││
- } // `borrow1 ends. ──────────────────────────────────┘│
+ } // `borrow1` ends. ─────────────────────────────────┘│
// │
// │
{ // │
diff --git a/src/doc/rust-by-example/src/std_misc/file/read_lines.md b/src/doc/rust-by-example/src/std_misc/file/read_lines.md
index 6792b1706..641eb972a 100644
--- a/src/doc/rust-by-example/src/std_misc/file/read_lines.md
+++ b/src/doc/rust-by-example/src/std_misc/file/read_lines.md
@@ -1,5 +1,39 @@
# `read_lines`
+## Beginner friendly method
+This method is NOT efficient. It's here for beginners
+who can't understand the efficient method yet.
+
+```rust,no_run
+use std::fs::File;
+use std::io::{ self, BufRead, BufReader };
+
+fn read_lines(filename: String) -> io::Lines<BufReader<File>> {
+ // Open the file in read-only mode.
+ let file = File::open(filename).unwrap();
+ // Read the file line by line, and return an iterator of the lines of the file.
+ return io::BufReader::new(file).lines();
+}
+
+fn main() {
+ // Stores the iterator of lines of the file in lines variable.
+ let lines = read_lines("./hosts".to_string());
+ // Iterate over the lines of the file, and in this case print them.
+ for line in lines {
+ println!("{}", line.unwrap());
+ }
+}
+```
+
+Running this program simply prints the lines individually.
+```shell
+$ echo -e "127.0.0.1\n192.168.0.1\n" > hosts
+$ rustc read_lines.rs && ./read_lines
+127.0.0.1
+192.168.0.1
+```
+
+## Efficient method
The method `lines()` returns an iterator over the lines
of a file.
diff --git a/src/doc/rust-by-example/src/types/cast.md b/src/doc/rust-by-example/src/types/cast.md
index deed34cf7..3078d82c1 100644
--- a/src/doc/rust-by-example/src/types/cast.md
+++ b/src/doc/rust-by-example/src/types/cast.md
@@ -22,7 +22,7 @@ fn main() {
let integer = decimal as u8;
let character = integer as char;
- // Error! There are limitations in conversion rules.
+ // Error! There are limitations in conversion rules.
// A float cannot be directly converted to a char.
let character = decimal as char;
// FIXME ^ Comment out this line
@@ -52,7 +52,7 @@ fn main() {
// Unless it already fits, of course.
println!(" 128 as a i16 is: {}", 128 as i16);
-
+
// 128 as u8 -> 128, whose value in 8-bit two's complement representation is:
println!(" 128 as a i8 is : {}", 128 as i8);
@@ -61,21 +61,21 @@ fn main() {
println!("1000 as a u8 is : {}", 1000 as u8);
// and the value of 232 in 8-bit two's complement representation is -24
println!(" 232 as a i8 is : {}", 232 as i8);
-
- // Since Rust 1.45, the `as` keyword performs a *saturating cast*
- // when casting from float to int. If the floating point value exceeds
- // the upper bound or is less than the lower bound, the returned value
+
+ // Since Rust 1.45, the `as` keyword performs a *saturating cast*
+ // when casting from float to int. If the floating point value exceeds
+ // the upper bound or is less than the lower bound, the returned value
// will be equal to the bound crossed.
-
+
// 300.0 as u8 is 255
println!(" 300.0 as u8 is : {}", 300.0_f32 as u8);
// -100.0 as u8 is 0
println!("-100.0 as u8 is : {}", -100.0_f32 as u8);
// nan as u8 is 0
println!(" nan as u8 is : {}", f32::NAN as u8);
-
- // This behavior incurs a small runtime cost and can be avoided
- // with unsafe methods, however the results might overflow and
+
+ // This behavior incurs a small runtime cost and can be avoided
+ // with unsafe methods, however the results might overflow and
// return **unsound values**. Use these methods wisely:
unsafe {
// 300.0 as u8 is 44
diff --git a/src/doc/rust-by-example/triagebot.toml b/src/doc/rust-by-example/triagebot.toml
index fa0824ac5..5b70fd0c4 100644
--- a/src/doc/rust-by-example/triagebot.toml
+++ b/src/doc/rust-by-example/triagebot.toml
@@ -1 +1,4 @@
[assign]
+
+[assign.owners]
+"*" = ["@marioidival"]
diff --git a/src/doc/rustc-dev-guide/src/asm.md b/src/doc/rustc-dev-guide/src/asm.md
index cd5430ffd..9b5a82f34 100644
--- a/src/doc/rustc-dev-guide/src/asm.md
+++ b/src/doc/rustc-dev-guide/src/asm.md
@@ -10,12 +10,13 @@ through all of the compiler layers down to LLVM codegen. Throughout the various
- The template string, which is stored as an array of `InlineAsmTemplatePiece`. Each piece
represents either a literal or a placeholder for an operand (just like format strings).
-```rust
-pub enum InlineAsmTemplatePiece {
- String(String),
- Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
-}
-```
+
+ ```rust
+ pub enum InlineAsmTemplatePiece {
+ String(String),
+ Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
+ }
+ ```
- The list of operands to the `asm!` (`in`, `[late]out`, `in[late]out`, `sym`, `const`). These are
represented differently at each stage of lowering, but follow a common pattern:
@@ -34,21 +35,22 @@ or a `fn`.
- The options set at the end of the `asm!` macro. The only ones that are of particular interest to
rustc are `NORETURN` which makes `asm!` return `!` instead of `()`, and `RAW` which disables format
string parsing. The remaining options are mostly passed through to LLVM with little processing.
-```rust
-bitflags::bitflags! {
- pub struct InlineAsmOptions: u16 {
- const PURE = 1 << 0;
- const NOMEM = 1 << 1;
- const READONLY = 1 << 2;
- const PRESERVES_FLAGS = 1 << 3;
- const NORETURN = 1 << 4;
- const NOSTACK = 1 << 5;
- const ATT_SYNTAX = 1 << 6;
- const RAW = 1 << 7;
- const MAY_UNWIND = 1 << 8;
- }
-}
-```
+
+ ```rust
+ bitflags::bitflags! {
+ pub struct InlineAsmOptions: u16 {
+ const PURE = 1 << 0;
+ const NOMEM = 1 << 1;
+ const READONLY = 1 << 2;
+ const PRESERVES_FLAGS = 1 << 3;
+ const NORETURN = 1 << 4;
+ const NOSTACK = 1 << 5;
+ const ATT_SYNTAX = 1 << 6;
+ const RAW = 1 << 7;
+ const MAY_UNWIND = 1 << 8;
+ }
+ }
+ ```
## AST
diff --git a/src/doc/rustc-dev-guide/src/backend/monomorph.md b/src/doc/rustc-dev-guide/src/backend/monomorph.md
index 416151ca9..21a788203 100644
--- a/src/doc/rustc-dev-guide/src/backend/monomorph.md
+++ b/src/doc/rustc-dev-guide/src/backend/monomorph.md
@@ -70,7 +70,7 @@ or more modules in Crate B.
| Crate A function | Behavior |
| - | - |
| Non-generic function | Crate A function doesn't appear in any codegen units of Crate B |
-| Non-generic `#[inline]` function | Crate A function appears with in a single CGU of Crate B, and exists even after post-inlining stage|
+| Non-generic `#[inline]` function | Crate A function appears within a single CGU of Crate B, and exists even after post-inlining stage|
| Generic function | Regardless of inlining, all monomorphized (specialized) functions <br> from Crate A appear within a single codegen unit for Crate B. <br> The codegen unit exists even after the post inlining stage.|
| Generic `#[inline]` function | - same - |
diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
index 81ebbbb40..38fbb2e44 100644
--- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
+++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
@@ -2,35 +2,25 @@
<!-- toc -->
-The Rust compiler uses LLVM as its primary codegen backend today, and naturally
-we want to at least occasionally update this dependency! Currently we do not
-have a strict policy about when to update LLVM or what it can be updated to, but
-a few guidelines are applied:
+<!-- date-check: Aug 2022 -->
+There is no formal policy about when to update LLVM or what it can be updated to,
+but a few guidelines are applied:
-* We try to always support the latest released version of LLVM
-* We try to support the "last few" versions of LLVM (how many is changing over
- time)
-* We allow moving to arbitrary commits during development.
-* Strongly prefer to upstream all patches to LLVM before including them in
- rustc.
-
-This policy may change over time (or may actually start to exist as a formal
-policy!), but for now these are rough guidelines!
+* We try to always support the latest released version
+* We try to support the last few versions
+ (and the number changes over time)
+* We allow moving to arbitrary commits during development
+* We strongly prefer to upstream all patches to LLVM before including them in rustc
## Why update LLVM?
-There are a few reasons nowadays that we want to update LLVM in one way or
-another:
+There are two reasons we would want to update LLVM:
* A bug could have been fixed! Often we find bugs in the compiler and fix
them upstream in LLVM. We'll want to pull fixes back to the compiler itself as
they're merged upstream.
-* A new feature may be available in LLVM that we want to use in rustc,
- but we don't want to wait for a full LLVM release to test it out.
-
-* LLVM itself may have a new release and we'd like to update to this LLVM
- release.
+* LLVM itself may have a new release.
Each of these reasons has a different strategy for updating LLVM, and we'll go
over them in detail here.
@@ -57,59 +47,67 @@ the branch we're already using. The steps for this are:
src/llvm-project` typically.
10. Wait for PR to be merged
-The tl;dr; is that we can cherry-pick bugfixes at any time and pull them back
-into the rust-lang/llvm-project branch that we're using, and getting it into the
-compiler is just updating the submodule via a PR!
-
-Example PRs look like:
+An example PR:
[#59089](https://github.com/rust-lang/rust/pull/59089)
-## Feature updates
-
-> Note that this information is as of the time of this writing, <!--
-date-check --> October 2021. The process for updating LLVM changes with
-practically all LLVM updates, so this may be out of date!
-
-Unlike bugfixes, updating to pick up a new feature of LLVM typically requires a
-lot more work. This is where we can't reasonably cherry-pick commits backwards
-so we need to do a full update. There's a lot of stuff to do here, so let's go
-through each in detail.
-
-1. Create a new branch in the [rust-lang/llvm-project repository]. This branch
- should be named `rustc/a.b-yyyy-mm-dd` where `a.b` is the current version
- number of LLVM in-tree at the time of the branch and the remaining part is
- today's date. Move this branch to the commit in LLVM that you'd like, which
- for this is probably the current LLVM HEAD.
-
-2. Apply Rust-specific patches to the llvm-project repository. All features and
- bugfixes are upstream, but there's often some weird build-related patches
- that don't make sense to upstream which we have on our repositories. These
- patches are around the latest patches in the rust-lang/llvm-project branch
- that rustc is currently using.
+## New LLVM Release Updates
-3. Build the new LLVM in the `rust` repository. To do this you'll want to update
- the `src/llvm-project` repository to your branch and the revision you've
- created. It's also typically a good idea to update `.gitmodules` with the new
- branch name of the LLVM submodule. Make sure you've committed changes to
- `src/llvm-project` to ensure submodule updates aren't reverted. Some commands
- you should execute are:
+<!-- date-check: Aug 2022 -->
+
+Unlike bugfixes,
+updating to a new release of LLVM typically requires a lot more work.
+This is where we can't reasonably cherry-pick commits backwards,
+so we need to do a full update.
+There's a lot of stuff to do here,
+so let's go through each in detail.
+
+1. LLVM announces that its latest release version has branched.
+ This will show up as a branch in the [llvm/llvm-project repository],
+ typically named `release/$N.x`,
+ where `$N` is the version of LLVM that's being released.
+
+1. Create a new branch in the [rust-lang/llvm-project repository]
+ from this `release/$N.x` branch,
+ and name it `rustc/a.b-yyyy-mm-dd`,
+ where `a.b` is the current version number of LLVM in-tree
+ at the time of the branch,
+ and the remaining part is the current date.
+
+2. Apply Rust-specific patches to the llvm-project repository.
+ All features and bugfixes are upstream,
+ but there's often some weird build-related patches
+ that don't make sense to upstream.
+ These patches are typically the latest patches in the
+ rust-lang/llvm-project branch that rustc is currently using.
+
+3. Build the new LLVM in the `rust` repository.
+ To do this,
+ you'll want to update the `src/llvm-project` repository to your branch,
+ and the revision you've created.
+ It's also typically a good idea to update `.gitmodules` with the new
+ branch name of the LLVM submodule.
+ Make sure you've committed changes to
+ `src/llvm-project` to ensure submodule updates aren't reverted.
+ Some commands you should execute are:
* `./x.py build src/llvm` - test that LLVM still builds
* `./x.py build src/tools/lld` - same for LLD
* `./x.py build` - build the rest of rustc
- You'll likely need to update [`llvm-wrapper/*.cpp`][`llvm-wrapper`] to compile
- with updated LLVM bindings. Note that you should use `#ifdef` and such to ensure
+ You'll likely need to update [`llvm-wrapper/*.cpp`][`llvm-wrapper`]
+ to compile with updated LLVM bindings.
+ Note that you should use `#ifdef` and such to ensure
that the bindings still compile on older LLVM versions.
Note that `profile = "compiler"` and other defaults set by `./x.py setup`
- download LLVM from CI instead of building it from source. You should
- disable this temporarily to make sure your changes are being used, by setting
+ download LLVM from CI instead of building it from source.
+ You should disable this temporarily to make sure your changes are being used.
+ This is done by having the following setting in `config.toml`:
+
```toml
[llvm]
download-ci-llvm = false
```
- in config.toml.
4. Test for regressions across other platforms. LLVM often has at least one bug
for non-tier-1 architectures, so it's good to do some more testing before
@@ -122,7 +120,7 @@ through each in detail.
* macOS
* Windows
- and afterwards run some docker containers that CI also does:
+ Afterwards, run some docker containers that CI also does:
* `./src/ci/docker/run.sh wasm32`
* `./src/ci/docker/run.sh arm-android`
@@ -135,16 +133,39 @@ through each in detail.
and then you can send a PR to `rust-lang/rust`. You'll change at least
`src/llvm-project` and will likely also change [`llvm-wrapper`] as well.
-For prior art, previous LLVM updates look like
-[#62474](https://github.com/rust-lang/rust/pull/62474)
-[#62592](https://github.com/rust-lang/rust/pull/62592)
-[#67759](https://github.com/rust-lang/rust/pull/67759)
-[#73526](https://github.com/rust-lang/rust/pull/73526)
-[#81451](https://github.com/rust-lang/rust/pull/81451). Note that sometimes it's
-easiest to land [`llvm-wrapper`] compatibility as a PR before actually updating
-`src/llvm-project`. This way while you're working through LLVM issues others
-interested in trying out the new LLVM can benefit from work you've done to
-update the C++ bindings.
+ > For prior art, here are some previous LLVM updates:
+ > - [LLVM 11](https://github.com/rust-lang/rust/pull/73526)
+ > - [LLVM 12](https://github.com/rust-lang/rust/pull/81451)
+ > - [LLVM 13](https://github.com/rust-lang/rust/pull/87570)
+ > - [LLVM 14](https://github.com/rust-lang/rust/pull/93577)
+ > - [LLVM 15](https://github.com/rust-lang/rust/pull/99464)
+
+ Note that sometimes it's easiest to land [`llvm-wrapper`] compatibility as a PR
+ before actually updating `src/llvm-project`.
+ This way,
+ while you're working through LLVM issues,
+ others interested in trying out the new LLVM can benefit from work you've done
+ to update the C++ bindings.
+
+3. Over the next few months,
+ LLVM will continually push commits to its `release/a.b` branch.
+ We will often want to have those bug fixes as well.
+ The merge process for that is to use `git merge` itself to merge LLVM's
+ `release/a.b` branch with the branch created in step 2.
+ This is typically
+ done multiple times when necessary while LLVM's release branch is baking.
+
+4. LLVM then announces the release of version `a.b`.
+
+5. After LLVM's official release,
+ we follow the process of creating a new branch on the
+ rust-lang/llvm-project repository again,
+ this time with a new date.
+ It is only then that the PR to update Rust to use that version is merged.
+
+ The commit history of `rust-lang/llvm-project`
+ should look much cleaner as a `git rebase` is done,
+ where just a few Rust-specific commits are stacked on top of stock LLVM's release branch.
### Caveats and gotchas
@@ -158,35 +179,6 @@ keep in mind while going through them:
* Creating branches is a privileged operation on GitHub, so you'll need someone
with write access to create the branches for you most likely.
-## New LLVM Release Updates
-
-Updating to a new release of LLVM is very similar to the "feature updates"
-section above. The release process for LLVM is often months-long though and we
-like to ensure compatibility ASAP. The main tweaks to the "feature updates"
-section above is generally around branch naming. The sequence of events
-typically looks like:
-
-1. LLVM announces that its latest release version has branched. This will show
- up as a branch in the [llvm/llvm-project repository] typically named
- `release/$N.x` where `$N` is the version of LLVM that's being released.
-
-2. We then follow the "feature updates" section above to create a new branch of
- LLVM in our rust-lang/llvm-project repository. This follows the same naming
- convention of branches as usual, except that `a.b` is the new version. This
- update is eventually landed in the rust-lang/rust repository.
-
-3. Over the next few months, LLVM will continually push commits to its
- `release/a.b` branch. Often those are bug fixes we'd like to have as well.
- The merge process for that is to use `git merge` itself to merge LLVM's
- `release/a.b` branch with the branch created in step 2. This is typically
- done multiple times when necessary while LLVM's release branch is baking.
-
-4. LLVM then announces the release of version `a.b`.
-
-5. After LLVM's official release, we follow the "feature update" section again
- to create a new branch in the rust-lang/llvm-project repository, this time
- with a new date. The commit history should look much cleaner as just a few
- Rust-specific commits stacked on top of stock LLVM's release branch.
[rust-lang/llvm-project repository]: https://github.com/rust-lang/llvm-project
[llvm/llvm-project repository]: https://github.com/llvm/llvm-project
diff --git a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md
index 8702f8aa9..2f5e24716 100644
--- a/src/doc/rustc-dev-guide/src/bug-fix-procedure.md
+++ b/src/doc/rustc-dev-guide/src/bug-fix-procedure.md
@@ -53,9 +53,9 @@ Please see [the RFC][rfc 1122] for full details!
The procedure for making a breaking change is as follows (each of these steps is
described in more detail below):
-0. Do a **crater run** to assess the impact of the change.
-1. Make a **special tracking issue** dedicated to the change.
-1. Do not report an error right away. Instead, **issue forwards-compatibility
+1. Do a **crater run** to assess the impact of the change.
+2. Make a **special tracking issue** dedicated to the change.
+3. Do not report an error right away. Instead, **issue forwards-compatibility
lint warnings**.
- Sometimes this is not straightforward. See the text below for suggestions
on different techniques we have employed in the past.
@@ -65,7 +65,7 @@ described in more detail below):
- Submit PRs to all known affected crates that fix the issue
- or, at minimum, alert the owners of those crates to the problem and
direct them to the tracking issue
-1. Once the change has been in the wild for at least one cycle, we can
+4. Once the change has been in the wild for at least one cycle, we can
**stabilize the change**, converting those warnings into errors.
Finally, for changes to `rustc_ast` that will affect plugins, the general policy
diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
index c5cf3166d..46d4b9c04 100644
--- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
+++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md
@@ -152,7 +152,9 @@ is what you need to build other Rust programs (unless you use `#![no_std]` or
You will probably find that building the stage1 `std` is a bottleneck for you,
but fear not, there is a (hacky) workaround...
-see [the section on "recommended workflows"](./suggested.md) below.
+see [the section on avoiding rebuilds for std][keep-stage].
+
+[keep-stage]: ./suggested.md#faster-builds-with---keep-stage
Note that this whole command just gives you a subset of the full `rustc`
build. The **full** `rustc` build (what you get with `./x.py build
diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md
index 5c5e571e4..a85229c6a 100644
--- a/src/doc/rustc-dev-guide/src/building/suggested.md
+++ b/src/doc/rustc-dev-guide/src/building/suggested.md
@@ -8,8 +8,9 @@ to make your life easier.
CI will automatically fail your build if it doesn't pass `tidy`, our
internal tool for ensuring code quality. If you'd like, you can install a
[Git hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)
-that will automatically run `./x.py test tidy --bless` on each push, to ensure
-your code is up to par. If you decide later that this behavior is
+that will automatically run `./x.py test tidy` on each push, to ensure
+your code is up to par. If the hook fails then run `./x.py test tidy --bless`
+and commit the changes. If you decide later that the pre-push behavior is
undesirable, you can delete the `pre-push` file in `.git/hooks`.
A prebuilt git hook lives at [`src/etc/pre-push.sh`](https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh) which can be copied into your `.git/hooks` folder as `pre-push` (without the `.sh` extension!).
@@ -22,7 +23,7 @@ You can also install the hook as a step of running `./x.py setup`!
a file. By default, `rust-analyzer` runs the `cargo check` and `rustfmt`
commands, but you can override these commands to use more adapted versions
of these tools when hacking on `rustc`. For example, for Visual Studio Code,
-you can write: <!-- date-check: apr 2022 --><!-- the date comment is for the edition below -->
+you can write: <!-- date-check: nov 2022 --><!-- the date comment is for the edition below -->
```JSON
{
@@ -135,13 +136,13 @@ lets you use `cargo fmt`.
[the section on vscode]: suggested.md#configuring-rust-analyzer-for-rustc
[the section on rustup]: how-to-build-and-run.md?highlight=rustup#creating-a-rustup-toolchain
-## Incremental builds with `--keep-stage`.
+## Faster builds with `--keep-stage`.
Sometimes just checking
whether the compiler builds is not enough. A common example is that
you need to add a `debug!` statement to inspect the value of some
state or better understand the problem. In that case, you really need
-a full build. By leveraging incremental, though, you can often get
+a full build. By bypassing bootstrap's cache invalidation, you can often get
these builds to complete very fast (e.g., around 30 seconds). The only
catch is this requires a bit of fudging and may produce compilers that
don't work (but that is easily detected and fixed).
diff --git a/src/doc/rustc-dev-guide/src/closure.md b/src/doc/rustc-dev-guide/src/closure.md
index c3906a80b..5746fd4de 100644
--- a/src/doc/rustc-dev-guide/src/closure.md
+++ b/src/doc/rustc-dev-guide/src/closure.md
@@ -142,11 +142,11 @@ declared in the file [`compiler/rustc_middle/src/ty/mod.rs`][ty].
[ty]:https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/index.html
Before we go any further, let's discuss how we can examine the flow of control through the rustc
-codebase. For closures specifically, set the `RUST_LOG` env variable as below and collect the
+codebase. For closures specifically, set the `RUSTC_LOG` env variable as below and collect the
output in a file:
```console
-> RUST_LOG=rustc_hir_typeck::upvar rustc +stage1 -Z dump-mir=all \
+> RUSTC_LOG=rustc_hir_typeck::upvar rustc +stage1 -Z dump-mir=all \
<.rs file to compile> 2> <file where the output will be dumped>
```
diff --git a/src/doc/rustc-dev-guide/src/compiler-team.md b/src/doc/rustc-dev-guide/src/compiler-team.md
index abdeac3d2..4570fd3fa 100644
--- a/src/doc/rustc-dev-guide/src/compiler-team.md
+++ b/src/doc/rustc-dev-guide/src/compiler-team.md
@@ -111,20 +111,22 @@ The guidelines for reviewers are as follows:
[Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct
-### high-five
+### Reviewer rotation
-Once you have r+ rights, you can also be added to the [high-five][hi5]
-rotation. high-five is the bot that assigns incoming PRs to
-reviewers. If you are added, you will be randomly selected to review
+Once you have r+ rights, you can also be added to the [reviewer rotation].
+[triagebot] is the bot that [automatically assigns] incoming PRs to reviewers.
+If you are added, you will be randomly selected to review
PRs. If you find you are assigned a PR that you don't feel comfortable
reviewing, you can also leave a comment like `r? @so-and-so` to assign
to someone else — if you don't know who to request, just write `r?
@nikomatsakis for reassignment` and @nikomatsakis will pick someone
for you.
-[hi5]: https://github.com/rust-highfive
+[reviewer rotation]: https://github.com/rust-lang/rust/blob/36285c5de8915ecc00d91ae0baa79a87ed5858d5/triagebot.toml#L528-L577
+[triagebot]: https://github.com/rust-lang/triagebot/
+[automatically assigns]: https://github.com/rust-lang/triagebot/wiki/Assignment
-Getting on the high-five list is much appreciated as it lowers the
+Getting on the reviewer rotation is much appreciated as it lowers the
review burden for all of us! However, if you don't have time to give
people timely feedback on their PRs, it may be better that you don't
get on the list.
diff --git a/src/doc/rustc-dev-guide/src/constants.md b/src/doc/rustc-dev-guide/src/constants.md
index 4f1027b98..a33a283f3 100644
--- a/src/doc/rustc-dev-guide/src/constants.md
+++ b/src/doc/rustc-dev-guide/src/constants.md
@@ -79,4 +79,4 @@ the constant doesn't use them in any way. This can cause
[`ty::Const`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Const.html
[`ty::ConstKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.ConstKind.html
[`ty::TyKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html
-[pcg-unused-substs]: https://github.com/rust-lang/project-const-generics/blob/master/design-docs/anon-const-substs.md#unused-substs \ No newline at end of file
+[pcg-unused-substs]: https://github.com/rust-lang/project-const-generics/issues/33
diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md
index 279bc2f28..41ad1c915 100644
--- a/src/doc/rustc-dev-guide/src/contributing.md
+++ b/src/doc/rustc-dev-guide/src/contributing.md
@@ -73,7 +73,7 @@ when contributing to Rust under [the git section](./git.md).
### r?
All pull requests are reviewed by another person. We have a bot,
-[@rust-highfive][rust-highfive], that will automatically assign a random person
+[@rustbot], that will automatically assign a random person
to review your request based on which files you changed.
If you want to request that a specific person reviews your pull request, you
@@ -82,7 +82,7 @@ if you want to ask a review to @awesome-reviewer, add
r? @awesome-reviewer
-to the end of the pull request description, and [@rust-highfive][rust-highfive] will assign
+to the end of the pull request description, and [@rustbot] will assign
them instead of a random person. This is entirely optional.
You can also assign a random reviewer from a specific team by writing `r? rust-lang/groupname`.
@@ -91,8 +91,10 @@ team by adding:
r? rust-lang/diagnostics
-For a full list of possible `groupname` check the `groups` section at the
-[rust highfive config file](https://github.com/rust-lang/highfive/blob/master/highfive/configs/rust-lang/rust.json).
+For a full list of possible `groupname` check the `adhoc_groups` section at the
+[triagebot.toml config file](https://github.com/rust-lang/rust/blob/master/triagebot.toml)
+or the list of teams in the [rust-lang teams
+database](https://github.com/rust-lang/team/tree/master/teams).
### CI
@@ -133,7 +135,7 @@ Changes that are rolled up are tested and merged alongside other PRs, to
speed the process up. Typically only small changes that are expected not to conflict
with one another are marked as "always roll up".
-[rust-highfive]: https://github.com/rust-highfive
+[@rustbot]: https://github.com/rustbot
[@bors]: https://github.com/bors
[merge-queue]: https://bors.rust-lang.org/queue/rust
@@ -189,8 +191,10 @@ differently from other crates that are directly in this repo:
In contrast to `submodule` dependencies
(see below for those), the `subtree` dependencies are just regular files and directories which can
-be updated in tree. However, enhancements, bug fixes, etc. specific to these tools should be filed
-against the tools directly in their respective upstream repositories.
+be updated in tree. However, if possible, enhancements, bug fixes, etc. specific
+to these tools should be filed against the tools directly in their respective
+upstream repositories. The exception is that when rustc changes are required to
+implement a new tool feature or test, that should happen in one collective rustc PR.
#### Synchronizing a subtree
diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md
index 0d5f17b99..4dd0a2da9 100644
--- a/src/doc/rustc-dev-guide/src/conventions.md
+++ b/src/doc/rustc-dev-guide/src/conventions.md
@@ -21,7 +21,7 @@ Formatting is checked by the `tidy` script. It runs automatically when you do
If you want to use format-on-save in your editor, the pinned version of
`rustfmt` is built under `build/<target>/stage0/bin/rustfmt`. You'll have to
-pass the <!-- date-check: April 2022 --> `--edition=2021` argument yourself when calling
+pass the <!-- date-check: nov 2022 --> `--edition=2021` argument yourself when calling
`rustfmt` directly.
[fmt]: https://github.com/rust-dev-tools/fmt-rfcs
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
index d51e79348..e26ba5f34 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
@@ -28,8 +28,10 @@ pub struct FieldAlreadyDeclared {
}
```
-`Diagnostic` can only be applied to structs. Every `Diagnostic`
-has to have one attribute, `#[diag(...)]`, applied to the struct itself.
+`Diagnostic` can only be applied to structs and enums.
+Attributes that are placed on the type for structs are placed on each
+variants for enums (or vice versa). Each `Diagnostic` has to have one
+attribute, `#[diag(...)]`, applied to the struct or each enum variant.
If an error has an error code (e.g. "E0624"), then that can be specified using
the `code` sub-attribute. Specifying a `code` isn't mandatory, but if you are
@@ -198,9 +200,9 @@ following attributes:
- See [translation documentation](./translation.md).
- Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or
- `.suggestion` in Fluent).
- - `code = "..."` (_Mandatory_)
- - Value is a format string indicating the code to be suggested as a
- replacement.
+ - `code = "..."`/`code("...", ...)` (_Mandatory_)
+ - One or multiple format strings indicating the code to be suggested as a
+ replacement. Multiple values signify multiple possible replacements.
- `applicability = "..."` (_Optional_)
- String which must be one of `machine-applicable`, `maybe-incorrect`,
`has-placeholders` or `unspecified`.
@@ -243,7 +245,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
}
```
-Unlike `Diagnostic`, `Subdiagnostic` can be applied to structs or
+Like `Diagnostic`, `Subdiagnostic` can be applied to structs or
enums. Attributes that are placed on the type for structs are placed on each
variants for enums (or vice versa). Each `Subdiagnostic` should have one
attribute applied to the struct or each variant, one of:
@@ -357,9 +359,9 @@ diagnostic struct.
- See [translation documentation](./translation.md).
- Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or
- `.suggestion` in Fluent).
- - `code = "..."` (_Mandatory_)
- - Value is a format string indicating the code to be suggested as a
- replacement.
+ - `code = "..."`/`code("...", ...)` (_Mandatory_)
+ - One or multiple format strings indicating the code to be suggested as a
+ replacement. Multiple values signify multiple possible replacements.
- `applicability = "..."` (_Optional_)
- _Mutually exclusive with `#[applicability]` on a field._
- Value is the applicability of the suggestion.
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
index 33d9646f6..603c9ed65 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
@@ -14,11 +14,6 @@ There are two parts to the linting mechanism within the compiler: lints and
lint passes. Unfortunately, a lot of the documentation we have refers to both
of these as just "lints."
-First, we have the lint declarations themselves: this is where the name and
-default lint level and other metadata come from. These are normally defined by
-way of the [`declare_lint!`] macro, which boils down to a static with type
-[`&rustc_lint_defs::Lint`].
-
First, we have the lint declarations themselves,
and this is where the name and default lint level and other metadata come from.
These are normally defined by way of the [`declare_lint!`] macro,
diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md
index b4dc11a68..4e1f520ff 100644
--- a/src/doc/rustc-dev-guide/src/getting-started.md
+++ b/src/doc/rustc-dev-guide/src/getting-started.md
@@ -156,7 +156,7 @@ highlights, but there are a lot more details, which we will link to below.
### Code Review
-When you open a PR on the `rust-lang/rust` repo, a bot called `@rust-highfive` will
+When you open a PR on the `rust-lang/rust` repo, a bot called `@rustbot` will
automatically assign a reviewer to the PR based on which files you changed.
The reviewer is the person that will approve the PR to be tested and merged.
If you want a specific reviewer (e.g. a team member you've been working with),
diff --git a/src/doc/rustc-dev-guide/src/macro-expansion.md b/src/doc/rustc-dev-guide/src/macro-expansion.md
index 156df8d5f..7f50f7f89 100644
--- a/src/doc/rustc-dev-guide/src/macro-expansion.md
+++ b/src/doc/rustc-dev-guide/src/macro-expansion.md
@@ -48,45 +48,45 @@ iteration, this represents a compile error. Here is the [algorithm][original]:
[fef]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/expand/struct.MacroExpander.html#method.fully_expand_fragment
[original]: https://github.com/rust-lang/rust/pull/53778#issuecomment-419224049
-0. Initialize an `queue` of unresolved macros.
-1. Repeat until `queue` is empty (or we make no progress, which is an error):
- 0. [Resolve](./name-resolution.md) imports in our partially built crate as
- much as possible.
- 1. Collect as many macro [`Invocation`s][inv] as possible from our
- partially built crate (fn-like, attributes, derives) and add them to the
- queue.
- 2. Dequeue the first element, and attempt to resolve it.
- 3. If it's resolved:
- 0. Run the macro's expander function that consumes a [`TokenStream`] or
- AST and produces a [`TokenStream`] or [`AstFragment`] (depending on
- the macro kind). (A `TokenStream` is a collection of [`TokenTree`s][tt],
- each of which are a token (punctuation, identifier, or literal) or a
- delimited group (anything inside `()`/`[]`/`{}`)).
- - At this point, we know everything about the macro itself and can
- call `set_expn_data` to fill in its properties in the global data;
- that is the hygiene data associated with `ExpnId`. (See [the
- "Hygiene" section below][hybelow]).
- 1. Integrate that piece of AST into the big existing partially built
- AST. This is essentially where the "token-like mass" becomes a
- proper set-in-stone AST with side-tables. It happens as follows:
- - If the macro produces tokens (e.g. a proc macro), we parse into
- an AST, which may produce parse errors.
- - During expansion, we create `SyntaxContext`s (hierarchy 2). (See
- [the "Hygiene" section below][hybelow])
- - These three passes happen one after another on every AST fragment
- freshly expanded from a macro:
- - [`NodeId`]s are assigned by [`InvocationCollector`]. This
- also collects new macro calls from this new AST piece and
- adds them to the queue.
- - ["Def paths"][defpath] are created and [`DefId`]s are
- assigned to them by [`DefCollector`].
- - Names are put into modules (from the resolver's point of
- view) by [`BuildReducedGraphVisitor`].
- 2. After expanding a single macro and integrating its output, continue
- to the next iteration of [`fully_expand_fragment`][fef].
- 4. If it's not resolved:
- 0. Put the macro back in the queue
- 1. Continue to next iteration...
+1. Initialize an `queue` of unresolved macros.
+2. Repeat until `queue` is empty (or we make no progress, which is an error):
+ 1. [Resolve](./name-resolution.md) imports in our partially built crate as
+ much as possible.
+ 2. Collect as many macro [`Invocation`s][inv] as possible from our
+ partially built crate (fn-like, attributes, derives) and add them to the
+ queue.
+ 3. Dequeue the first element, and attempt to resolve it.
+ 4. If it's resolved:
+ 1. Run the macro's expander function that consumes a [`TokenStream`] or
+ AST and produces a [`TokenStream`] or [`AstFragment`] (depending on
+ the macro kind). (A `TokenStream` is a collection of [`TokenTree`s][tt],
+ each of which are a token (punctuation, identifier, or literal) or a
+ delimited group (anything inside `()`/`[]`/`{}`)).
+ - At this point, we know everything about the macro itself and can
+ call `set_expn_data` to fill in its properties in the global data;
+ that is the hygiene data associated with `ExpnId`. (See [the
+ "Hygiene" section below][hybelow]).
+ 2. Integrate that piece of AST into the big existing partially built
+ AST. This is essentially where the "token-like mass" becomes a
+ proper set-in-stone AST with side-tables. It happens as follows:
+ - If the macro produces tokens (e.g. a proc macro), we parse into
+ an AST, which may produce parse errors.
+ - During expansion, we create `SyntaxContext`s (hierarchy 2). (See
+ [the "Hygiene" section below][hybelow])
+ - These three passes happen one after another on every AST fragment
+ freshly expanded from a macro:
+ - [`NodeId`]s are assigned by [`InvocationCollector`]. This
+ also collects new macro calls from this new AST piece and
+ adds them to the queue.
+ - ["Def paths"][defpath] are created and [`DefId`]s are
+ assigned to them by [`DefCollector`].
+ - Names are put into modules (from the resolver's point of
+ view) by [`BuildReducedGraphVisitor`].
+ 3. After expanding a single macro and integrating its output, continue
+ to the next iteration of [`fully_expand_fragment`][fef].
+ 5. If it's not resolved:
+ 1. Put the macro back in the queue
+ 2. Continue to next iteration...
[defpath]: hir.md#identifiers-in-the-hir
[`NodeId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/node_id/struct.NodeId.html
@@ -149,9 +149,9 @@ macros are implemented in [`rustc_builtin_macros`], along with some other early
code generation facilities like injection of standard library imports or
generation of test harness. There are some additional helpers for building
their AST fragments in [`rustc_expand::build`][reb]. Eager expansion generally
-performs a subset of the things that lazy (normal) expansion. It is done by
+performs a subset of the things that lazy (normal) expansion does. It is done by
invoking [`fully_expand_fragment`][fef] on only part of a crate (as opposed to
-whole crate, like we normally do).
+the whole crate, like we normally do).
### Other Data Structures
@@ -532,7 +532,7 @@ three cases has occurred:
- Failure: the token stream does not match `matcher`. This results in an error message such as
"No rule expected token _blah_".
- Error: some fatal error has occurred _in the parser_. For example, this
- happens if there are more than one pattern match, since that indicates
+ happens if there is more than one pattern match, since that indicates
the macro is ambiguous.
The full interface is defined [here][code_parse_int].
diff --git a/src/doc/rustc-dev-guide/src/mir/dataflow.md b/src/doc/rustc-dev-guide/src/mir/dataflow.md
index ce4a86a23..15bfd6aed 100644
--- a/src/doc/rustc-dev-guide/src/mir/dataflow.md
+++ b/src/doc/rustc-dev-guide/src/mir/dataflow.md
@@ -61,7 +61,7 @@ slower as a result. All implementers of `GenKillAnalysis` also implement
### Transfer Functions and Effects
The dataflow framework in `rustc` allows each statement (and terminator) inside
-a basic block define its own transfer function. For brevity, these
+a basic block to define its own transfer function. For brevity, these
individual transfer functions are known as "effects". Each effect is applied
successively in dataflow order, and together they define the transfer function
for the entire basic block. It's also possible to define an effect for
diff --git a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md
index 20b92cc45..0869e0e3d 100644
--- a/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md
+++ b/src/doc/rustc-dev-guide/src/mir/drop-elaboration.md
@@ -111,7 +111,7 @@ a few optimizations:
- Only paths that are the target of a `Drop` (or have the target as a prefix)
need drop flags.
-- Some variables are known to initialized (or uninitialized) when they are
+- Some variables are known to be initialized (or uninitialized) when they are
dropped. These do not need drop flags.
- If a set of paths are only dropped or moved from via a shared prefix, those
paths can share a single drop flag.
diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md
index 7fbdfd359..ceb0efdb2 100644
--- a/src/doc/rustc-dev-guide/src/overview.md
+++ b/src/doc/rustc-dev-guide/src/overview.md
@@ -292,7 +292,7 @@ Moreover, the compiler wasn't originally built to use a query system; the query
system has been retrofitted into the compiler, so parts of it are not query-fied
yet. Also, LLVM isn't our code, so that isn't querified either. The plan is to
eventually query-fy all of the steps listed in the previous section,
-but as of <!-- date-check --> November 2021, only the steps between HIR and
+but as of <!-- date-check --> November 2022, only the steps between HIR and
LLVM IR are query-fied. That is, lexing, parsing, name resolution, and macro
expansion are done all at once for the whole program.
diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md
index e93f51dbb..e7cbbd7ee 100644
--- a/src/doc/rustc-dev-guide/src/parallel-rustc.md
+++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md
@@ -26,7 +26,7 @@ occurs in the `rustc_codegen_ssa::base` module.
The underlying thread-safe data-structures used in the parallel compiler
can be found in the `rustc_data_structures::sync` module. These data structures
-are implemented diferently depending on whether `parallel-compiler` is true.
+are implemented differently depending on whether `parallel-compiler` is true.
| data structure | parallel | non-parallel |
| -------------------------------- | --------------------------------------------------- | ------------ |
@@ -141,7 +141,7 @@ the previous `Data Structures` and `Parallel Iterators`. See [this tracking issu
## Rustdoc
-As of <!-- date-check--> May 2022, there are still a number of steps
+As of <!-- date-check--> November 2022, there are still a number of steps
to complete before rustdoc rendering can be made parallel. More details on
this issue can be found [here][parallel-rustdoc].
diff --git a/src/doc/rustc-dev-guide/src/part-5-intro.md b/src/doc/rustc-dev-guide/src/part-5-intro.md
index faa12f484..f32508d27 100644
--- a/src/doc/rustc-dev-guide/src/part-5-intro.md
+++ b/src/doc/rustc-dev-guide/src/part-5-intro.md
@@ -21,16 +21,16 @@ Now, we will finally take the MIR and produce some executable machine code.
So what do we need to do?
-0. First, we need to collect the set of things to generate code for.
+1. First, we need to collect the set of things to generate code for.
In particular,
we need to find out which concrete types to substitute for generic ones,
since we need to generate code for the concrete types.
Generating code for the concrete types
(i.e. emitting a copy of the code for each concrete type) is called _monomorphization_,
so the process of collecting all the concrete types is called _monomorphization collection_.
-1. Next, we need to actually lower the MIR to a codegen IR
+2. Next, we need to actually lower the MIR to a codegen IR
(usually LLVM IR) for each concrete type we collected.
-2. Finally, we need to invoke the codegen backend,
+3. Finally, we need to invoke the codegen backend,
which runs a bunch of optimization passes,
generates executable code,
and links together an executable binary.
diff --git a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md
index dc196e490..abd2b0155 100644
--- a/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md
+++ b/src/doc/rustc-dev-guide/src/queries/incremental-compilation-in-detail.md
@@ -175,11 +175,12 @@ fn try_mark_green(tcx, current_node) -> bool {
true
}
-
-// Note: The actual implementation can be found in
-// compiler/rustc_middle/src/dep_graph/graph.rs
```
+> NOTE:
+> The actual implementation can be found in
+> [`compiler/rustc_query_system/src/dep_graph/graph.rs`][try_mark_green]
+
By using red-green marking we can avoid the devastating cumulative effect of
having false positives during change detection. Whenever a query is executed
in incremental mode, we first check if its already green. If not, we run
@@ -187,7 +188,6 @@ in incremental mode, we first check if its already green. If not, we run
invoke the query provider to re-compute the result.
-
## The Real World: How Persistence Makes Everything Complicated
The sections above described the underlying algorithm for incremental
@@ -533,5 +533,5 @@ be reusable. See <https://github.com/rust-lang/rust/issues/47389> for more
information.
-
[query-model]: ./query-evaluation-model-in-detail.html
+[try_mark_green]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_query_system/dep_graph/graph.rs.html
diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md
index 3d60059bd..268a56558 100644
--- a/src/doc/rustc-dev-guide/src/query.md
+++ b/src/doc/rustc-dev-guide/src/query.md
@@ -169,31 +169,30 @@ they define both a `provide` and a `provide_extern` function, through
How do you add a new query?
Defining a query takes place in two steps:
-1. Specify the query name and its arguments.
+1. Declare the query name, its arguments and description.
2. Supply query providers where needed.
-To specify the query name and arguments, you simply add an entry to
-the big macro invocation in
-[`compiler/rustc_middle/src/query/mod.rs`][query-mod], which looks something like:
+To declare the query name and arguments, you simply add an entry to
+the big macro invocation in [`compiler/rustc_middle/src/query/mod.rs`][query-mod].
+Then you need to add a documentation comment to it with some _internal_ description.
+Then, provide the `desc` attribute which contains a _user-facing_ description of the query.
+The `desc` attribute is shown to the user in query cycles.
+
+This looks something like:
[query-mod]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/index.html
```rust,ignore
rustc_queries! {
- Other {
- /// Records the type of every item.
- query type_of(key: DefId) -> Ty<'tcx> {
- cache { key.is_local() }
- }
+ /// Records the type of every item.
+ query type_of(key: DefId) -> Ty<'tcx> {
+ cache_on_disk_if { key.is_local() }
+ desc { |tcx| "computing the type of `{}`", tcx.def_path_str(key) }
}
-
...
}
```
-Queries are grouped into categories (`Other`, `Codegen`, `TypeChecking`, etc.).
-Each group contains one or more queries.
-
A query definition has the following form:
```rust,ignore
@@ -238,62 +237,6 @@ which is used to cheaply modify MIR in place. See the definition
of `Steal` for more details. New uses of `Steal` should **not** be
added without alerting `@rust-lang/compiler`.
-### Query structs and descriptions
-
-For each query, the `rustc_queries` macro will generate a "query struct"
-named after the query. This struct is a kind of placeholder
-describing the query. Each query struct implements the
-[`self::config::QueryConfig`][QueryConfig] trait, which has associated types for the
-key/value of that particular query. Basically the code generated looks something
-like this:
-
-```rust,ignore
-// Dummy struct representing a particular kind of query:
-pub struct type_of<'tcx> { data: PhantomData<&'tcx ()> }
-
-impl<'tcx> QueryConfig for type_of<'tcx> {
- type Key = DefId;
- type Value = Ty<'tcx>;
-
- const NAME: QueryName = QueryName::type_of;
- const CATEGORY: ProfileCategory = ProfileCategory::Other;
-}
-```
-
-There is an additional trait that you may wish to implement called
-[`self::config::QueryDescription`][QueryDescription]. This trait is
-used during cycle errors to give a "human readable" name for the query,
-so that we can summarize what was happening when the cycle occurred.
-Implementing this trait is optional if the query key is `DefId`, but
-if you *don't* implement it, you get a pretty generic error ("processing `foo`...").
-You can put new impls into the `config` module. They look something like this:
-
-[QueryConfig]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_query_system/query/config/trait.QueryConfig.html
-[QueryDescription]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_query_system/query/config/trait.QueryDescription.html
-
-```rust,ignore
-impl<'tcx> QueryDescription for queries::type_of<'tcx> {
- fn describe(tcx: TyCtxt, key: DefId) -> String {
- format!("computing the type of `{}`", tcx.def_path_str(key))
- }
-}
-```
-
-Another option is to add `desc` modifier:
-
-```rust,ignore
-rustc_queries! {
- Other {
- /// Records the type of every item.
- query type_of(key: DefId) -> Ty<'tcx> {
- desc { |tcx| "computing the type of `{}`", tcx.def_path_str(key) }
- }
- }
-}
-```
-
-`rustc_queries` macro will generate an appropriate `impl` automatically.
-
## External links
Related design ideas, and tracking issues:
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
index f21c8725c..c85e82e96 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md
@@ -66,7 +66,7 @@ these passes, please let us know!)
[44136]: https://github.com/rust-lang/rust/issues/44136
-Here is the list of passes as of <!-- date-check --> May 2022:
+Here is the list of passes as of <!-- date-check --> November 2022:
- `calculate-doc-coverage` calculates information used for the `--show-coverage`
flag.
diff --git a/src/doc/rustc-dev-guide/src/salsa.md b/src/doc/rustc-dev-guide/src/salsa.md
index 872308e78..66f9d7479 100644
--- a/src/doc/rustc-dev-guide/src/salsa.md
+++ b/src/doc/rustc-dev-guide/src/salsa.md
@@ -9,7 +9,7 @@ want to watch [Salsa In More
Depth](https://www.youtube.com/watch?v=i_IhACacPRY), also by Niko
Matsakis.
-> As of <!-- date-check --> April 2022, although Salsa is inspired by
+> As of <!-- date-check --> November 2022, although Salsa is inspired by
> (among other things) rustc's query system, it is not used directly in rustc.
> It _is_ used in chalk and extensively in `rust-analyzer`, but there are no
> medium or long-term concrete plans to integrate it into the compiler.
diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md
index b7308ee73..85c75fadb 100644
--- a/src/doc/rustc-dev-guide/src/stability.md
+++ b/src/doc/rustc-dev-guide/src/stability.md
@@ -72,14 +72,14 @@ Furthermore this attribute is needed to mark an intrinsic as callable from
To stabilize a feature, follow these steps:
-0. Ask a **@T-libs-api** member to start an FCP on the tracking issue and wait for
+1. Ask a **@T-libs-api** member to start an FCP on the tracking issue and wait for
the FCP to complete (with `disposition-merge`).
-1. Change `#[unstable(...)]` to `#[stable(since = "CURRENT_RUSTC_VERSION")]`.
-2. Remove `#![feature(...)]` from any test or doc-test for this API. If the feature is used in the
+2. Change `#[unstable(...)]` to `#[stable(since = "CURRENT_RUSTC_VERSION")]`.
+3. Remove `#![feature(...)]` from any test or doc-test for this API. If the feature is used in the
compiler or tools, remove it from there as well.
-3. If applicable, change `#[rustc_const_unstable(...)]` to
+4. If applicable, change `#[rustc_const_unstable(...)]` to
`#[rustc_const_stable(since = "CURRENT_RUSTC_VERSION")]`.
-4. Open a PR against `rust-lang/rust`.
+5. Open a PR against `rust-lang/rust`.
- Add the appropriate labels: `@rustbot modify labels: +T-libs-api`.
- Link to the tracking issue and say "Closes #XXXXX".
diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md
index 1baa447a0..3556f4e23 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -207,6 +207,10 @@ There are several ways to match the message with the line (see the examples belo
This is more convenient than using multiple carets when there are multiple
messages associated with the same line.
+The space character between `//~` (or other variants) and the subsequent text
+is negligible (i.e. there is no semantic difference between `//~ ERROR` and
+`//~ERROR` although the former is more common in the codebase).
+
### Error annotation examples
Here are examples of error annotations on different lines of UI test
diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md
index 88767ad94..9cf753b19 100644
--- a/src/doc/rustc-dev-guide/src/traits/resolution.md
+++ b/src/doc/rustc-dev-guide/src/traits/resolution.md
@@ -52,7 +52,7 @@ by proving that an appropriate impl does exist.
During type checking, we do not store the results of trait selection.
We simply wish to verify that trait selection will succeed. Then
-later, at trans time, when we have all concrete types available, we
+later, at codegen time, when we have all concrete types available, we
can repeat the trait selection to choose an actual implementation, which
will then be generated in the output binary.
diff --git a/src/doc/rustc-dev-guide/src/traits/specialization.md b/src/doc/rustc-dev-guide/src/traits/specialization.md
index 7a30314b4..7cae5e9c1 100644
--- a/src/doc/rustc-dev-guide/src/traits/specialization.md
+++ b/src/doc/rustc-dev-guide/src/traits/specialization.md
@@ -36,7 +36,7 @@ as long as they are part of the same specialization family. In that
case, it returns a *single* impl on success – this is the most
specialized impl *known* to apply. However, if there are any inference
variables in play, the returned impl may not be the actual impl we
-will use at trans time. Thus, we take special care to avoid projecting
+will use at codegen time. Thus, we take special care to avoid projecting
associated types unless either (1) the associated type does not use
`default` and thus cannot be overridden or (2) all input types are
known concretely.
diff --git a/src/doc/rustc-dev-guide/src/ty-fold.md b/src/doc/rustc-dev-guide/src/ty-fold.md
index c390597f9..dd76b80d4 100644
--- a/src/doc/rustc-dev-guide/src/ty-fold.md
+++ b/src/doc/rustc-dev-guide/src/ty-fold.md
@@ -17,7 +17,7 @@ and
For example, the `TypeFolder` trait has a method
[`fold_ty`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFolder.html#method.fold_ty)
-that takes a type as input a type and returns a new type as a result. `TypeFoldable` invokes the
+that takes a type as input and returns a new type as a result. `TypeFoldable` invokes the
`TypeFolder` `fold_foo` methods on itself, giving the `TypeFolder` access to its contents (the
types, regions, etc that are contained within).
diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md
index 10f1dd5ef..ca88c1686 100644
--- a/src/doc/rustc-dev-guide/src/type-inference.md
+++ b/src/doc/rustc-dev-guide/src/type-inference.md
@@ -218,29 +218,33 @@ algorithms.
[`region_constraints`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/region_constraints/index.html
[`opportunistic_resolve_var`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/region_constraints/struct.RegionConstraintCollector.html#method.opportunistic_resolve_var
-## Extracting region constraints
+## Solving region constraints
-Ultimately, region constraints are only solved at the very end of
-type-checking, once all other constraints are known. There are two
+Region constraints are only solved at the very end of
+typechecking, once all other constraints are known and
+all other obligations have been proven. There are two
ways to solve region constraints right now: lexical and
non-lexical. Eventually there will only be one.
+An exception here is the leak-check which is used during trait solving
+and relies on region constraints containing higher-ranked regions. Region
+constraints in the root universe (i.e. not arising from a `for<'a>`) must
+not influence the trait system, as these regions are all erased during
+codegen.
+
To solve **lexical** region constraints, you invoke
[`resolve_regions_and_report_errors`]. This "closes" the region
constraint process and invokes the [`lexical_region_resolve`] code. Once
this is done, any further attempt to equate or create a subtyping
relationship will yield an ICE.
-Non-lexical region constraints are not handled within the inference
-context. Instead, the NLL solver (actually, the MIR type-checker)
-invokes [`take_and_reset_region_constraints`] periodically. This
-extracts all of the outlives constraints from the region solver, but
-leaves the set of variables intact. This is used to get *just* the
-region constraints that resulted from some particular point in the
-program, since the NLL solver needs to know not just *what* regions
-were subregions, but also *where*. Finally, the NLL solver invokes
-[`take_region_var_origins`], which "closes" the region constraint
-process in the same way as normal solving.
+The NLL solver (actually, the MIR type-checker) does things slightly
+differently. It uses canonical queries for trait solving which use
+[`take_and_reset_region_constraints`] at the end. This extracts all of the
+outlives constraints added during the canonical query. This is required
+as the NLL solver must not only know *what* regions outlive each other,
+but also *where*. Finally, the NLL solver invokes [`take_region_var_origins`],
+providing all region variables to the solver.
[`resolve_regions_and_report_errors`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.resolve_regions_and_report_errors
[`lexical_region_resolve`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/lexical_region_resolve/index.html
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 06883ddd5..2d3b83094 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -29,9 +29,11 @@
- [\*-kmc-solid_\*](platform-support/kmc-solid.md)
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
- [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
+ - [mipsel-sony-psx](platform-support/mipsel-sony-psx.md)
- [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md)
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
+ - [\*-nto-qnx-\*](platform-support/nto-qnx.md)
- [*-unknown-openbsd](platform-support/openbsd.md)
- [\*-unknown-uefi](platform-support/unknown-uefi.md)
- [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index b1c3b618c..7e355b7fc 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -210,8 +210,8 @@ metrics.
## link-self-contained
-On targets that support it this flag controls whether the linker will use libraries and objects
-shipped with Rust instead or those in the system.
+On `windows-gnu`, `linux-musl`, and `wasi` targets, this flag controls whether the
+linker will use libraries and objects shipped with Rust instead or those in the system.
It takes one of the following values:
* no value: rustc will use heuristic to disable self-contained mode if system has necessary tools.
@@ -531,8 +531,10 @@ platforms. Possible values are:
debug information. On other Unix platforms this means that `*.dwo` files will
contain debug information.
-Note that `packed` and `unpacked` are gated behind `-Z unstable-options` on
-non-macOS platforms at this time.
+Note that all three options are supported on Linux and Apple platforms,
+`packed` is supported on Windows-MSVC, and all other platforms support `off`.
+Attempting to use an unsupported option requires using the nightly channel
+with the `-Z unstable-options` flag.
## strip
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index 2dc182b3d..ef6eee75f 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -104,6 +104,33 @@ This modifier has no effect when building other targets like executables or dyna
The default for this modifier is `+bundle`.
+### Linking modifiers: `verbatim`
+
+This modifier is compatible with all linking kinds.
+
+`+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes
+(like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the
+linker.
+
+For `ld`-like linkers supporting GNU extensions rustc will use the `-l:filename` syntax (note the
+colon) when passing the library, so the linker won't add any prefixes or suffixes to it.
+See [`-l namespec`](https://sourceware.org/binutils/docs/ld/Options.html) in ld documentation for
+more details. \
+For linkers not supporting any verbatim modifiers (e.g. `link.exe` or `ld64`) the library name will
+be passed as is. So the most reliable cross-platform use scenarios for this option are when no
+linker is involved, for example bundling native libraries into rlibs.
+
+`-verbatim` means that rustc will either add a target-specific prefix and suffix to the library
+name before passing it to linker, or won't prevent linker from implicitly adding it. \
+In case of `raw-dylib` kind in particular `.dll` will be added to the library name on Windows.
+
+The default for this modifier is `-verbatim`.
+
+NOTE: Even with `+verbatim` and `-l:filename` syntax `ld`-like linkers do not typically support
+passing absolute paths to libraries. Usually such paths need to be passed as input files without
+using any options like `-l`, e.g. `ld /my/absolute/path`. \
+`-Clink-arg=/my/absolute/path` can be used for doing this from stable `rustc`.
+
<a id="option-crate-type"></a>
## `--crate-type`: a list of types of crates for the compiler to emit
diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md
index b1854b22a..9272b9ac9 100644
--- a/src/doc/rustc/src/linker-plugin-lto.md
+++ b/src/doc/rustc/src/linker-plugin-lto.md
@@ -131,24 +131,47 @@ able to get around this problem by setting `-Clinker=lld-link` in RUSTFLAGS
## Toolchain Compatibility
-<!-- NOTE: to update the below table, you can use this shell script:
-
-```sh
-rustup toolchain install --profile minimal nightly
-MINOR_VERSION=$(rustc +nightly --version | cut -d . -f 2)
-LOWER_BOUND=61
-
-llvm_version() {
- toolchain="$1"
- printf "Rust $toolchain | Clang "
- rustc +"$toolchain" -Vv | grep LLVM | cut -d ':' -f 2 | tr -d ' '
-}
-
-for version in `seq $LOWER_BOUND $((MINOR_VERSION - 2))`; do
- toolchain=1.$version.0
- rustup toolchain install --no-self-update --profile minimal $toolchain >/dev/null 2>&1
- llvm_version $toolchain
-done
+<!-- NOTE: to update the below table, you can use this Python script:
+
+```python
+from collections import defaultdict
+import subprocess
+
+def minor_version(version):
+ return int(version.split('.')[1])
+
+INSTALL_TOOLCHAIN = ["rustup", "toolchain", "install", "--profile", "minimal"]
+subprocess.run(INSTALL_TOOLCHAIN + ["nightly"])
+
+LOWER_BOUND = 65
+NIGHTLY_VERSION = minor_version(subprocess.run(
+ ["rustc", "+nightly", "--version"],
+ capture_output=True,
+ text=True).stdout)
+
+def llvm_version(toolchain):
+ version_text = subprocess.run(
+ ["rustc", "+{}".format(toolchain), "-Vv"],
+ capture_output=True,
+ text=True).stdout
+ return int(version_text.split("LLVM")[1].split(':')[1].split('.')[0])
+
+version_map = defaultdict(lambda: [])
+for version in range(LOWER_BOUND, NIGHTLY_VERSION - 1):
+ toolchain = "1.{}.0".format(version)
+ subprocess.run(
+ INSTALL_TOOLCHAIN + ["--no-self-update", toolchain],
+ capture_output=True)
+ version_map[llvm_version(toolchain)].append(version)
+
+print("| Rust Version | Clang Version |")
+print("|--------------|---------------|")
+for clang, rust in sorted(version_map.items()):
+ if len(rust) > 1:
+ rust_range = "1.{} - 1.{}".format(rust[0], rust[-1])
+ else:
+ rust_range = "1.{} ".format(rust[0])
+ print("| {} | {} |".format(rust_range, clang))
```
-->
@@ -166,32 +189,13 @@ The following table shows known good combinations of toolchain versions.
| Rust Version | Clang Version |
|--------------|---------------|
-| Rust 1.34 | Clang 8 |
-| Rust 1.35 | Clang 8 |
-| Rust 1.36 | Clang 8 |
-| Rust 1.37 | Clang 8 |
-| Rust 1.38 | Clang 9 |
-| Rust 1.39 | Clang 9 |
-| Rust 1.40 | Clang 9 |
-| Rust 1.41 | Clang 9 |
-| Rust 1.42 | Clang 9 |
-| Rust 1.43 | Clang 9 |
-| Rust 1.44 | Clang 9 |
-| Rust 1.45 | Clang 10 |
-| Rust 1.46 | Clang 10 |
-| Rust 1.47 | Clang 11 |
-| Rust 1.48 | Clang 11 |
-| Rust 1.49 | Clang 11 |
-| Rust 1.50 | Clang 11 |
-| Rust 1.51 | Clang 11 |
-| Rust 1.52 | Clang 12 |
-| Rust 1.53 | Clang 12 |
-| Rust 1.54 | Clang 12 |
-| Rust 1.55 | Clang 12 |
-| Rust 1.56 | Clang 13 |
-| Rust 1.57 | Clang 13 |
-| Rust 1.58 | Clang 13 |
-| Rust 1.59 | Clang 13 |
-| Rust 1.60 | Clang 14 |
+| 1.34 - 1.37 | 8 |
+| 1.38 - 1.44 | 9 |
+| 1.45 - 1.46 | 10 |
+| 1.47 - 1.51 | 11 |
+| 1.52 - 1.55 | 12 |
+| 1.56 - 1.59 | 13 |
+| 1.60 - 1.64 | 14 |
+| 1.65 | 15 |
Note that the compatibility policy for this feature might change in the future.
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index a36518cc8..d0c3ddf26 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -128,6 +128,7 @@ target | std | notes
[`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android
`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat
`aarch64-unknown-none` | * | Bare ARM64, hardfloat
+[`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | * | ARM64 UEFI
[`arm-linux-androideabi`](platform-support/android.md) | ✓ | ARMv7 Android
`arm-unknown-linux-musleabi` | ✓ | ARMv6 Linux with MUSL
`arm-unknown-linux-musleabihf` | ✓ | ARMv6 Linux with MUSL, hardfloat
@@ -149,6 +150,7 @@ target | std | notes
[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android
`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD
`i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL
+[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI
`mips-unknown-linux-musl` | ✓ | MIPS Linux with MUSL
`mips64-unknown-linux-muslabi64` | ✓ | MIPS64 Linux, n64 ABI, MUSL
`mips64el-unknown-linux-muslabi64` | ✓ | MIPS64 (LE) Linux, n64 ABI, MUSL
@@ -181,6 +183,7 @@ target | std | notes
`x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
[`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat
`x86_64-unknown-redox` | ✓ | Redox OS
+[`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | 64-bit UEFI
[Fortanix ABI]: https://edp.fortanix.com/
@@ -211,9 +214,9 @@ target | std | host | notes
[`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3
[`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon
[`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
+[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.1 RTOS |
`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
`aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore
-[`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | * | | ARM64 UEFI
`aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI)
`aarch64-unknown-netbsd` | ✓ | ✓ |
[`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD
@@ -252,7 +255,6 @@ target | std | host | notes
`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku
`i686-unknown-netbsd` | ✓ | ✓ | NetBSD/i386 with SSE2
[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD
-[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | | 32-bit UEFI
`i686-uwp-windows-gnu` | ? | |
`i686-uwp-windows-msvc` | ? | |
`i686-wrs-vxworks` | ? | |
@@ -260,6 +262,7 @@ target | std | host | notes
`mips-unknown-linux-uclibc` | ✓ | | MIPS Linux with uClibc
[`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? | | MIPS64 for OpenWrt Linux MUSL
`mipsel-sony-psp` | * | | MIPS (LE) Sony PlayStation Portable (PSP)
+[`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX)
`mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc
`mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat
`mipsisa32r6-unknown-linux-gnu` | ? | |
@@ -280,6 +283,7 @@ target | std | host | notes
`powerpc64-wrs-vxworks` | ? | |
`powerpc64le-unknown-linux-musl` | ? | |
[`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64
+`powerpc64-ibm-aix` | ? | | 64-bit AIX (7.2 and newer)
`riscv32gc-unknown-linux-gnu` | | | RISC-V Linux (kernel 5.4, glibc 2.33)
`riscv32gc-unknown-linux-musl` | | | RISC-V Linux (kernel 5.4, musl + RISCV32 support patches)
`riscv32im-unknown-none-elf` | * | | Bare RISC-V (RV32IM ISA)
@@ -301,6 +305,7 @@ target | std | host | notes
`x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64
`x86_64-apple-tvos` | * | | x86 64-bit tvOS
[`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator
+[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ? | | x86 64-bit QNX Neutrino 7.1 RTOS |
[`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
`x86_64-pc-windows-msvc` | * | | 64-bit Windows XP support
`x86_64-sun-solaris` | ? | | Deprecated target for 64-bit Solaris 10/11, illumos
@@ -308,9 +313,7 @@ target | std | host | notes
`x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
`x86_64-unknown-hermit` | ✓ | | HermitCore
`x86_64-unknown-l4re-uclibc` | ? | |
-`x86_64-unknown-none-linuxkernel` | * | | Linux kernel modules
[`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD
-[`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | | 64-bit UEFI
`x86_64-uwp-windows-gnu` | ✓ | |
`x86_64-uwp-windows-msvc` | ✓ | |
`x86_64-wrs-vxworks` | ? | |
diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md
index 1ff6003c1..fbf999f97 100644
--- a/src/doc/rustc/src/platform-support/fuchsia.md
+++ b/src/doc/rustc/src/platform-support/fuchsia.md
@@ -189,17 +189,45 @@ Fuchsia as well. A recent version (14+) of clang should be sufficient to compile
Rust for Fuchsia.
x86-64 and AArch64 Fuchsia targets can be enabled using the following
-configuration.
-
-In `config.toml`, add:
+configuration in `config.toml`:
```toml
[build]
target = ["<host_platform>", "aarch64-fuchsia", "x86_64-fuchsia"]
+
+[rust]
+lld = true
+
+[target.x86_64-fuchsia]
+cc = "clang"
+cxx = "clang++"
+
+[target.aarch64-fuchsia]
+cc = "clang"
+cxx = "clang++"
+```
+
+Though not strictly required, you may also want to use `clang` for your host
+target as well:
+
+```toml
+[target.<host_platform>]
+cc = "clang"
+cxx = "clang++"
+```
+
+By default, the Rust compiler installs itself to `/usr/local` on most UNIX
+systems. You may want to install it to another location (e.g. a local `install`
+directory) by setting a custom prefix in `config.toml`:
+
+```toml
+[install]
+# Make sure to use the absolute path to your install directory
+prefix = "<RUST_SRC_PATH>/install"
```
-Additionally, the following environment variables must be configured (for
-example, using a script like `config-env.sh`):
+Next, the following environment variables must be configured. For example, using
+a script we name `config-env.sh`:
```sh
# Configure this environment variable to be the path to the downloaded SDK
@@ -215,8 +243,11 @@ export LDFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arc
export CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/x64/sysroot -Lnative=${SDK_PATH}/arch/x64/sysroot/lib -Lnative=${SDK_PATH}/arch/x64/lib"
```
-These can be run together in a shell environment by executing
-`(source config-env.sh && ./x.py install)`.
+Finally, the Rust compiler can be built and installed:
+
+```sh
+(source config-env.sh && ./x.py install)
+```
Once `rustc` is installed, we can create a new working directory to work from,
`hello_fuchsia` along with `hello_fuchsia/src`:
@@ -641,8 +672,72 @@ available on the [Fuchsia devsite].
### Running the compiler test suite
-Running the Rust test suite on Fuchsia is [not currently supported], but work is
-underway to enable it.
+The commands in this section assume that they are being run from inside your
+local Rust source checkout:
+
+```sh
+cd ${RUST_SRC_PATH}
+```
+
+To run the Rust test suite on an emulated Fuchsia device, you must install the
+Rust compiler locally. See "[Targeting Fuchsia with a compiler built from source](#targeting-fuchsia-with-a-compiler-built-from-source)"
+for the steps to build locally.
+
+You'll also need to download a copy of the Fuchsia SDK. The current minimum
+supported SDK version is [9.20220726.1.1](https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:9.20220726.1.1).
+
+Fuchsia's test runner interacts with the Fuchsia emulator and is located at
+`src/ci/docker/scripts/fuchsia-test-runner.py`. We can use it to start our
+test environment with:
+
+```sh
+src/ci/docker/scripts/fuchsia-test-runner.py start
+ --rust ${RUST_SRC_PATH}/install
+ --sdk ${SDK_PATH}
+ --target-arch {x64,arm64}
+```
+
+Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and
+`${SDK_PATH}` is the path to the downloaded and unzipped SDK.
+
+Once our environment is started, we can run our tests using `x.py` as usual. The
+test runner script will run the compiled tests on an emulated Fuchsia device. To
+run the full `src/test/ui` test suite:
+
+```sh
+( \
+ source config-env.sh && \
+ ./x.py \
+ --config config.toml \
+ --stage=2 \
+ test src/test/ui \
+ --target x86_64-fuchsia \
+ --run=always --jobs 1 \
+ --test-args --target-rustcflags \
+ --test-args -L \
+ --test-args --target-rustcflags \
+ --test-args ${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \
+ --test-args --target-rustcflags \
+ --test-args -L \
+ --test-args --target-rustcflags \
+ --test-args ${SDK_PATH}/arch/{x64|arm64}/lib \
+ --test-args --target-rustcflags \
+ --test-args -Cpanic=abort \
+ --test-args --target-rustcflags \
+ --test-args -Zpanic_abort_tests \
+ --test-args --remote-test-client \
+ --test-args src/ci/docker/scripts/fuchsia-test-runner.py \
+)
+```
+
+*Note: The test suite cannot be run in parallel at the moment, so `x.py`
+must be run with `--jobs 1` to ensure only one test runs at a time.*
+
+When finished, the test runner can be used to stop the test environment:
+
+```sh
+src/ci/docker/scripts/fuchsia-test-runner.py stop
+```
## Debugging
diff --git a/src/doc/rustc/src/platform-support/mipsel-sony-psx.md b/src/doc/rustc/src/platform-support/mipsel-sony-psx.md
new file mode 100644
index 000000000..589100e88
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/mipsel-sony-psx.md
@@ -0,0 +1,49 @@
+# mipsel-sony-psx
+
+**Tier: 3**
+
+Sony PlayStation 1 (psx)
+
+## Designated Developer
+
+* [@ayrtonm](https://github.com/ayrtonm)
+
+## Requirements
+
+This target is cross-compiled.
+It has no special requirements for the host.
+
+## Building
+
+The target can be built by enabling it for a `rustc` build:
+
+```toml
+[build]
+build-stage = 1
+target = ["mipsel-sony-psx"]
+```
+
+## Cross-compilation
+
+This target can be cross-compiled from any host.
+
+## Testing
+
+Currently there is no support to run the rustc test suite for this target.
+
+## Building Rust programs
+
+Since it is Tier 3, rust doesn't ship pre-compiled artifacts for this target.
+
+Just use the `build-std` nightly cargo feature to build the `core` and `alloc` libraries:
+```shell
+cargo build -Zbuild-std=core,alloc --target mipsel-sony-psx
+```
+
+The command above generates an ELF. To generate binaries in the PSEXE format that emulators run, you can use [cargo-psx](https://github.com/ayrtonm/psx-sdk-rs#readme):
+
+```shell
+cargo psx build
+```
+
+or use `-Clink-arg=--oformat=binary` to produce a flat binary.
diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md
new file mode 100644
index 000000000..37d0c3197
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/nto-qnx.md
@@ -0,0 +1,118 @@
+# nto-qnx
+
+**Tier: 3**
+
+[BlackBerry® QNX®][BlackBerry] Neutrino (nto) Real-time operating system.
+The support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit]
+and [BlackBerry][BlackBerry].
+
+[BlackBerry]: https://blackberry.qnx.com
+[Elektrobit]: https://www.elektrobit.com
+
+## Target maintainers
+
+- Florian Bartels, `Florian.Bartels@elektrobit.com`, https://github.com/flba-eb
+- Tristan Roach, `TRoach@blackberry.com`, https://github.com/gh-tr
+
+## Requirements
+
+Currently, only cross-compilation for QNX Neutrino on AArch64 and x86_64 are supported (little endian).
+Adding other architectures that are supported by QNX Neutrino is possible.
+
+The standard library does not yet support QNX Neutrino. Therefore, only `no_std` code can
+be compiled.
+
+`core` and `alloc` (with default allocator) are supported.
+
+Applications must link against `libc.so` (see example). This is required because applications
+always link against the `crt` library and `crt` depends on `libc.so`.
+
+The correct version of `qcc` must be available by setting the `$PATH` variable (e.g. by sourcing `qnxsdp-env.sh` of the
+QNX Neutrino toolchain).
+
+### Small example application
+
+```rust,ignore (platform-specific)
+#![no_std]
+#![no_main]
+#![feature(lang_items)]
+
+// We must always link against libc, even if no external functions are used
+// "extern C" - Block can be empty but must be present
+#[link(name = "c")]
+extern "C" {
+ pub fn printf(format: *const core::ffi::c_char, ...) -> core::ffi::c_int;
+}
+
+#[no_mangle]
+pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
+ const HELLO: &'static str = "Hello World, the answer is %d\n\0";
+ unsafe {
+ printf(HELLO.as_ptr() as *const _, 42);
+ }
+ 0
+}
+
+use core::panic::PanicInfo;
+
+#[panic_handler]
+fn panic(_panic: &PanicInfo<'_>) -> ! {
+ loop {}
+}
+
+#[lang = "eh_personality"]
+#[no_mangle]
+pub extern "C" fn rust_eh_personality() {}
+```
+
+The QNX Neutrino support of Rust has been tested with QNX Neutrino 7.1.
+
+There are no further known requirements.
+
+## Conditional compilation
+
+For conditional compilation, following QNX Neutrino specific attributes are defined:
+
+- `target_os` = `"nto"`
+- `target_env` = `"nto71"` (for QNX Neutrino 7.1)
+
+## Building the target
+
+1. Create a `config.toml`
+
+Example content:
+
+```toml
+profile = "compiler"
+changelog-seen = 2
+```
+
+2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host (for both `aarch64` and `x86_64` targets)
+
+Run the following:
+
+```bash
+env \
+ CC_aarch64-unknown-nto-qnx710="qcc" \
+ CFLAGS_aarch64-unknown-nto-qnx710="-Vgcc_ntoaarch64le_cxx" \
+ CXX_aarch64-unknown-nto-qnx710="qcc" \
+ AR_aarch64_unknown_nto_qnx710="ntoaarch64-ar" \
+ CC_x86_64-pc-nto-qnx710="qcc" \
+ CFLAGS_x86_64-pc-nto-qnx710="-Vgcc_ntox86_64_cxx" \
+ CXX_x86_64-pc-nto-qnx710="qcc" \
+ AR_x86_64_pc_nto_qnx710="ntox86_64-ar" \
+ ./x.py build --target aarch64-unknown-nto-qnx710 --target x86_64-pc-nto-qnx710 --target x86_64-unknown-linux-gnu rustc library/core library/alloc/
+```
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for this target, you must either build Rust with the target enabled (see "Building the target" above), or build your own copy of `core` by using
+`build-std` or similar.
+
+## Testing
+
+Compiled executables can directly be run on QNX Neutrino.
+
+## Cross-compilation toolchains and C code
+
+Compiling C code requires the same environment variables to be set as compiling the Rust toolchain (see above), to ensure `qcc` is used with proper arguments. To ensure compatibility, do not specify any further arguments that for example change calling conventions or memory layout.
diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md
index 295dec0f0..e2bdf73a9 100644
--- a/src/doc/rustc/src/platform-support/unknown-uefi.md
+++ b/src/doc/rustc/src/platform-support/unknown-uefi.md
@@ -1,6 +1,6 @@
# `*-unknown-uefi`
-**Tier: 3**
+**Tier: 2**
Unified Extensible Firmware Interface (UEFI) targets for application, driver,
and core UEFI binaries.
@@ -72,28 +72,14 @@ target = ["x86_64-unknown-uefi"]
## Building Rust programs
-Rust does not yet ship pre-compiled artifacts for this target. To compile for
-this target, you will either need to build Rust with the target enabled (see
-"Building rust for UEFI targets" above), or build your own copy of `core` by
-using `build-std`, `cargo-buildx`, or similar.
-
-A native build with the unstable `build-std`-feature can be achieved via:
-
-```sh
-cargo +nightly build \
- -Zbuild-std=core,compiler_builtins \
- -Zbuild-std-features=compiler-builtins-mem \
- --target x86_64-unknown-uefi
-```
-
-Alternatively, you can install `cargo-xbuild` via
-`cargo install --force cargo-xbuild` and build for the UEFI targets via:
+Starting with Rust 1.67, precompiled artifacts are provided via
+`rustup`. For example, to use `x86_64-unknown-uefi`:
```sh
-cargo \
- +nightly \
- xbuild \
- --target x86_64-unknown-uefi
+# install cross-compile toolchain
+rustup target add x86_64-unknown-uefi
+# target flag may be used with any cargo or rustc command
+cargo build --target x86_64-unknown-uefi
```
## Testing
@@ -167,18 +153,10 @@ The following code is a valid UEFI application returning immediately upon
execution with an exit code of 0. A panic handler is provided. This is executed
by rust on panic. For simplicity, we simply end up in an infinite loop.
-Note that as of rust-1.31.0, all features used here are stabilized. No unstable
-features are required, nor do we rely on nightly compilers. However, if you do
-not compile rustc for the UEFI targets, you need a nightly compiler to support
-the `-Z build-std` flag.
-
This example can be compiled as binary crate via `cargo`:
```sh
-cargo +nightly build \
- -Zbuild-std=core,compiler_builtins \
- -Zbuild-std-features=compiler-builtins-mem \
- --target x86_64-unknown-uefi
+cargo build --target x86_64-unknown-uefi
```
```rust,ignore (platform-specific,eh-personality-is-unstable)
diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md
index 53d0470fa..95932db14 100644
--- a/src/doc/rustc/src/target-tier-policy.md
+++ b/src/doc/rustc/src/target-tier-policy.md
@@ -3,6 +3,7 @@
## Table of Contents
* [General](#general)
+* [Adding a new target](#adding-a-new-target)
* [Tier 3 target policy](#tier-3-target-policy)
* [Tier 2 target policy](#tier-2-target-policy)
* [Tier 2 with host tools](#tier-2-with-host-tools)
@@ -104,6 +105,30 @@ indicates something entirely optional, and does not indicate guidance or
recommendations. This language is based on [IETF RFC
2119](https://tools.ietf.org/html/rfc2119).
+## Adding a new target
+
+New targets typically start as Tier 3 and then can be promoted later.
+To propose addition of a new target, open a pull request on [`rust-lang/rust`]:
+
+- Copy the [Tier 3 target policy](#tier-3-target-policy) to the description
+ and fill it out, see [example][tier3example].
+- Add a new description for the target in `src/doc/rustc/src/platform-support`
+ using the [template][platform_template].
+- Add the target to the [SUMMARY.md][summary] (allows wildcards) and
+ [platform-support.md][platformsupport] (must name all targets verbatim).
+ Link to the created description page.
+- Ensure the pull request is assigned to a member of the [Rust compiler team][rust_compiler_team] by commenting:
+ ```text
+ r? compiler-team
+ ```
+
+[tier3example]: https://github.com/rust-lang/rust/pull/94872
+[platform_template]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support/TEMPLATE.md
+[summary]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/SUMMARY.md
+[platformsupport]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support.md
+[rust_compiler_team]: https://www.rust-lang.org/governance/teams/compiler
+[`rust-lang/rust`]: https://github.com/rust-lang/rust
+
## Tier 3 target policy
At this tier, the Rust project provides no official support for a target, so we
@@ -133,6 +158,8 @@ approved by the appropriate team for that shared code before acceptance.
the name of the target makes people extremely likely to form incorrect
beliefs about what it targets, the name should be changed or augmented to
disambiguate it.
+ - If possible, use only letters, numbers, dashes and underscores for the name.
+ Periods (`.`) are known to cause issues in Cargo.
- Tier 3 targets may have unusual requirements to build or use, but must not
create legal issues or impose onerous legal terms for the Rust project or for
Rust developers or users.
diff --git a/src/doc/rustdoc/book.toml b/src/doc/rustdoc/book.toml
index 45405a117..dfa685785 100644
--- a/src/doc/rustdoc/book.toml
+++ b/src/doc/rustdoc/book.toml
@@ -6,5 +6,9 @@ title = "The rustdoc book"
git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/rustdoc"
[output.html.redirect]
+"/what-to-include.html" = "write-documentation/what-to-include.html"
"/the-doc-attribute.html" = "write-documentation/the-doc-attribute.html"
+"/linking-to-items-by-name.html" = "write-documentation/linking-to-items-by-name.html"
"/documentation-tests.html" = "write-documentation/documentation-tests.html"
+"/website-features.html" = "advanced-features.html#custom-search-engines"
+"/passes.html" = "deprecated-features.html#passes"
diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md
index bff01d7cb..45db3bb9b 100644
--- a/src/doc/rustdoc/src/lints.md
+++ b/src/doc/rustdoc/src/lints.md
@@ -261,7 +261,7 @@ typo mistakes for some common attributes.
## `invalid_html_tags`
-This lint is **allowed by default** and is **nightly-only**. It detects unclosed
+This lint **warns by default**. It detects unclosed
or invalid HTML tags. For example:
```rust
diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md
index b02b3c047..216689731 100644
--- a/src/doc/style-guide/src/principles.md
+++ b/src/doc/style-guide/src/principles.md
@@ -8,7 +8,9 @@ following principles (in rough priority order):
- avoiding misleading formatting
- accessibility - readable and editable by users using the the widest
variety of hardware, including non-visual accessibility interfaces
- - readability of code when quoted in rustc error messages
+ - readability of code in contexts without syntax highlighting or IDE
+ assistance, such as rustc error messages, diffs, grep, and other
+ plain-text contexts
* aesthetics
- sense of 'beauty'
diff --git a/src/doc/unstable-book/src/language-features/abi-efiapi.md b/src/doc/unstable-book/src/language-features/abi-efiapi.md
new file mode 100644
index 000000000..b492da884
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/abi-efiapi.md
@@ -0,0 +1,23 @@
+# `abi_efiapi`
+
+The tracking issue for this feature is: [#65815]
+
+[#65815]: https://github.com/rust-lang/rust/issues/65815
+
+------------------------
+
+The `efiapi` calling convention can be used for defining a function with
+an ABI compatible with the UEFI Interfaces as defined in the [UEFI
+Specification].
+
+Example:
+
+```rust,ignore (not-all-targets-support-uefi)
+#![feature(abi_efiapi)]
+
+extern "efiapi" { fn f1(); }
+
+extern "efiapi" fn f2() { todo!() }
+```
+
+[UEFI Specification]: https://uefi.org/specs/UEFI/2.10/
diff --git a/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md
new file mode 100644
index 000000000..b20c30ec8
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md
@@ -0,0 +1,10 @@
+# `extended_varargs_abi_support`
+
+The tracking issue for this feature is: [#100189]
+
+[#100189]: https://github.com/rust-lang/rust/issues/100189
+
+------------------------
+
+This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling
+conventions on functions with varargs.
diff --git a/src/doc/unstable-book/src/language-features/native-link-modifiers-verbatim.md b/src/doc/unstable-book/src/language-features/native-link-modifiers-verbatim.md
deleted file mode 100644
index 02bd87e50..000000000
--- a/src/doc/unstable-book/src/language-features/native-link-modifiers-verbatim.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# `native_link_modifiers_verbatim`
-
-The tracking issue for this feature is: [#81490]
-
-[#81490]: https://github.com/rust-lang/rust/issues/81490
-
-------------------------
-
-The `native_link_modifiers_verbatim` feature allows you to use the `verbatim` modifier.
-
-`+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes (like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the linker.
-
-For `ld`-like linkers rustc will use the `-l:filename` syntax (note the colon) when passing the library, so the linker won't add any prefixes or suffixes as well.
-See [`-l namespec`](https://sourceware.org/binutils/docs/ld/Options.html) in ld documentation for more details.
-For linkers not supporting any verbatim modifiers (e.g. `link.exe` or `ld64`) the library name will be passed as is.
-
-The default for this modifier is `-verbatim`.
-
-This RFC changes the behavior of `raw-dylib` linking kind specified by [RFC 2627](https://github.com/rust-lang/rfcs/pull/2627). The `.dll` suffix (or other target-specified suffixes for other targets) is now added automatically.
-If your DLL doesn't have the `.dll` suffix, it can be specified with `+verbatim`.
diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py
index c351c3450..32b8d8e24 100644
--- a/src/etc/gdb_providers.py
+++ b/src/etc/gdb_providers.py
@@ -144,20 +144,16 @@ class StdVecDequeProvider:
def __init__(self, valobj):
self.valobj = valobj
self.head = int(valobj["head"])
- self.tail = int(valobj["tail"])
+ self.size = int(valobj["len"])
self.cap = int(valobj["buf"]["cap"])
self.data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
- if self.head >= self.tail:
- self.size = self.head - self.tail
- else:
- self.size = self.cap + self.head - self.tail
def to_string(self):
return "VecDeque(size={})".format(self.size)
def children(self):
return _enumerate_array_elements(
- (self.data_ptr + ((self.tail + index) % self.cap)) for index in xrange(self.size)
+ (self.data_ptr + ((self.head + index) % self.cap)) for index in xrange(self.size)
)
@staticmethod
diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py
index 8a9927e7d..697ad4293 100644
--- a/src/etc/lldb_providers.py
+++ b/src/etc/lldb_providers.py
@@ -356,7 +356,7 @@ class StdSliceSyntheticProvider:
class StdVecDequeSyntheticProvider:
"""Pretty-printer for alloc::collections::vec_deque::VecDeque<T>
- struct VecDeque<T> { tail: usize, head: usize, buf: RawVec<T> }
+ struct VecDeque<T> { head: usize, len: usize, buf: RawVec<T> }
"""
def __init__(self, valobj, dict):
@@ -373,7 +373,7 @@ class StdVecDequeSyntheticProvider:
def get_child_index(self, name):
# type: (str) -> int
index = name.lstrip('[').rstrip(']')
- if index.isdigit() and self.tail <= index and (self.tail + index) % self.cap < self.head:
+ if index.isdigit() and int(index) < self.size:
return int(index)
else:
return -1
@@ -381,20 +381,16 @@ class StdVecDequeSyntheticProvider:
def get_child_at_index(self, index):
# type: (int) -> SBValue
start = self.data_ptr.GetValueAsUnsigned()
- address = start + ((index + self.tail) % self.cap) * self.element_type_size
+ address = start + ((index + self.head) % self.cap) * self.element_type_size
element = self.data_ptr.CreateValueFromAddress("[%s]" % index, address, self.element_type)
return element
def update(self):
# type: () -> None
self.head = self.valobj.GetChildMemberWithName("head").GetValueAsUnsigned()
- self.tail = self.valobj.GetChildMemberWithName("tail").GetValueAsUnsigned()
+ self.size = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()
self.buf = self.valobj.GetChildMemberWithName("buf")
self.cap = self.buf.GetChildMemberWithName("cap").GetValueAsUnsigned()
- if self.head >= self.tail:
- self.size = self.head - self.tail
- else:
- self.size = self.cap + self.head - self.tail
self.data_ptr = unwrap_unique_or_non_null(self.buf.GetChildMemberWithName("ptr"))
diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis
index 277e57aaf..8c16a562e 100644
--- a/src/etc/natvis/intrinsic.natvis
+++ b/src/etc/natvis/intrinsic.natvis
@@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
- <Type Name="str">
+ <Type Name="ref$&lt;str$&gt;">
+ <AlternativeType Name="ref_mut$&lt;str$&gt;" />
+ <AlternativeType Name="ptr_const$&lt;str$&gt;" />
+ <AlternativeType Name="ptr_mut$&lt;str$&gt;" />
+
<DisplayString>{(char*)data_ptr,[length]s8}</DisplayString>
<StringView>(char*)data_ptr,[length]s8</StringView>
<Expand>
@@ -15,7 +19,11 @@
</Synthetic>
</Expand>
</Type>
- <Type Name="slice$&lt;*&gt;">
+ <Type Name="ref$&lt;slice2$&lt;*&gt; &gt;">
+ <AlternativeType Name="ref_mut$&lt;slice2$&lt;*&gt; &gt;" />
+ <AlternativeType Name="ptr_const$&lt;slice2$&lt;*&gt; &gt;" />
+ <AlternativeType Name="ptr_mut$&lt;slice2$&lt;*&gt; &gt;" />
+
<DisplayString>{{ len={length} }}</DisplayString>
<Expand>
<Item Name="[len]" ExcludeView="simple">length</Item>
diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis
index bf6c02b91..c4ad98ec1 100644
--- a/src/etc/natvis/liballoc.natvis
+++ b/src/etc/natvis/liballoc.natvis
@@ -12,20 +12,19 @@
</Expand>
</Type>
<Type Name="alloc::collections::vec_deque::VecDeque&lt;*&gt;">
- <DisplayString>{{ len={tail &lt;= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
+ <DisplayString>{{ len={len} }}</DisplayString>
<Expand>
- <Item Name="[len]" ExcludeView="simple">tail &lt;= head ? head - tail : buf.cap - tail + head</Item>
+ <Item Name="[len]" ExcludeView="simple">len</Item>
<Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
<CustomListItems>
- <Variable Name="i" InitialValue="tail" />
-
- <Size>tail &lt;= head ? head - tail : buf.cap - tail + head</Size>
+ <Variable Name="i" InitialValue="0" />
+ <Size>len</Size>
<Loop>
- <If Condition="i == head">
+ <If Condition="i == len">
<Break/>
</If>
- <Item>buf.ptr.pointer.pointer[i]</Item>
- <Exec>i = (i + 1 == buf.cap ? 0 : i + 1)</Exec>
+ <Item>buf.ptr.pointer.pointer[(i + head) % buf.cap]</Item>
+ <Exec>i = i + 1</Exec>
</Loop>
</CustomListItems>
</Expand>
@@ -85,7 +84,7 @@
</Type>
<!-- alloc::rc::Rc<[T]> -->
- <Type Name="alloc::rc::Rc&lt;slice$&lt;*&gt; &gt;">
+ <Type Name="alloc::rc::Rc&lt;slice2$&lt;*&gt; &gt;">
<DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
<Expand>
<Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
@@ -115,7 +114,7 @@
</Type>
<!-- alloc::rc::Weak<[T]> -->
- <Type Name="alloc::rc::Weak&lt;slice$&lt;*&gt; &gt;">
+ <Type Name="alloc::rc::Weak&lt;slice2$&lt;*&gt; &gt;">
<DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
<Expand>
<Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
@@ -144,7 +143,7 @@
</Type>
<!-- alloc::sync::Arc<[T]> -->
- <Type Name="alloc::sync::Arc&lt;slice$&lt;*&gt; &gt;">
+ <Type Name="alloc::sync::Arc&lt;slice2$&lt;*&gt; &gt;">
<DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
<Expand>
<Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
@@ -173,7 +172,7 @@
</Type>
<!-- alloc::sync::Weak<[T]> -->
- <Type Name="alloc::sync::Weak&lt;slice$&lt;*&gt; &gt;">
+ <Type Name="alloc::sync::Weak&lt;slice2$&lt;*&gt; &gt;">
<DisplayString>{{ len={ptr.pointer.length} }}</DisplayString>
<Expand>
<Item Name="[Length]" ExcludeView="simple">ptr.pointer.length</Item>
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 7bc35c7d5..0271c27b4 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -9,7 +9,6 @@ path = "lib.rs"
[dependencies]
arrayvec = { version = "0.7", default-features = false }
askama = { version = "0.11", default-features = false, features = ["config"] }
-atty = "0.2"
itertools = "0.10.1"
minifier = "0.2.2"
once_cell = "1.10.0"
@@ -20,7 +19,7 @@ serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
smallvec = "1.8.1"
tempfile = "3"
-thin-vec = "0.2.8"
+thin-vec = "0.2.9"
tracing = "0.1"
tracing-tree = "0.2.0"
@@ -33,7 +32,7 @@ features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"]
rayon = "1.5.1"
[dev-dependencies]
-expect-test = "1.0"
+expect-test = "1.4.0"
[features]
jemalloc = []
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 764a6d3aa..953f4aa8a 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -3,6 +3,7 @@ use rustc_hir as hir;
use rustc_hir::lang_items::LangItem;
use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable, TypeSuperFoldable};
use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult};
+use thin_vec::ThinVec;
use std::fmt::Debug;
@@ -43,7 +44,7 @@ where
discard_positive_impl: bool,
) -> Option<Item> {
let tcx = self.cx.tcx;
- let trait_ref = ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(ty, &[]) };
+ let trait_ref = tcx.mk_trait_ref(trait_def_id, [ty]);
if !self.cx.generated_synthetics.insert((ty, trait_def_id)) {
debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref);
return None;
@@ -110,7 +111,7 @@ where
);
let params = raw_generics.params;
- Generics { params, where_predicates: Vec::new() }
+ Generics { params, where_predicates: ThinVec::new() }
}
AutoTraitResult::ExplicitImpl => return None,
};
@@ -118,7 +119,6 @@ where
Some(Item {
name: None,
attrs: Default::default(),
- visibility: Inherited,
item_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id },
kind: Box::new(ImplItem(Box::new(Impl {
unsafety: hir::Unsafety::Normal,
@@ -130,6 +130,7 @@ where
kind: ImplKind::Auto,
}))),
cfg: None,
+ inline_stmt_id: None,
})
}
@@ -183,7 +184,7 @@ where
fn handle_lifetimes<'cx>(
regions: &RegionConstraintData<'cx>,
names_map: &FxHashMap<Symbol, Lifetime>,
- ) -> Vec<WherePredicate> {
+ ) -> ThinVec<WherePredicate> {
// Our goal is to 'flatten' the list of constraints by eliminating
// all intermediate RegionVids. At the end, all constraints should
// be between Regions (aka region variables). This gives us the information
@@ -320,10 +321,10 @@ where
let bound_predicate = pred.kind();
let tcx = self.cx.tcx;
let regions = match bound_predicate.skip_binder() {
- ty::PredicateKind::Trait(poly_trait_pred) => {
+ ty::PredicateKind::Clause(ty::Clause::Trait(poly_trait_pred)) => {
tcx.collect_referenced_late_bound_regions(&bound_predicate.rebind(poly_trait_pred))
}
- ty::PredicateKind::Projection(poly_proj_pred) => {
+ ty::PredicateKind::Clause(ty::Clause::Projection(poly_proj_pred)) => {
tcx.collect_referenced_late_bound_regions(&bound_predicate.rebind(poly_proj_pred))
}
_ => return FxHashSet::default(),
@@ -335,10 +336,7 @@ where
match br {
// We only care about named late bound regions, as we need to add them
// to the 'for<>' section
- ty::BrNamed(_, name) => Some(GenericParamDef {
- name,
- kind: GenericParamDefKind::Lifetime { outlives: vec![] },
- }),
+ ty::BrNamed(_, name) => Some(GenericParamDef::lifetime(name)),
_ => None,
}
})
@@ -429,7 +427,7 @@ where
&mut self,
item_def_id: DefId,
param_env: ty::ParamEnv<'tcx>,
- mut existing_predicates: Vec<WherePredicate>,
+ mut existing_predicates: ThinVec<WherePredicate>,
vid_to_region: FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
) -> Generics {
debug!(
@@ -453,7 +451,9 @@ where
.filter(|p| {
!orig_bounds.contains(p)
|| match p.kind().skip_binder() {
- ty::PredicateKind::Trait(pred) => pred.def_id() == sized_trait,
+ ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => {
+ pred.def_id() == sized_trait
+ }
_ => false,
}
})
@@ -663,7 +663,7 @@ where
/// both for visual consistency between 'rustdoc' runs, and to
/// make writing tests much easier
#[inline]
- fn sort_where_predicates(&self, predicates: &mut Vec<WherePredicate>) {
+ fn sort_where_predicates(&self, predicates: &mut [WherePredicate]) {
// We should never have identical bounds - and if we do,
// they're visually identical as well. Therefore, using
// an unstable sort is fine.
@@ -710,7 +710,7 @@ where
/// approach is probably somewhat slower, but the small number of items
/// involved (impls rarely have more than a few bounds) means that it
/// shouldn't matter in practice.
- fn unstable_debug_sort<T: Debug>(&self, vec: &mut Vec<T>) {
+ fn unstable_debug_sort<T: Debug>(&self, vec: &mut [T]) {
vec.sort_by_cached_key(|x| format!("{:?}", x))
}
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 8b63c3db3..a1145b90d 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -20,7 +20,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
trace!("get_blanket_impls({:?})", ty);
let mut impls = Vec::new();
for trait_def_id in cx.tcx.all_traits() {
- if !cx.cache.effective_visibilities.is_directly_public(trait_def_id)
+ if !cx.cache.effective_visibilities.is_directly_public(cx.tcx, trait_def_id)
|| cx.generated_synthetics.get(&(ty.0, trait_def_id)).is_some()
{
continue;
@@ -67,15 +67,11 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
.instantiate(cx.tcx, impl_substs)
.predicates
.into_iter()
- .chain(Some(
- ty::Binder::dummy(impl_trait_ref)
- .to_poly_trait_predicate()
- .map_bound(ty::PredicateKind::Trait)
- .to_predicate(infcx.tcx),
- ));
+ .chain(Some(ty::Binder::dummy(impl_trait_ref).to_predicate(infcx.tcx)));
for predicate in predicates {
debug!("testing predicate {:?}", predicate);
let obligation = traits::Obligation::new(
+ infcx.tcx,
traits::ObligationCause::dummy(),
param_env,
predicate,
@@ -97,7 +93,6 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
impls.push(Item {
name: None,
attrs: Default::default(),
- visibility: Inherited,
item_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
kind: Box::new(ImplItem(Box::new(Impl {
unsafety: hir::Unsafety::Normal,
@@ -128,6 +123,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
))),
}))),
cfg: None,
+ inline_stmt_id: None,
});
}
}
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index f33f5d27d..1843a2120 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -50,7 +50,7 @@ impl Cfg {
) -> Result<Option<Cfg>, InvalidCfgError> {
match nested_cfg {
NestedMetaItem::MetaItem(ref cfg) => Cfg::parse_without(cfg, exclude),
- NestedMetaItem::Literal(ref lit) => {
+ NestedMetaItem::Lit(ref lit) => {
Err(InvalidCfgError { msg: "unexpected literal", span: lit.span })
}
}
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 4e2031a91..e7c3e5a45 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -3,7 +3,7 @@
use std::iter::once;
use std::sync::Arc;
-use thin_vec::ThinVec;
+use thin_vec::{thin_vec, ThinVec};
use rustc_ast as ast;
use rustc_data_structures::fx::FxHashSet;
@@ -19,8 +19,7 @@ use rustc_span::symbol::{kw, sym, Symbol};
use crate::clean::{
self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_assoc_item,
clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty,
- clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt,
- ImplKind, ItemId, Type, Visibility,
+ clean_ty_generics, clean_variant_def, utils, Attributes, AttributesExt, ImplKind, ItemId, Type,
};
use crate::core::DocContext;
use crate::formats::item_type::ItemType;
@@ -152,18 +151,10 @@ pub(crate) fn try_inline(
let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs);
cx.inlined.insert(did.into());
- let mut item = clean::Item::from_def_id_and_attrs_and_parts(
- did,
- Some(name),
- kind,
- Box::new(attrs),
- cx,
- cfg,
- );
- if let Some(import_def_id) = import_def_id {
- // The visibility needs to reflect the one from the reexport and not from the "source" DefId.
- item.visibility = clean_visibility(cx.tcx.visibility(import_def_id));
- }
+ let mut item =
+ clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, Box::new(attrs), cfg);
+ // The visibility needs to reflect the one from the reexport and not from the "source" DefId.
+ item.inline_stmt_id = import_def_id;
ret.push(item);
Some(ret)
}
@@ -239,13 +230,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
.tcx
.associated_items(did)
.in_definition_order()
- .map(|item| {
- // When building an external trait, the cleaned trait will have all items public,
- // which causes methods to have a `pub` prefix, which is invalid since items in traits
- // can not have a visibility prefix. Thus we override the visibility here manually.
- // See https://github.com/rust-lang/rust/issues/81274
- clean::Item { visibility: Visibility::Inherited, ..clean_middle_assoc_item(item, cx) }
- })
+ .map(|item| clean_middle_assoc_item(item, cx))
.collect();
let predicates = cx.tcx.predicates_of(did);
@@ -258,10 +243,19 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<clean::Function> {
let sig = cx.tcx.fn_sig(did);
- let predicates = cx.tcx.predicates_of(did);
+ let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var {
+ ty::BoundVariableKind::Region(ty::BrNamed(_, name)) if name != kw::UnderscoreLifetime => {
+ Some(clean::GenericParamDef::lifetime(name))
+ }
+ _ => None,
+ });
+
+ let predicates = cx.tcx.explicit_predicates_of(did);
let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
// NOTE: generics need to be cleaned before the decl!
- let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
+ let mut generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
+ // FIXME: This does not place parameters in source order (late-bound ones come last)
+ generics.params.extend(late_bound_regions);
let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig);
(generics, decl)
});
@@ -282,7 +276,7 @@ fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct {
let variant = cx.tcx.adt_def(did).non_enum_variant();
clean::Struct {
- struct_type: variant.ctor_kind,
+ ctor_kind: variant.ctor_kind(),
generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
fields: variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(),
}
@@ -389,7 +383,7 @@ pub(crate) fn build_impl(
if !did.is_local() {
if let Some(traitref) = associated_trait {
let did = traitref.def_id;
- if !cx.cache.effective_visibilities.is_directly_public(did) {
+ if !cx.cache.effective_visibilities.is_directly_public(tcx, did) {
return;
}
@@ -418,7 +412,7 @@ pub(crate) fn build_impl(
// reachable in rustdoc generated documentation
if !did.is_local() {
if let Some(did) = for_.def_id(&cx.cache) {
- if !cx.cache.effective_visibilities.is_directly_public(did) {
+ if !cx.cache.effective_visibilities.is_directly_public(tcx, did) {
return;
}
@@ -559,7 +553,6 @@ pub(crate) fn build_impl(
},
})),
Box::new(merged_attrs),
- cx,
cfg,
));
}
@@ -607,13 +600,12 @@ fn build_module_items(
name: None,
attrs: Box::new(clean::Attributes::default()),
item_id: ItemId::Primitive(prim_ty, did.krate),
- visibility: clean::Public,
kind: Box::new(clean::ImportItem(clean::Import::new_simple(
item.ident.name,
clean::ImportSource {
path: clean::Path {
res,
- segments: vec![clean::PathSegment {
+ segments: thin_vec![clean::PathSegment {
name: prim_ty.as_sym(),
args: clean::GenericArgs::AngleBracketed {
args: Default::default(),
@@ -626,6 +618,7 @@ fn build_module_items(
true,
))),
cfg: None,
+ inline_stmt_id: None,
});
} else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) {
items.extend(i)
@@ -669,7 +662,7 @@ fn build_macro(
match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) {
LoadedMacro::MacroDef(item_def, _) => {
if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
- let vis = clean_visibility(cx.tcx.visibility(import_def_id.unwrap_or(def_id)));
+ let vis = cx.tcx.visibility(import_def_id.unwrap_or(def_id));
clean::MacroItem(clean::Macro {
source: utils::display_macro_source(cx, name, def, def_id, vis),
})
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 64a18757b..2a2a9470d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -12,7 +12,7 @@ pub(crate) mod utils;
use rustc_ast as ast;
use rustc_attr as attr;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
@@ -74,12 +74,12 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
// This covers the case where somebody does an import which should pull in an item,
// but there's already an item with the same namespace and same name. Rust gives
// priority to the not-imported one, so we should, too.
- items.extend(doc.items.iter().flat_map(|(item, renamed)| {
+ items.extend(doc.items.iter().flat_map(|(item, renamed, import_id)| {
// First, lower everything other than imports.
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
return Vec::new();
}
- let v = clean_maybe_renamed_item(cx, item, *renamed);
+ let v = clean_maybe_renamed_item(cx, item, *renamed, *import_id);
for item in &v {
if let Some(name) = item.name && !item.attrs.lists(sym::doc).has_word(sym::hidden) {
inserted.insert((item.type_(), name));
@@ -87,7 +87,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
}
v
}));
- items.extend(doc.items.iter().flat_map(|(item, renamed)| {
+ items.extend(doc.items.iter().flat_map(|(item, renamed, _)| {
// Now we actually lower the imports, skipping everything else.
if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind {
let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
@@ -182,10 +182,7 @@ fn clean_poly_trait_ref_with_bindings<'tcx>(
.collect_referenced_late_bound_regions(&poly_trait_ref)
.into_iter()
.filter_map(|br| match br {
- ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => Some(GenericParamDef {
- name,
- kind: GenericParamDefKind::Lifetime { outlives: vec![] },
- }),
+ ty::BrNamed(_, name) if br.is_named() => Some(GenericParamDef::lifetime(name)),
_ => None,
})
.collect();
@@ -209,7 +206,7 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) ->
return lt;
}
}
- Lifetime(lifetime.name.ident().name)
+ Lifetime(lifetime.ident.name)
}
pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'tcx>) -> Constant {
@@ -227,23 +224,18 @@ pub(crate) fn clean_middle_const<'tcx>(
// FIXME: instead of storing the stringified expression, store `self` directly instead.
Constant {
type_: clean_middle_ty(constant.ty(), cx, None),
- kind: ConstantKind::TyConst { expr: constant.to_string() },
+ kind: ConstantKind::TyConst { expr: constant.to_string().into() },
}
}
pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Lifetime> {
match *region {
ty::ReStatic => Some(Lifetime::statik()),
+ _ if !region.has_name() => None,
ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) => {
- if name != kw::UnderscoreLifetime { Some(Lifetime(name)) } else { None }
- }
- ty::ReEarlyBound(ref data) => {
- if data.name != kw::UnderscoreLifetime {
- Some(Lifetime(data.name))
- } else {
- None
- }
+ Some(Lifetime(name))
}
+ ty::ReEarlyBound(ref data) => Some(Lifetime(data.name)),
ty::ReLateBound(..)
| ty::ReFree(..)
| ty::ReVar(..)
@@ -303,12 +295,16 @@ pub(crate) fn clean_predicate<'tcx>(
) -> Option<WherePredicate> {
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
- ty::PredicateKind::Trait(pred) => {
+ ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => {
clean_poly_trait_predicate(bound_predicate.rebind(pred), cx)
}
- ty::PredicateKind::RegionOutlives(pred) => clean_region_outlives_predicate(pred),
- ty::PredicateKind::TypeOutlives(pred) => clean_type_outlives_predicate(pred, cx),
- ty::PredicateKind::Projection(pred) => {
+ ty::PredicateKind::Clause(ty::Clause::RegionOutlives(pred)) => {
+ clean_region_outlives_predicate(pred)
+ }
+ ty::PredicateKind::Clause(ty::Clause::TypeOutlives(pred)) => {
+ clean_type_outlives_predicate(pred, cx)
+ }
+ ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => {
Some(clean_projection_predicate(bound_predicate.rebind(pred), cx))
}
ty::PredicateKind::ConstEvaluatable(..) => None,
@@ -319,6 +315,7 @@ pub(crate) fn clean_predicate<'tcx>(
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::ConstEquate(..)
+ | ty::PredicateKind::Ambiguous
| ty::PredicateKind::TypeWellFormedFromEnv(..) => panic!("not user writable"),
}
}
@@ -396,7 +393,7 @@ fn clean_projection_predicate<'tcx>(
.collect_referenced_late_bound_regions(&pred)
.into_iter()
.filter_map(|br| match br {
- ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => Some(Lifetime(name)),
+ ty::BrNamed(_, name) if br.is_named() => Some(Lifetime(name)),
_ => None,
})
.collect();
@@ -601,47 +598,105 @@ pub(crate) fn clean_generics<'tcx>(
})
.collect::<Vec<_>>();
- let mut params = Vec::with_capacity(gens.params.len());
- for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) {
- let p = clean_generic_param(cx, Some(gens), p);
- params.push(p);
+ let mut bound_predicates = FxIndexMap::default();
+ let mut region_predicates = FxIndexMap::default();
+ let mut eq_predicates = ThinVec::default();
+ for pred in gens.predicates.iter().filter_map(|x| clean_where_predicate(x, cx)) {
+ match pred {
+ WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
+ match bound_predicates.entry(ty) {
+ IndexEntry::Vacant(v) => {
+ v.insert((bounds, bound_params));
+ }
+ IndexEntry::Occupied(mut o) => {
+ // we merge both bounds.
+ for bound in bounds {
+ if !o.get().0.contains(&bound) {
+ o.get_mut().0.push(bound);
+ }
+ }
+ for bound_param in bound_params {
+ if !o.get().1.contains(&bound_param) {
+ o.get_mut().1.push(bound_param);
+ }
+ }
+ }
+ }
+ }
+ WherePredicate::RegionPredicate { lifetime, bounds } => {
+ match region_predicates.entry(lifetime) {
+ IndexEntry::Vacant(v) => {
+ v.insert(bounds);
+ }
+ IndexEntry::Occupied(mut o) => {
+ // we merge both bounds.
+ for bound in bounds {
+ if !o.get().contains(&bound) {
+ o.get_mut().push(bound);
+ }
+ }
+ }
+ }
+ }
+ WherePredicate::EqPredicate { lhs, rhs, bound_params } => {
+ eq_predicates.push(WherePredicate::EqPredicate { lhs, rhs, bound_params });
+ }
+ }
}
- params.extend(impl_trait_params);
- let mut generics = Generics {
- params,
- where_predicates: gens
- .predicates
- .iter()
- .filter_map(|x| clean_where_predicate(x, cx))
- .collect(),
- };
-
- // Some duplicates are generated for ?Sized bounds between type params and where
- // predicates. The point in here is to move the bounds definitions from type params
- // to where predicates when such cases occur.
- for where_pred in &mut generics.where_predicates {
- match *where_pred {
- WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds, .. } => {
- if bounds.is_empty() {
- for param in &mut generics.params {
- match param.kind {
- GenericParamDefKind::Lifetime { .. } => {}
- GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => {
- if &param.name == name {
- mem::swap(bounds, ty_bounds);
- break;
- }
- }
- GenericParamDefKind::Const { .. } => {}
+ let mut params = ThinVec::with_capacity(gens.params.len());
+ // In this loop, we gather the generic parameters (`<'a, B: 'a>`) and check if they have
+ // bounds in the where predicates. If so, we move their bounds into the where predicates
+ // while also preventing duplicates.
+ for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) {
+ let mut p = clean_generic_param(cx, Some(gens), p);
+ match &mut p.kind {
+ GenericParamDefKind::Lifetime { ref mut outlives } => {
+ if let Some(region_pred) = region_predicates.get_mut(&Lifetime(p.name)) {
+ // We merge bounds in the `where` clause.
+ for outlive in outlives.drain(..) {
+ let outlive = GenericBound::Outlives(outlive);
+ if !region_pred.contains(&outlive) {
+ region_pred.push(outlive);
+ }
+ }
+ }
+ }
+ GenericParamDefKind::Type { bounds, synthetic: false, .. } => {
+ if let Some(bound_pred) = bound_predicates.get_mut(&Type::Generic(p.name)) {
+ // We merge bounds in the `where` clause.
+ for bound in bounds.drain(..) {
+ if !bound_pred.0.contains(&bound) {
+ bound_pred.0.push(bound);
}
}
}
}
- _ => continue,
+ GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
+ // nothing to do here.
+ }
}
+ params.push(p);
+ }
+ params.extend(impl_trait_params);
+
+ Generics {
+ params,
+ where_predicates: bound_predicates
+ .into_iter()
+ .map(|(ty, (bounds, bound_params))| WherePredicate::BoundPredicate {
+ ty,
+ bounds,
+ bound_params,
+ })
+ .chain(
+ region_predicates
+ .into_iter()
+ .map(|(lifetime, bounds)| WherePredicate::RegionPredicate { lifetime, bounds }),
+ )
+ .chain(eq_predicates.into_iter())
+ .collect(),
}
- generics
}
fn clean_ty_generics<'tcx>(
@@ -660,7 +715,7 @@ fn clean_ty_generics<'tcx>(
.params
.iter()
.filter_map(|param| match param.kind {
- ty::GenericParamDefKind::Lifetime if param.name == kw::UnderscoreLifetime => None,
+ ty::GenericParamDefKind::Lifetime if param.is_anonymous_lifetime() => None,
ty::GenericParamDefKind::Lifetime => Some(clean_generic_param_def(param, cx)),
ty::GenericParamDefKind::Type { synthetic, .. } => {
if param.name == kw::SelfUpper {
@@ -675,7 +730,7 @@ fn clean_ty_generics<'tcx>(
}
ty::GenericParamDefKind::Const { .. } => Some(clean_generic_param_def(param, cx)),
})
- .collect::<Vec<GenericParamDef>>();
+ .collect::<ThinVec<GenericParamDef>>();
// param index -> [(trait DefId, associated type name & generics, type, higher-ranked params)]
let mut impl_trait_proj =
@@ -689,17 +744,20 @@ fn clean_ty_generics<'tcx>(
let param_idx = (|| {
let bound_p = p.kind();
match bound_p.skip_binder() {
- ty::PredicateKind::Trait(pred) => {
+ ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => {
if let ty::Param(param) = pred.self_ty().kind() {
return Some(param.index);
}
}
- ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
+ ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(
+ ty,
+ _reg,
+ ))) => {
if let ty::Param(param) = ty.kind() {
return Some(param.index);
}
}
- ty::PredicateKind::Projection(p) => {
+ ty::PredicateKind::Clause(ty::Clause::Projection(p)) => {
if let ty::Param(param) = p.projection_ty.self_ty().kind() {
projection = Some(bound_p.rebind(p));
return Some(param.index);
@@ -741,10 +799,7 @@ fn clean_ty_generics<'tcx>(
p.get_bound_params()
.into_iter()
.flatten()
- .map(|param| GenericParamDef {
- name: param.0,
- kind: GenericParamDefKind::Lifetime { outlives: Vec::new() },
- })
+ .map(|param| GenericParamDef::lifetime(param.0))
.collect(),
));
}
@@ -880,7 +935,7 @@ fn clean_fn_or_proc_macro<'tcx>(
ProcMacroItem(ProcMacro { kind, helpers })
}
None => {
- let mut func = clean_function(cx, sig, generics, body_id);
+ let mut func = clean_function(cx, sig, generics, FunctionArgs::Body(body_id));
clean_fn_decl_legacy_const_generics(&mut func, attrs);
FunctionItem(func)
}
@@ -896,7 +951,7 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib
.filter(|a| a.has_name(sym::rustc_legacy_const_generics))
.filter_map(|a| a.meta_item_list())
{
- for (pos, literal) in meta_item_list.iter().filter_map(|meta| meta.literal()).enumerate() {
+ for (pos, literal) in meta_item_list.iter().filter_map(|meta| meta.lit()).enumerate() {
match literal.kind {
ast::LitKind::Int(a, _) => {
let gen = func.generics.params.remove(0);
@@ -917,16 +972,28 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib
}
}
+enum FunctionArgs<'tcx> {
+ Body(hir::BodyId),
+ Names(&'tcx [Ident]),
+}
+
fn clean_function<'tcx>(
cx: &mut DocContext<'tcx>,
sig: &hir::FnSig<'tcx>,
generics: &hir::Generics<'tcx>,
- body_id: hir::BodyId,
+ args: FunctionArgs<'tcx>,
) -> Box<Function> {
let (generics, decl) = enter_impl_trait(cx, |cx| {
// NOTE: generics must be cleaned before args
let generics = clean_generics(generics, cx);
- let args = clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id);
+ let args = match args {
+ FunctionArgs::Body(body_id) => {
+ clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id)
+ }
+ FunctionArgs::Names(names) => {
+ clean_args_from_types_and_names(cx, sig.decl.inputs, names)
+ }
+ };
let mut decl = clean_fn_decl_with_args(cx, sig.decl, args);
if sig.header.is_async() {
decl.output = decl.sugared_async_return_type();
@@ -945,12 +1012,14 @@ fn clean_args_from_types_and_names<'tcx>(
values: types
.iter()
.enumerate()
- .map(|(i, ty)| {
- let mut name = names.get(i).map_or(kw::Empty, |ident| ident.name);
- if name.is_empty() {
- name = kw::Underscore;
- }
- Argument { name, type_: clean_ty(ty, cx), is_const: false }
+ .map(|(i, ty)| Argument {
+ type_: clean_ty(ty, cx),
+ name: names
+ .get(i)
+ .map(|ident| ident.name)
+ .filter(|ident| !ident.is_empty())
+ .unwrap_or(kw::Underscore),
+ is_const: false,
})
.collect(),
}
@@ -1012,7 +1081,11 @@ fn clean_fn_decl_from_did_and_sig<'tcx>(
.iter()
.map(|t| Argument {
type_: clean_middle_ty(*t, cx, None),
- name: names.next().map_or(kw::Empty, |i| i.name),
+ name: names
+ .next()
+ .map(|i| i.name)
+ .filter(|i| !i.is_empty())
+ .unwrap_or(kw::Underscore),
is_const: false,
})
.collect(),
@@ -1051,18 +1124,12 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
),
hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(clean_ty(ty, cx)),
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
- let m = clean_function(cx, sig, trait_item.generics, body);
+ let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body));
MethodItem(m, None)
}
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => {
- let (generics, decl) = enter_impl_trait(cx, |cx| {
- // NOTE: generics must be cleaned before args
- let generics = clean_generics(trait_item.generics, cx);
- let args = clean_args_from_types_and_names(cx, sig.decl.inputs, names);
- let decl = clean_fn_decl_with_args(cx, sig.decl, args);
- (generics, decl)
- });
- TyMethodItem(Box::new(Function { decl, generics }))
+ let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Names(names));
+ TyMethodItem(m)
}
hir::TraitItemKind::Type(bounds, Some(default)) => {
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
@@ -1080,13 +1147,10 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
hir::TraitItemKind::Type(bounds, None) => {
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect();
- TyAssocTypeItem(Box::new(generics), bounds)
+ TyAssocTypeItem(generics, bounds)
}
};
- let what_rustc_thinks =
- Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx);
- // Trait items always inherit the trait's visibility -- we don't want to show `pub`.
- Item { visibility: Inherited, ..what_rustc_thinks }
+ Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx)
})
}
@@ -1102,7 +1166,7 @@ pub(crate) fn clean_impl_item<'tcx>(
AssocConstItem(clean_ty(ty, cx), default)
}
hir::ImplItemKind::Fn(ref sig, body) => {
- let m = clean_function(cx, sig, impl_.generics, body);
+ let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body));
let defaultness = cx.tcx.impl_defaultness(impl_.owner_id);
MethodItem(m, Some(defaultness))
}
@@ -1117,18 +1181,7 @@ pub(crate) fn clean_impl_item<'tcx>(
}
};
- let mut what_rustc_thinks =
- Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx);
-
- let impl_ref = cx.tcx.impl_trait_ref(cx.tcx.local_parent(impl_.owner_id.def_id));
-
- // Trait impl items always inherit the impl's visibility --
- // we don't want to show `pub`.
- if impl_ref.is_some() {
- what_rustc_thinks.visibility = Inherited;
- }
-
- what_rustc_thinks
+ Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx)
})
}
@@ -1152,12 +1205,25 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
}
}
ty::AssocKind::Fn => {
- let generics = clean_ty_generics(
+ let sig = tcx.fn_sig(assoc_item.def_id);
+
+ let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var {
+ ty::BoundVariableKind::Region(ty::BrNamed(_, name))
+ if name != kw::UnderscoreLifetime =>
+ {
+ Some(GenericParamDef::lifetime(name))
+ }
+ _ => None,
+ });
+
+ let mut generics = clean_ty_generics(
cx,
tcx.generics_of(assoc_item.def_id),
tcx.explicit_predicates_of(assoc_item.def_id),
);
- let sig = tcx.fn_sig(assoc_item.def_id);
+ // FIXME: This does not place parameters in source order (late-bound ones come last)
+ generics.params.extend(late_bound_regions);
+
let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(assoc_item.def_id), sig);
if assoc_item.fn_has_self_parameter {
@@ -1208,7 +1274,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
true
}
(GenericParamDefKind::Const { .. }, GenericArg::Const(c)) => match &c.kind {
- ConstantKind::TyConst { expr } => expr == param.name.as_str(),
+ ConstantKind::TyConst { expr } => **expr == *param.name.as_str(),
_ => false,
},
_ => false,
@@ -1225,56 +1291,47 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
tcx.generics_of(assoc_item.def_id),
ty::GenericPredicates { parent: None, predicates },
);
- // Move bounds that are (likely) directly attached to the associated type
- // from the where clause to the associated type.
- // There is no guarantee that this is what the user actually wrote but we have
- // no way of knowing.
- let mut bounds = generics
- .where_predicates
- .drain_filter(|pred| match *pred {
- WherePredicate::BoundPredicate {
- ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }),
- ..
- } => {
- if assoc.name != my_name {
- return false;
- }
- if trait_.def_id() != assoc_item.container_id(tcx) {
- return false;
- }
- match *self_type {
- Generic(ref s) if *s == kw::SelfUpper => {}
- _ => return false,
- }
- match &assoc.args {
- GenericArgs::AngleBracketed { args, bindings } => {
- if !bindings.is_empty()
- || generics
- .params
- .iter()
- .zip(args.iter())
- .any(|(param, arg)| !param_eq_arg(param, arg))
- {
- return false;
- }
- }
- GenericArgs::Parenthesized { .. } => {
- // The only time this happens is if we're inside the rustdoc for Fn(),
- // which only has one associated type, which is not a GAT, so whatever.
+ // Filter out the bounds that are (likely?) directly attached to the associated type,
+ // as opposed to being located in the where clause.
+ let mut bounds: Vec<GenericBound> = Vec::new();
+ generics.where_predicates.retain_mut(|pred| match *pred {
+ WherePredicate::BoundPredicate {
+ ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }),
+ bounds: ref mut pred_bounds,
+ ..
+ } => {
+ if assoc.name != my_name {
+ return true;
+ }
+ if trait_.def_id() != assoc_item.container_id(tcx) {
+ return true;
+ }
+ match *self_type {
+ Generic(ref s) if *s == kw::SelfUpper => {}
+ _ => return true,
+ }
+ match &assoc.args {
+ GenericArgs::AngleBracketed { args, bindings } => {
+ if !bindings.is_empty()
+ || generics
+ .params
+ .iter()
+ .zip(args.iter())
+ .any(|(param, arg)| !param_eq_arg(param, arg))
+ {
+ return true;
}
}
- true
- }
- _ => false,
- })
- .flat_map(|pred| {
- if let WherePredicate::BoundPredicate { bounds, .. } = pred {
- bounds
- } else {
- unreachable!()
+ GenericArgs::Parenthesized { .. } => {
+ // The only time this happens is if we're inside the rustdoc for Fn(),
+ // which only has one associated type, which is not a GAT, so whatever.
+ }
}
- })
- .collect::<Vec<_>>();
+ bounds.extend(mem::replace(pred_bounds, Vec::new()));
+ false
+ }
+ _ => true,
+ });
// Our Sized/?Sized bound didn't get handled when creating the generics
// because we didn't actually get our whole set of bounds until just now
// (some of them may have come from the trait). If we do have a sized
@@ -1290,7 +1347,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
// (generic) associated type from the where clause to the respective parameter.
// There is no guarantee that this is what the user actually wrote but we have
// no way of knowing.
- let mut where_predicates = Vec::new();
+ let mut where_predicates = ThinVec::new();
for mut pred in generics.where_predicates {
if let WherePredicate::BoundPredicate { ty: Generic(arg), bounds, .. } = &mut pred
&& let Some(GenericParamDef {
@@ -1298,7 +1355,16 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
..
}) = generics.params.iter_mut().find(|param| &param.name == arg)
{
- param_bounds.extend(mem::take(bounds));
+ param_bounds.append(bounds);
+ } else if let WherePredicate::RegionPredicate { lifetime: Lifetime(arg), bounds } = &mut pred
+ && let Some(GenericParamDef {
+ kind: GenericParamDefKind::Lifetime { outlives: param_bounds },
+ ..
+ }) = generics.params.iter_mut().find(|param| &param.name == arg) {
+ param_bounds.extend(bounds.drain(..).map(|bound| match bound {
+ GenericBound::Outlives(lifetime) => lifetime,
+ _ => unreachable!(),
+ }));
} else {
where_predicates.push(pred);
}
@@ -1320,7 +1386,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
bounds,
)
} else {
- TyAssocTypeItem(Box::new(generics), bounds)
+ TyAssocTypeItem(generics, bounds)
}
} else {
// FIXME: when could this happen? Associated items in inherent impls?
@@ -1331,7 +1397,10 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
cx,
Some(assoc_item.def_id),
),
- generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
+ generics: Generics {
+ params: ThinVec::new(),
+ where_predicates: ThinVec::new(),
+ },
item_type: None,
}),
Vec::new(),
@@ -1340,18 +1409,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
}
};
- let mut what_rustc_thinks =
- Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx);
-
- let impl_ref = tcx.impl_trait_ref(tcx.parent(assoc_item.def_id));
-
- // Trait impl items always inherit the impl's visibility --
- // we don't want to show `pub`.
- if impl_ref.is_some() {
- what_rustc_thinks.visibility = Visibility::Inherited;
- }
-
- what_rustc_thinks
+ Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx)
}
fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type {
@@ -1406,7 +1464,8 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
ty::Projection(proj) => Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id),
// Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
ty::Error(_) => return Type::Infer,
- _ => bug!("clean: expected associated type, found `{:?}`", ty),
+ // Otherwise, this is an inherent associated type.
+ _ => return clean_middle_ty(ty, cx, None),
};
let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
register_res(cx, trait_.res);
@@ -1431,7 +1490,7 @@ fn maybe_expand_private_type_alias<'tcx>(
let Res::Def(DefKind::TyAlias, def_id) = path.res else { return None };
// Substitute private type aliases
let def_id = def_id.as_local()?;
- let alias = if !cx.cache.effective_visibilities.is_exported(def_id.to_def_id()) {
+ let alias = if !cx.cache.effective_visibilities.is_exported(cx.tcx, def_id.to_def_id()) {
&cx.tcx.hir().expect_item(def_id).kind
} else {
return None;
@@ -1459,8 +1518,11 @@ fn maybe_expand_private_type_alias<'tcx>(
});
if let Some(lt) = lifetime {
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
- let cleaned =
- if !lt.is_elided() { clean_lifetime(lt, cx) } else { Lifetime::elided() };
+ let cleaned = if !lt.is_anonymous() {
+ clean_lifetime(lt, cx)
+ } else {
+ Lifetime::elided()
+ };
substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
}
indices.lifetimes += 1;
@@ -1523,16 +1585,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
TyKind::Never => Primitive(PrimitiveType::Never),
TyKind::Ptr(ref m) => RawPointer(m.mutbl, Box::new(clean_ty(m.ty, cx))),
TyKind::Rptr(ref l, ref m) => {
- // There are two times a `Fresh` lifetime can be created:
- // 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`.
- // 2. For `&x` as a parameter to an `async fn`. This corresponds to `elided_ref_lifetime in `rustc_ast_lowering`.
- // See #59286 for more information.
- // Ideally we would only hide the `'_` for case 2., but I don't know a way to distinguish it.
- // Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though;
- // there's no case where it could cause the function to fail to compile.
- let elided =
- l.is_elided() || matches!(l.name, LifetimeName::Param(_, ParamName::Fresh));
- let lifetime = if elided { None } else { Some(clean_lifetime(*l, cx)) };
+ let lifetime = if l.is_anonymous() { None } else { Some(clean_lifetime(*l, cx)) };
BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(clean_ty(m.ty, cx)) }
}
TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))),
@@ -1554,7 +1607,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
}
};
- Array(Box::new(clean_ty(ty, cx)), length)
+ Array(Box::new(clean_ty(ty, cx)), length.into())
}
TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
TyKind::OpaqueDef(item_id, _, _) => {
@@ -1586,14 +1639,14 @@ fn normalize<'tcx>(cx: &mut DocContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>>
}
use crate::rustc_trait_selection::infer::TyCtxtInferExt;
- use crate::rustc_trait_selection::traits::query::normalize::AtExt;
+ use crate::rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
use rustc_middle::traits::ObligationCause;
// Try to normalize `<X as Y>::T` to a type
let infcx = cx.tcx.infer_ctxt().build();
let normalized = infcx
.at(&ObligationCause::dummy(), cx.param_env)
- .normalize(ty)
+ .query_normalize(ty)
.map(|resolved| infcx.resolve_vars_if_possible(resolved.value));
match normalized {
Ok(normalized_value) => {
@@ -1626,7 +1679,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
ty::Array(ty, mut n) => {
n = n.eval(cx.tcx, ty::ParamEnv::reveal_all());
let n = print_const(cx, n);
- Array(Box::new(clean_middle_ty(ty, cx, None)), n)
+ Array(Box::new(clean_middle_ty(ty, cx, None)), n.into())
}
ty::RawPtr(mt) => RawPointer(mt.mutbl, Box::new(clean_middle_ty(mt.ty, cx, None))),
ty::Ref(r, ty, mutbl) => BorrowedRef {
@@ -1677,6 +1730,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
inline::record_extern_fqn(cx, did, ItemType::Trait);
+ // FIXME(fmease): Hide the trait-object lifetime bound if it coincides with its default
+ // to partially address #44306. Follow the rules outlined at
+ // https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes
let lifetime = clean_middle_region(*reg);
let mut bounds = dids
.map(|did| {
@@ -1704,8 +1760,22 @@ pub(crate) fn clean_middle_ty<'tcx>(
})
.collect();
+ let late_bound_regions: FxIndexSet<_> = obj
+ .iter()
+ .flat_map(|pb| pb.bound_vars())
+ .filter_map(|br| match br {
+ ty::BoundVariableKind::Region(ty::BrNamed(_, name))
+ if name != kw::UnderscoreLifetime =>
+ {
+ Some(GenericParamDef::lifetime(name))
+ }
+ _ => None,
+ })
+ .collect();
+ let late_bound_regions = late_bound_regions.into_iter().collect();
+
let path = external_path(cx, did, false, bindings, substs);
- bounds.insert(0, PolyTrait { trait_: path, generic_params: Vec::new() });
+ bounds.insert(0, PolyTrait { trait_: path, generic_params: late_bound_regions });
DynTrait(bounds, lifetime)
}
@@ -1754,8 +1824,13 @@ fn clean_middle_opaque_bounds<'tcx>(
.filter_map(|bound| {
let bound_predicate = bound.kind();
let trait_ref = match bound_predicate.skip_binder() {
- ty::PredicateKind::Trait(tr) => bound_predicate.rebind(tr.trait_ref),
- ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => {
+ ty::PredicateKind::Clause(ty::Clause::Trait(tr)) => {
+ bound_predicate.rebind(tr.trait_ref)
+ }
+ ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(
+ _ty,
+ reg,
+ ))) => {
if let Some(r) = clean_middle_region(reg) {
regions.push(GenericBound::Outlives(r));
}
@@ -1774,7 +1849,9 @@ fn clean_middle_opaque_bounds<'tcx>(
let bindings: ThinVec<_> = bounds
.iter()
.filter_map(|bound| {
- if let ty::PredicateKind::Projection(proj) = bound.kind().skip_binder() {
+ if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) =
+ bound.kind().skip_binder()
+ {
if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() {
Some(TypeBinding {
assoc: projection_to_path_segment(proj.projection_ty, cx),
@@ -1821,50 +1898,24 @@ pub(crate) fn clean_field_with_def_id(
ty: Type,
cx: &mut DocContext<'_>,
) -> Item {
- let what_rustc_thinks =
- Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx);
- if is_field_vis_inherited(cx.tcx, def_id) {
- // Variant fields inherit their enum's visibility.
- Item { visibility: Visibility::Inherited, ..what_rustc_thinks }
- } else {
- what_rustc_thinks
- }
-}
-
-fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
- let parent = tcx.parent(def_id);
- match tcx.def_kind(parent) {
- DefKind::Struct | DefKind::Union => false,
- DefKind::Variant => true,
- parent_kind => panic!("unexpected parent kind: {:?}", parent_kind),
- }
-}
-
-pub(crate) fn clean_visibility(vis: ty::Visibility<DefId>) -> Visibility {
- match vis {
- ty::Visibility::Public => Visibility::Public,
- ty::Visibility::Restricted(module) => Visibility::Restricted(module),
- }
+ Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx)
}
pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item {
- let kind = match variant.ctor_kind {
- CtorKind::Const => Variant::CLike(match variant.discr {
+ let kind = match variant.ctor_kind() {
+ Some(CtorKind::Const) => Variant::CLike(match variant.discr {
ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }),
ty::VariantDiscr::Relative(_) => None,
}),
- CtorKind::Fn => Variant::Tuple(
+ Some(CtorKind::Fn) => Variant::Tuple(
variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
),
- CtorKind::Fictive => Variant::Struct(VariantStruct {
- struct_type: CtorKind::Fictive,
+ None => Variant::Struct(VariantStruct {
+ ctor_kind: None,
fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
}),
};
- let what_rustc_thinks =
- Item::from_def_id_and_parts(variant.def_id, Some(variant.name), VariantItem(kind), cx);
- // don't show `pub` for variants, which always inherit visibility
- Item { visibility: Inherited, ..what_rustc_thinks }
+ Item::from_def_id_and_parts(variant.def_id, Some(variant.name), VariantItem(kind), cx)
}
fn clean_variant_data<'tcx>(
@@ -1874,7 +1925,7 @@ fn clean_variant_data<'tcx>(
) -> Variant {
match variant {
hir::VariantData::Struct(..) => Variant::Struct(VariantStruct {
- struct_type: CtorKind::from_hir(variant),
+ ctor_kind: None,
fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(),
}),
hir::VariantData::Tuple(..) => {
@@ -1909,7 +1960,7 @@ fn clean_generic_args<'tcx>(
.args
.iter()
.map(|arg| match arg {
- hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
+ hir::GenericArg::Lifetime(lt) if !lt.is_anonymous() => {
GenericArg::Lifetime(clean_lifetime(*lt, cx))
}
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
@@ -1951,10 +2002,84 @@ fn clean_bare_fn_ty<'tcx>(
BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params }
}
+/// This visitor is used to go through only the "top level" of a item and not enter any sub
+/// item while looking for a given `Ident` which is stored into `item` if found.
+struct OneLevelVisitor<'hir> {
+ map: rustc_middle::hir::map::Map<'hir>,
+ item: Option<&'hir hir::Item<'hir>>,
+ looking_for: Ident,
+ target_hir_id: hir::HirId,
+}
+
+impl<'hir> OneLevelVisitor<'hir> {
+ fn new(map: rustc_middle::hir::map::Map<'hir>, target_hir_id: hir::HirId) -> Self {
+ Self { map, item: None, looking_for: Ident::empty(), target_hir_id }
+ }
+
+ fn reset(&mut self, looking_for: Ident) {
+ self.looking_for = looking_for;
+ self.item = None;
+ }
+}
+
+impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> {
+ type NestedFilter = rustc_middle::hir::nested_filter::All;
+
+ fn nested_visit_map(&mut self) -> Self::Map {
+ self.map
+ }
+
+ fn visit_item(&mut self, item: &'hir hir::Item<'hir>) {
+ if self.item.is_none()
+ && item.ident == self.looking_for
+ && matches!(item.kind, hir::ItemKind::Use(_, _))
+ || item.hir_id() == self.target_hir_id
+ {
+ self.item = Some(item);
+ }
+ }
+}
+
+/// Because a `Use` item directly links to the imported item, we need to manually go through each
+/// import one by one. To do so, we go to the parent item and look for the `Ident` into it. Then,
+/// if we found the "end item" (the imported one), we stop there because we don't need its
+/// documentation. Otherwise, we repeat the same operation until we find the "end item".
+fn get_all_import_attributes<'hir>(
+ mut item: &hir::Item<'hir>,
+ tcx: TyCtxt<'hir>,
+ target_hir_id: hir::HirId,
+ attributes: &mut Vec<ast::Attribute>,
+) {
+ let hir_map = tcx.hir();
+ let mut visitor = OneLevelVisitor::new(hir_map, target_hir_id);
+ // If the item is an import and has at least a path with two parts, we go into it.
+ while let hir::ItemKind::Use(path, _) = item.kind &&
+ path.segments.len() > 1 &&
+ let hir::def::Res::Def(_, def_id) = path.segments[path.segments.len() - 2].res
+ {
+ if let Some(hir::Node::Item(parent_item)) = hir_map.get_if_local(def_id) {
+ // We add the attributes from this import into the list.
+ attributes.extend_from_slice(hir_map.attrs(item.hir_id()));
+ // We get the `Ident` we will be looking for into `item`.
+ let looking_for = path.segments[path.segments.len() - 1].ident;
+ visitor.reset(looking_for);
+ hir::intravisit::walk_item(&mut visitor, parent_item);
+ if let Some(i) = visitor.item {
+ item = i;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+}
+
fn clean_maybe_renamed_item<'tcx>(
cx: &mut DocContext<'tcx>,
item: &hir::Item<'tcx>,
renamed: Option<Symbol>,
+ import_id: Option<hir::HirId>,
) -> Vec<Item> {
use hir::ItemKind;
@@ -1995,7 +2120,7 @@ fn clean_maybe_renamed_item<'tcx>(
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
}),
ItemKind::Struct(ref variant_data, generics) => StructItem(Struct {
- struct_type: CtorKind::from_hir(variant_data),
+ ctor_kind: variant_data.ctor_kind(),
generics: clean_generics(generics, cx),
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
}),
@@ -2005,7 +2130,7 @@ fn clean_maybe_renamed_item<'tcx>(
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
}
ItemKind::Macro(ref macro_def, _) => {
- let ty_vis = clean_visibility(cx.tcx.visibility(def_id));
+ let ty_vis = cx.tcx.visibility(def_id);
MacroItem(Macro {
source: display_macro_source(cx, name, macro_def, def_id, ty_vis),
})
@@ -2032,16 +2157,35 @@ fn clean_maybe_renamed_item<'tcx>(
_ => unreachable!("not yet converted"),
};
- vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)]
+ let mut extra_attrs = Vec::new();
+ if let Some(hir::Node::Item(use_node)) =
+ import_id.and_then(|hir_id| cx.tcx.hir().find(hir_id))
+ {
+ // We get all the various imports' attributes.
+ get_all_import_attributes(use_node, cx.tcx, item.hir_id(), &mut extra_attrs);
+ }
+
+ if !extra_attrs.is_empty() {
+ extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
+ let attrs = Attributes::from_ast(&extra_attrs);
+ let cfg = extra_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
+
+ vec![Item::from_def_id_and_attrs_and_parts(
+ def_id,
+ Some(name),
+ kind,
+ Box::new(attrs),
+ cfg,
+ )]
+ } else {
+ vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)]
+ }
})
}
fn clean_variant<'tcx>(variant: &hir::Variant<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
let kind = VariantItem(clean_variant_data(&variant.data, &variant.disr_expr, cx));
- let what_rustc_thinks =
- Item::from_hir_id_and_parts(variant.id, Some(variant.ident.name), kind, cx);
- // don't show `pub` for variants, which are always public
- Item { visibility: Inherited, ..what_rustc_thinks }
+ Item::from_hir_id_and_parts(variant.hir_id, Some(variant.ident.name), kind, cx)
}
fn clean_impl<'tcx>(
@@ -2114,6 +2258,7 @@ fn clean_extern_crate<'tcx>(
}
});
+ let krate_owner_def_id = krate.owner_id.to_def_id();
if please_inline {
let mut visited = FxHashSet::default();
@@ -2122,7 +2267,7 @@ fn clean_extern_crate<'tcx>(
if let Some(items) = inline::try_inline(
cx,
cx.tcx.parent_module(krate.hir_id()).to_def_id(),
- Some(krate.owner_id.to_def_id()),
+ Some(krate_owner_def_id),
res,
name,
Some(attrs),
@@ -2137,15 +2282,35 @@ fn clean_extern_crate<'tcx>(
name: Some(name),
attrs: Box::new(Attributes::from_ast(attrs)),
item_id: crate_def_id.into(),
- visibility: clean_visibility(ty_vis),
kind: Box::new(ExternCrateItem { src: orig_name }),
cfg: attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
+ inline_stmt_id: Some(krate_owner_def_id),
}]
}
fn clean_use_statement<'tcx>(
import: &hir::Item<'tcx>,
name: Symbol,
+ path: &hir::UsePath<'tcx>,
+ kind: hir::UseKind,
+ cx: &mut DocContext<'tcx>,
+ inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
+) -> Vec<Item> {
+ let mut items = Vec::new();
+ let hir::UsePath { segments, ref res, span } = *path;
+ for &res in res {
+ if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
+ continue;
+ }
+ let path = hir::Path { segments, res, span };
+ items.append(&mut clean_use_statement_inner(import, name, &path, kind, cx, inlined_names));
+ }
+ items
+}
+
+fn clean_use_statement_inner<'tcx>(
+ import: &hir::Item<'tcx>,
+ name: Symbol,
path: &hir::Path<'tcx>,
kind: hir::UseKind,
cx: &mut DocContext<'tcx>,
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 1bcb9fcd5..e96a9bab7 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -14,13 +14,14 @@
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::def_id::DefId;
use rustc_middle::ty;
+use thin_vec::ThinVec;
use crate::clean;
use crate::clean::GenericArgs as PP;
use crate::clean::WherePredicate as WP;
use crate::core::DocContext;
-pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
+pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> ThinVec<WP> {
// First, partition the where clause into its separate components.
//
// We use `FxIndexMap` so that the insertion order is preserved to prevent messing up to
@@ -50,16 +51,13 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
let Some((bounds, _)) = tybounds.get_mut(ty) else { return true };
let bound_params = bound_params
.into_iter()
- .map(|param| clean::GenericParamDef {
- name: param.0,
- kind: clean::GenericParamDefKind::Lifetime { outlives: Vec::new() },
- })
+ .map(|param| clean::GenericParamDef::lifetime(param.0))
.collect();
merge_bounds(cx, bounds, bound_params, trait_did, name, rhs)
});
// And finally, let's reassemble everything
- let mut clauses = Vec::new();
+ let mut clauses = ThinVec::with_capacity(lifetimes.len() + tybounds.len() + equalities.len());
clauses.extend(
lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }),
);
@@ -98,9 +96,8 @@ pub(crate) fn merge_bounds(
let last = trait_ref.trait_.segments.last_mut().expect("segments were empty");
trait_ref.generic_params.append(&mut bound_params);
- // Since the parameters (probably) originate from `tcx.collect_*_late_bound_regions` which
- // returns a hash set, sort them alphabetically to guarantee a stable and deterministic
- // output (and to fully deduplicate them).
+ // Sort parameters (likely) originating from a hashset alphabetically to
+ // produce predictable output (and to allow for full deduplication).
trait_ref.generic_params.sort_unstable_by(|p, q| p.name.as_str().cmp(q.name.as_str()));
trait_ref.generic_params.dedup_by_key(|p| p.name);
@@ -135,7 +132,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId)
.predicates
.iter()
.filter_map(|(pred, _)| {
- if let ty::PredicateKind::Trait(pred) = pred.kind().skip_binder() {
+ if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = pred.kind().skip_binder() {
if pred.trait_ref.self_ty() == self_ty { Some(pred.def_id()) } else { None }
} else {
None
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index cd1f972dc..2590bb0df 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -24,7 +24,7 @@ use rustc_hir::{BodyId, Mutability};
use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety;
use rustc_index::vec::IndexVec;
use rustc_middle::ty::fast_reject::SimplifiedType;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, DefIdTree, TyCtxt, Visibility};
use rustc_session::Session;
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::DUMMY_SP;
@@ -34,7 +34,6 @@ use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
use crate::clean::cfg::Cfg;
-use crate::clean::clean_visibility;
use crate::clean::external_path;
use crate::clean::inline::{self, print_inlined_const};
use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const};
@@ -51,7 +50,6 @@ pub(crate) use self::Type::{
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
RawPointer, Slice, Tuple,
};
-pub(crate) use self::Visibility::{Inherited, Public};
#[cfg(test)]
mod tests;
@@ -117,7 +115,6 @@ impl From<DefId> for ItemId {
#[derive(Clone, Debug)]
pub(crate) struct Crate {
pub(crate) module: Item,
- pub(crate) primitives: ThinVec<(DefId, PrimitiveType)>,
/// Only here so that they can be filtered through the rustdoc passes.
pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, Trait>>>,
}
@@ -245,7 +242,9 @@ impl ExternalCrate {
hir::ItemKind::Use(path, hir::UseKind::Single)
if tcx.visibility(id.owner_id).is_public() =>
{
- as_keyword(path.res.expect_non_local())
+ path.res
+ .iter()
+ .find_map(|res| as_keyword(res.expect_non_local()))
.map(|(_, prim)| (id.owner_id.to_def_id(), prim))
}
_ => None,
@@ -313,10 +312,11 @@ impl ExternalCrate {
hir::ItemKind::Use(path, hir::UseKind::Single)
if tcx.visibility(id.owner_id).is_public() =>
{
- as_primitive(path.res.expect_non_local()).map(|(_, prim)| {
+ path.res
+ .iter()
+ .find_map(|res| as_primitive(res.expect_non_local()))
// Pretend the primitive is local.
- (id.owner_id.to_def_id(), prim)
- })
+ .map(|(_, prim)| (id.owner_id.to_def_id(), prim))
}
_ => None,
}
@@ -348,12 +348,12 @@ pub(crate) struct Item {
/// Optional because not every item has a name, e.g. impls.
pub(crate) name: Option<Symbol>,
pub(crate) attrs: Box<Attributes>,
- pub(crate) visibility: Visibility,
/// Information about this item that is specific to what kind of item it is.
/// E.g., struct vs enum vs function.
pub(crate) kind: Box<ItemKind>,
pub(crate) item_id: ItemId,
-
+ /// This is the `DefId` of the `use` statement if the item was inlined.
+ pub(crate) inline_stmt_id: Option<DefId>,
pub(crate) cfg: Option<Arc<Cfg>>,
}
@@ -364,9 +364,7 @@ impl fmt::Debug for Item {
let alternate = f.alternate();
// hand-picked fields that don't bloat the logs too much
let mut fmt = f.debug_struct("Item");
- fmt.field("name", &self.name)
- .field("visibility", &self.visibility)
- .field("item_id", &self.item_id);
+ fmt.field("name", &self.name).field("item_id", &self.item_id);
// allow printing the full item if someone really wants to
if alternate {
fmt.field("attrs", &self.attrs).field("kind", &self.kind).field("cfg", &self.cfg);
@@ -388,6 +386,15 @@ pub(crate) fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span {
))
}
+fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+ let parent = tcx.parent(def_id);
+ match tcx.def_kind(parent) {
+ DefKind::Struct | DefKind::Union => false,
+ DefKind::Variant => true,
+ parent_kind => panic!("unexpected parent kind: {:?}", parent_kind),
+ }
+}
+
impl Item {
pub(crate) fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<Stability> {
self.item_id.as_def_id().and_then(|did| tcx.lookup_stability(did))
@@ -462,7 +469,6 @@ impl Item {
name,
kind,
Box::new(Attributes::from_ast(ast_attrs)),
- cx,
ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
)
}
@@ -472,21 +478,18 @@ impl Item {
name: Option<Symbol>,
kind: ItemKind,
attrs: Box<Attributes>,
- cx: &mut DocContext<'_>,
cfg: Option<Arc<Cfg>>,
) -> Item {
trace!("name={:?}, def_id={:?} cfg={:?}", name, def_id, cfg);
- // Primitives and Keywords are written in the source code as private modules.
- // The modules need to be private so that nobody actually uses them, but the
- // keywords and primitives that they are documenting are public.
- let visibility = if matches!(&kind, ItemKind::KeywordItem | ItemKind::PrimitiveItem(..)) {
- Visibility::Public
- } else {
- clean_visibility(cx.tcx.visibility(def_id))
- };
-
- Item { item_id: def_id.into(), kind: Box::new(kind), name, attrs, visibility, cfg }
+ Item {
+ item_id: def_id.into(),
+ kind: Box::new(kind),
+ name,
+ attrs,
+ cfg,
+ inline_stmt_id: None,
+ }
}
/// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
@@ -691,17 +694,61 @@ impl Item {
asyncness: hir::IsAsync::NotAsync,
}
}
- ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) => {
+ ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) | ItemKind::TyMethodItem(_) => {
let def_id = self.item_id.as_def_id().unwrap();
build_fn_header(def_id, tcx, tcx.asyncness(def_id))
}
- ItemKind::TyMethodItem(_) => {
- build_fn_header(self.item_id.as_def_id().unwrap(), tcx, hir::IsAsync::NotAsync)
- }
_ => return None,
};
Some(header)
}
+
+ /// Returns the visibility of the current item. If the visibility is "inherited", then `None`
+ /// is returned.
+ pub(crate) fn visibility(&self, tcx: TyCtxt<'_>) -> Option<Visibility<DefId>> {
+ let def_id = match self.item_id {
+ // Anything but DefId *shouldn't* matter, but return a reasonable value anyway.
+ ItemId::Auto { .. } | ItemId::Blanket { .. } => return None,
+ // Primitives and Keywords are written in the source code as private modules.
+ // The modules need to be private so that nobody actually uses them, but the
+ // keywords and primitives that they are documenting are public.
+ ItemId::Primitive(..) => return Some(Visibility::Public),
+ ItemId::DefId(def_id) => def_id,
+ };
+
+ match *self.kind {
+ // Explication on `ItemId::Primitive` just above.
+ ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Some(Visibility::Public),
+ // Variant fields inherit their enum's visibility.
+ StructFieldItem(..) if is_field_vis_inherited(tcx, def_id) => {
+ return None;
+ }
+ // Variants always inherit visibility
+ VariantItem(..) => return None,
+ // Trait items inherit the trait's visibility
+ AssocConstItem(..) | TyAssocConstItem(..) | AssocTypeItem(..) | TyAssocTypeItem(..)
+ | TyMethodItem(..) | MethodItem(..) => {
+ let assoc_item = tcx.associated_item(def_id);
+ let is_trait_item = match assoc_item.container {
+ ty::TraitContainer => true,
+ ty::ImplContainer => {
+ // Trait impl items always inherit the impl's visibility --
+ // we don't want to show `pub`.
+ tcx.impl_trait_ref(tcx.parent(assoc_item.def_id)).is_some()
+ }
+ };
+ if is_trait_item {
+ return None;
+ }
+ }
+ _ => {}
+ }
+ let def_id = match self.inline_stmt_id {
+ Some(inlined) => inlined,
+ None => def_id,
+ };
+ Some(tcx.visibility(def_id))
+ }
}
#[derive(Clone, Debug)]
@@ -747,7 +794,7 @@ pub(crate) enum ItemKind {
/// A required associated type in a trait declaration.
///
/// The bounds may be non-empty if there is a `where` clause.
- TyAssocTypeItem(Box<Generics>, Vec<GenericBound>),
+ TyAssocTypeItem(Generics, Vec<GenericBound>),
/// An associated type in a trait impl or a provided one in a trait declaration.
AssocTypeItem(Box<Typedef>, Vec<GenericBound>),
/// An item that has been stripped by a rustdoc pass
@@ -1261,7 +1308,7 @@ impl Attributes {
for attr in self.other_attrs.lists(sym::doc).filter(|a| a.has_name(sym::alias)) {
if let Some(values) = attr.meta_item_list() {
for l in values {
- match l.literal().unwrap().kind {
+ match l.lit().unwrap().kind {
ast::LitKind::Str(s, _) => {
aliases.insert(s);
}
@@ -1392,6 +1439,10 @@ pub(crate) struct GenericParamDef {
}
impl GenericParamDef {
+ pub(crate) fn lifetime(name: Symbol) -> Self {
+ Self { name, kind: GenericParamDefKind::Lifetime { outlives: Vec::new() } }
+ }
+
pub(crate) fn is_synthetic_type_param(&self) -> bool {
match self.kind {
GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false,
@@ -1414,8 +1465,8 @@ impl GenericParamDef {
// maybe use a Generic enum and use Vec<Generic>?
#[derive(Clone, Debug, Default)]
pub(crate) struct Generics {
- pub(crate) params: Vec<GenericParamDef>,
- pub(crate) where_predicates: Vec<WherePredicate>,
+ pub(crate) params: ThinVec<GenericParamDef>,
+ pub(crate) where_predicates: ThinVec<WherePredicate>,
}
impl Generics {
@@ -1576,7 +1627,7 @@ pub(crate) enum Type {
/// An array type.
///
/// The `String` field is a stringified version of the array's length parameter.
- Array(Box<Type>, String),
+ Array(Box<Type>, Box<str>),
/// A raw pointer type: `*const i32`, `*mut i32`
RawPointer(Mutability, Box<Type>),
/// A reference type: `&i32`, `&'a mut Foo`
@@ -2030,27 +2081,9 @@ impl From<hir::PrimTy> for PrimitiveType {
}
}
-#[derive(Copy, Clone, Debug)]
-pub(crate) enum Visibility {
- /// `pub`
- Public,
- /// Visibility inherited from parent.
- ///
- /// For example, this is the visibility of private items and of enum variants.
- Inherited,
- /// `pub(crate)`, `pub(super)`, or `pub(in path::to::somewhere)`
- Restricted(DefId),
-}
-
-impl Visibility {
- pub(crate) fn is_public(&self) -> bool {
- matches!(self, Visibility::Public)
- }
-}
-
#[derive(Clone, Debug)]
pub(crate) struct Struct {
- pub(crate) struct_type: CtorKind,
+ pub(crate) ctor_kind: Option<CtorKind>,
pub(crate) generics: Generics,
pub(crate) fields: Vec<Item>,
}
@@ -2078,7 +2111,7 @@ impl Union {
/// only as a variant in an enum.
#[derive(Clone, Debug)]
pub(crate) struct VariantStruct {
- pub(crate) struct_type: CtorKind,
+ pub(crate) ctor_kind: Option<CtorKind>,
pub(crate) fields: Vec<Item>,
}
@@ -2179,7 +2212,7 @@ impl Span {
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub(crate) struct Path {
pub(crate) res: Res,
- pub(crate) segments: Vec<PathSegment>,
+ pub(crate) segments: ThinVec<PathSegment>,
}
impl Path {
@@ -2329,7 +2362,7 @@ pub(crate) enum ConstantKind {
///
/// Note that `ty::Const` includes generic parameters, and may not always be uniquely identified
/// by a DefId. So this field must be different from `Extern`.
- TyConst { expr: String },
+ TyConst { expr: Box<str> },
/// A constant (expression) that's not an item or associated item. These are usually found
/// nested inside types (e.g., array lengths) or expressions (e.g., repeat counts), and also
/// used to define explicit discriminant values for enum variants.
@@ -2357,7 +2390,7 @@ impl Constant {
impl ConstantKind {
pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> String {
match *self {
- ConstantKind::TyConst { ref expr } => expr.clone(),
+ ConstantKind::TyConst { ref expr } => expr.to_string(),
ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id),
ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => {
print_const_expr(tcx, body)
@@ -2541,14 +2574,15 @@ mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// tidy-alphabetical-start
- static_assert_size!(Crate, 72); // frequently moved by-value
+ static_assert_size!(Crate, 64); // frequently moved by-value
static_assert_size!(DocFragment, 32);
- static_assert_size!(GenericArg, 48);
+ static_assert_size!(GenericArg, 32);
static_assert_size!(GenericArgs, 32);
static_assert_size!(GenericParamDef, 56);
+ static_assert_size!(Generics, 16);
static_assert_size!(Item, 56);
- static_assert_size!(ItemKind, 88);
+ static_assert_size!(ItemKind, 64);
static_assert_size!(PathSegment, 40);
- static_assert_size!(Type, 48);
+ static_assert_size!(Type, 32);
// tidy-alphabetical-end
}
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 58767d3a4..246560bad 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -4,10 +4,10 @@ use crate::clean::render_macro_matchers::render_macro_matcher;
use crate::clean::{
clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, Crate,
ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path,
- PathSegment, Primitive, PrimitiveType, Type, TypeBinding, Visibility,
+ PathSegment, Primitive, PrimitiveType, Term, Type, TypeBinding, TypeBindingKind,
};
use crate::core::DocContext;
-use crate::visit_lib::LibEmbargoVisitor;
+use crate::html::format::visibility_to_src_with_space;
use rustc_ast as ast;
use rustc_ast::tokenstream::TokenTree;
@@ -21,7 +21,7 @@ use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_span::symbol::{kw, sym, Symbol};
use std::fmt::Write as _;
use std::mem;
-use thin_vec::ThinVec;
+use thin_vec::{thin_vec, ThinVec};
#[cfg(test)]
mod tests;
@@ -31,7 +31,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
for &cnum in cx.tcx.crates(()) {
// Analyze doc-reachability for extern items
- LibEmbargoVisitor::new(cx).visit_lib(cnum);
+ crate::visit_lib::lib_embargo_visit_item(cx, cnum.as_def_id());
}
// Clean the crate, translating the entire librustc_ast AST to one that is
@@ -73,7 +73,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
}));
}
- Crate { module, primitives, external_traits: cx.external_traits.clone() }
+ Crate { module, external_traits: cx.external_traits.clone() }
}
pub(crate) fn substs_to_args<'tcx>(
@@ -106,19 +106,19 @@ fn external_generic_args<'tcx>(
) -> GenericArgs {
let args = substs_to_args(cx, substs, has_self);
- if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() {
+ if cx.tcx.fn_trait_kind_from_def_id(did).is_some() {
let inputs =
// The trait's first substitution is the one after self, if there is one.
match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(t, cx, None)).collect::<Vec<_>>().into(),
_ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
};
- let output = None;
- // FIXME(#20299) return type comes from a projection now
- // match types[1].kind {
- // ty::Tuple(ref v) if v.is_empty() => None, // -> ()
- // _ => Some(types[1].clean(cx))
- // };
+ let output = bindings.into_iter().next().and_then(|binding| match binding.kind {
+ TypeBindingKind::Equality { term: Term::Type(ty) } if ty != Type::Tuple(Vec::new()) => {
+ Some(Box::new(ty))
+ }
+ _ => None,
+ });
GenericArgs::Parenthesized { inputs, output }
} else {
GenericArgs::AngleBracketed { args: args.into(), bindings: bindings.into() }
@@ -136,7 +136,7 @@ pub(super) fn external_path<'tcx>(
let name = cx.tcx.item_name(did);
Path {
res: Res::Def(def_kind, did),
- segments: vec![PathSegment {
+ segments: thin_vec![PathSegment {
name,
args: external_generic_args(cx, did, has_self, bindings, substs),
}],
@@ -242,19 +242,13 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
s
}
- _ => {
- let mut s = n.to_string();
- // array lengths are obviously usize
- if s.ends_with("_usize") {
- let n = s.len() - "_usize".len();
- s.truncate(n);
- if s.ends_with(": ") {
- let n = s.len() - ": ".len();
- s.truncate(n);
- }
- }
- s
+ // array lengths are obviously usize
+ ty::ConstKind::Value(ty::ValTree::Leaf(scalar))
+ if *n.ty().kind() == ty::Uint(ty::UintTy::Usize) =>
+ {
+ scalar.to_string()
}
+ _ => n.to_string(),
}
}
@@ -584,9 +578,9 @@ pub(super) fn display_macro_source(
name: Symbol,
def: &ast::MacroDef,
def_id: DefId,
- vis: Visibility,
+ vis: ty::Visibility<DefId>,
) -> String {
- let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
+ let tts: Vec<_> = def.body.tokens.clone().into_trees().collect();
// Extract the spans of all matchers. They represent the "interface" of the macro.
let matchers = tts.chunks(4).map(|arm| &arm[0]);
@@ -596,14 +590,14 @@ pub(super) fn display_macro_source(
if matchers.len() <= 1 {
format!(
"{}macro {}{} {{\n ...\n}}",
- vis.to_src_with_space(cx.tcx, def_id),
+ visibility_to_src_with_space(Some(vis), cx.tcx, def_id),
name,
matchers.map(|matcher| render_macro_matcher(cx.tcx, matcher)).collect::<String>(),
)
} else {
format!(
"{}macro {} {{\n{}}}",
- vis.to_src_with_space(cx.tcx, def_id),
+ visibility_to_src_with_space(Some(vis), cx.tcx, def_id),
name,
render_macro_arms(cx.tcx, matchers, ","),
)
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 67ea39fb9..56b40d8c6 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -69,6 +69,8 @@ pub(crate) struct Options {
pub(crate) input: PathBuf,
/// The name of the crate being documented.
pub(crate) crate_name: Option<String>,
+ /// Whether or not this is a bin crate
+ pub(crate) bin_crate: bool,
/// Whether or not this is a proc-macro crate
pub(crate) proc_macro_crate: bool,
/// How to format errors and warnings.
@@ -176,6 +178,7 @@ impl fmt::Debug for Options {
f.debug_struct("Options")
.field("input", &self.input)
.field("crate_name", &self.crate_name)
+ .field("bin_crate", &self.bin_crate)
.field("proc_macro_crate", &self.proc_macro_crate)
.field("error_format", &self.error_format)
.field("libs", &self.libs)
@@ -239,9 +242,6 @@ pub(crate) struct RenderOptions {
pub(crate) default_settings: FxHashMap<String, String>,
/// If present, suffix added to CSS/JavaScript files when referencing them in generated pages.
pub(crate) resource_suffix: String,
- /// Whether to run the static CSS/JavaScript through a minifier when outputting them. `true` by
- /// default.
- pub(crate) enable_minification: bool,
/// Whether to create an index page in the root of the output directory. If this is true but
/// `enable_index_page` is None, generate a static listing of crates instead.
pub(crate) enable_index_page: bool,
@@ -329,7 +329,7 @@ impl Options {
crate::usage("rustdoc");
return Err(0);
} else if matches.opt_present("version") {
- rustc_driver::version("rustdoc", matches);
+ rustc_driver::version!("rustdoc", matches);
return Err(0);
}
@@ -416,10 +416,12 @@ impl Options {
let to_check = matches.opt_strs("check-theme");
if !to_check.is_empty() {
- let paths = match theme::load_css_paths(static_files::themes::LIGHT) {
+ let paths = match theme::load_css_paths(
+ std::str::from_utf8(static_files::STATIC_FILES.theme_light_css.bytes).unwrap(),
+ ) {
Ok(p) => p,
Err(e) => {
- diag.struct_err(&e.to_string()).emit();
+ diag.struct_err(e).emit();
return Err(1);
}
};
@@ -557,10 +559,12 @@ impl Options {
let mut themes = Vec::new();
if matches.opt_present("theme") {
- let paths = match theme::load_css_paths(static_files::themes::LIGHT) {
+ let paths = match theme::load_css_paths(
+ std::str::from_utf8(static_files::STATIC_FILES.theme_light_css.bytes).unwrap(),
+ ) {
Ok(p) => p,
Err(e) => {
- diag.struct_err(&e.to_string()).emit();
+ diag.struct_err(e).emit();
return Err(1);
}
};
@@ -666,6 +670,7 @@ impl Options {
None => OutputFormat::default(),
};
let crate_name = matches.opt_str("crate-name");
+ let bin_crate = crate_types.contains(&CrateType::Executable);
let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
let playground_url = matches.opt_str("playground-url");
let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
@@ -675,7 +680,6 @@ impl Options {
ModuleSorting::Alphabetical
};
let resource_suffix = matches.opt_str("resource-suffix").unwrap_or_default();
- let enable_minification = !matches.opt_present("disable-minification");
let markdown_no_toc = matches.opt_present("markdown-no-toc");
let markdown_css = matches.opt_strs("markdown-css");
let markdown_playground_url = matches.opt_str("markdown-playground-url");
@@ -718,6 +722,7 @@ impl Options {
rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
let options = Options {
input,
+ bin_crate,
proc_macro_crate,
error_format,
diagnostic_width,
@@ -768,7 +773,6 @@ impl Options {
extern_html_root_takes_precedence,
default_settings,
resource_suffix,
- enable_minification,
enable_index_page,
index_page,
static_root_path,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 3e5f42b7a..da0df596c 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -166,6 +166,7 @@ pub(crate) fn new_handler(
unstable_opts.teach,
diagnostic_width,
false,
+ unstable_opts.track_diagnostics,
)
.ui_testing(unstable_opts.ui_testing),
)
@@ -184,6 +185,7 @@ pub(crate) fn new_handler(
json_rendered,
diagnostic_width,
false,
+ unstable_opts.track_diagnostics,
)
.ui_testing(unstable_opts.ui_testing),
)
@@ -348,7 +350,6 @@ pub(crate) fn run_global_ctxt(
let auto_traits =
tcx.all_traits().filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)).collect();
- let effective_visibilities = tcx.effective_visibilities(()).map_id(Into::into);
let mut ctxt = DocContext {
tcx,
@@ -361,7 +362,7 @@ pub(crate) fn run_global_ctxt(
impl_trait_bounds: Default::default(),
generated_synthetics: Default::default(),
auto_traits,
- cache: Cache::new(effective_visibilities, render_options.document_private),
+ cache: Cache::new(render_options.document_private),
inlined: FxHashSet::default(),
output_format,
render_options,
@@ -488,7 +489,7 @@ impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> {
self.tcx.hir()
}
- fn visit_path(&mut self, path: &'tcx Path<'_>, _id: HirId) {
+ fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
debug!("visiting path {:?}", path);
if path.res == Res::Err {
// We have less context here than in rustc_resolve,
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index db70029f6..81d9c4644 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -19,7 +19,7 @@ use rustc_span::edition::Edition;
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::sym;
use rustc_span::{BytePos, FileName, Pos, Span, DUMMY_SP};
-use rustc_target::spec::TargetTriple;
+use rustc_target::spec::{Target, TargetTriple};
use tempfile::Builder as TempFileBuilder;
use std::env;
@@ -293,6 +293,16 @@ struct UnusedExterns {
unused_extern_names: Vec<String>,
}
+fn add_exe_suffix(input: String, target: &TargetTriple) -> String {
+ let exe_suffix = match target {
+ TargetTriple::TargetTriple(_) => Target::expect_builtin(target).options.exe_suffix,
+ TargetTriple::TargetJson { contents, .. } => {
+ Target::from_json(contents.parse().unwrap()).unwrap().0.options.exe_suffix
+ }
+ };
+ input + &exe_suffix
+}
+
fn run_test(
test: &str,
crate_name: &str,
@@ -313,7 +323,9 @@ fn run_test(
let (test, line_offset, supports_color) =
make_test(test, Some(crate_name), lang_string.test_harness, opts, edition, Some(test_id));
- let output_file = outdir.path().join("rust_out");
+ // Make sure we emit well-formed executable names for our target.
+ let rust_out = add_exe_suffix("rust_out".to_owned(), &target);
+ let output_file = outdir.path().join(rust_out);
let rustc_binary = rustdoc_options
.test_builder
@@ -551,6 +563,7 @@ pub(crate) fn make_test(
false,
Some(80),
false,
+ false,
)
.supports_color();
@@ -564,6 +577,7 @@ pub(crate) fn make_test(
false,
None,
false,
+ false,
);
// FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
@@ -748,6 +762,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
false,
None,
false,
+ false,
);
let handler = Handler::with_emitter(false, None, Box::new(emitter));
@@ -1290,7 +1305,7 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
}
fn visit_variant(&mut self, v: &'hir hir::Variant<'_>) {
- self.visit_testable(v.ident.to_string(), v.id, v.span, |this| {
+ self.visit_testable(v.ident.to_string(), v.hir_id, v.span, |this| {
intravisit::walk_variant(this, v);
});
}
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index afe2264e8..d027fb6e8 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -2,7 +2,6 @@ use std::mem;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::{CrateNum, DefId};
-use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::Symbol;
@@ -15,6 +14,7 @@ use crate::html::format::join_with_double_colon;
use crate::html::markdown::short_markdown_summary;
use crate::html::render::search_index::get_function_type_for_search;
use crate::html::render::IndexItem;
+use crate::visit_lib::RustdocEffectiveVisibilities;
/// This cache is used to store information about the [`clean::Crate`] being
/// rendered in order to provide more useful documentation. This contains
@@ -78,7 +78,7 @@ pub(crate) struct Cache {
// Note that external items for which `doc(hidden)` applies to are shown as
// non-reachable while local items aren't. This is because we're reusing
// the effective visibilities from the privacy check pass.
- pub(crate) effective_visibilities: EffectiveVisibilities<DefId>,
+ pub(crate) effective_visibilities: RustdocEffectiveVisibilities,
/// The version of the crate being documented, if given from the `--crate-version` flag.
pub(crate) crate_version: Option<String>,
@@ -132,11 +132,8 @@ struct CacheBuilder<'a, 'tcx> {
}
impl Cache {
- pub(crate) fn new(
- effective_visibilities: EffectiveVisibilities<DefId>,
- document_private: bool,
- ) -> Self {
- Cache { effective_visibilities, document_private, ..Cache::default() }
+ pub(crate) fn new(document_private: bool) -> Self {
+ Cache { document_private, ..Cache::default() }
}
/// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was
@@ -319,21 +316,28 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
let desc = item.doc_value().map_or_else(String::new, |x| {
short_markdown_summary(x.as_str(), &item.link_names(self.cache))
});
- self.cache.search_index.push(IndexItem {
- ty: item.type_(),
- name: s.to_string(),
- path: join_with_double_colon(path),
- desc,
- parent,
- parent_idx: None,
- search_type: get_function_type_for_search(
- &item,
- self.tcx,
- clean_impl_generics(self.cache.parent_stack.last()).as_ref(),
- self.cache,
- ),
- aliases: item.attrs.get_doc_aliases(),
- });
+ let ty = item.type_();
+ let name = s.to_string();
+ if ty != ItemType::StructField || u16::from_str_radix(&name, 10).is_err() {
+ // In case this is a field from a tuple struct, we don't add it into
+ // the search index because its name is something like "0", which is
+ // not useful for rustdoc search.
+ self.cache.search_index.push(IndexItem {
+ ty,
+ name,
+ path: join_with_double_colon(path),
+ desc,
+ parent,
+ parent_idx: None,
+ search_type: get_function_type_for_search(
+ &item,
+ self.tcx,
+ clean_impl_generics(self.cache.parent_stack.last()).as_ref(),
+ self.cache,
+ ),
+ aliases: item.attrs.get_doc_aliases(),
+ });
+ }
}
}
(Some(parent), None) if is_inherent_impl_item => {
@@ -387,7 +391,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|| self
.cache
.effective_visibilities
- .is_directly_public(item.item_id.expect_def_id())
+ .is_directly_public(self.tcx, item.item_id.expect_def_id())
{
self.cache.paths.insert(
item.item_id.expect_def_id(),
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 92e7f2739..39e2a9022 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -107,10 +107,6 @@ impl Buffer {
self.buffer
}
- pub(crate) fn insert_str(&mut self, idx: usize, s: &str) {
- self.buffer.insert_str(idx, s);
- }
-
pub(crate) fn push_str(&mut self, s: &str) {
self.buffer.push_str(s);
}
@@ -659,7 +655,7 @@ pub(crate) fn href_with_root_path(
}
if !did.is_local()
- && !cache.effective_visibilities.is_directly_public(did)
+ && !cache.effective_visibilities.is_directly_public(tcx, did)
&& !cache.document_private
&& !cache.primitive_locations.values().any(|&id| id == did)
{
@@ -1232,9 +1228,8 @@ impl clean::Arguments {
) -> impl fmt::Display + 'a + Captures<'tcx> {
display_fn(move |f| {
for (i, input) in self.values.iter().enumerate() {
- if !input.name.is_empty() {
- write!(f, "{}: ", input.name)?;
- }
+ write!(f, "{}: ", input.name)?;
+
if f.alternate() {
write!(f, "{:#}", input.type_.print(cx))?;
} else {
@@ -1367,10 +1362,8 @@ impl clean::FnDecl {
args.push_str("const ");
args_plain.push_str("const ");
}
- if !input.name.is_empty() {
- write!(args, "{}: ", input.name);
- write!(args_plain, "{}: ", input.name);
- }
+ write!(args, "{}: ", input.name);
+ write!(args_plain, "{}: ", input.name);
if f.alternate() {
write!(args, "{:#}", input.type_.print(cx));
@@ -1420,87 +1413,84 @@ impl clean::FnDecl {
}
}
-impl clean::Visibility {
- pub(crate) fn print_with_space<'a, 'tcx: 'a>(
- self,
- item_did: ItemId,
- cx: &'a Context<'tcx>,
- ) -> impl fmt::Display + 'a + Captures<'tcx> {
- use std::fmt::Write as _;
-
- let to_print: Cow<'static, str> = match self {
- clean::Public => "pub ".into(),
- clean::Inherited => "".into(),
- clean::Visibility::Restricted(vis_did) => {
- // FIXME(camelid): This may not work correctly if `item_did` is a module.
- // However, rustdoc currently never displays a module's
- // visibility, so it shouldn't matter.
- let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id());
-
- if vis_did.is_crate_root() {
- "pub(crate) ".into()
- } else if parent_module == Some(vis_did) {
- // `pub(in foo)` where `foo` is the parent module
- // is the same as no visibility modifier
- "".into()
- } else if parent_module
- .and_then(|parent| find_nearest_parent_module(cx.tcx(), parent))
- == Some(vis_did)
- {
- "pub(super) ".into()
- } else {
- let path = cx.tcx().def_path(vis_did);
- debug!("path={:?}", path);
- // modified from `resolved_path()` to work with `DefPathData`
- let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
- let anchor = anchor(vis_did, last_name, cx).to_string();
-
- let mut s = "pub(in ".to_owned();
- for seg in &path.data[..path.data.len() - 1] {
- let _ = write!(s, "{}::", seg.data.get_opt_name().unwrap());
- }
- let _ = write!(s, "{}) ", anchor);
- s.into()
+pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>(
+ visibility: Option<ty::Visibility<DefId>>,
+ item_did: ItemId,
+ cx: &'a Context<'tcx>,
+) -> impl fmt::Display + 'a + Captures<'tcx> {
+ use std::fmt::Write as _;
+
+ let to_print: Cow<'static, str> = match visibility {
+ None => "".into(),
+ Some(ty::Visibility::Public) => "pub ".into(),
+ Some(ty::Visibility::Restricted(vis_did)) => {
+ // FIXME(camelid): This may not work correctly if `item_did` is a module.
+ // However, rustdoc currently never displays a module's
+ // visibility, so it shouldn't matter.
+ let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id());
+
+ if vis_did.is_crate_root() {
+ "pub(crate) ".into()
+ } else if parent_module == Some(vis_did) {
+ // `pub(in foo)` where `foo` is the parent module
+ // is the same as no visibility modifier
+ "".into()
+ } else if parent_module.and_then(|parent| find_nearest_parent_module(cx.tcx(), parent))
+ == Some(vis_did)
+ {
+ "pub(super) ".into()
+ } else {
+ let path = cx.tcx().def_path(vis_did);
+ debug!("path={:?}", path);
+ // modified from `resolved_path()` to work with `DefPathData`
+ let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
+ let anchor = anchor(vis_did, last_name, cx).to_string();
+
+ let mut s = "pub(in ".to_owned();
+ for seg in &path.data[..path.data.len() - 1] {
+ let _ = write!(s, "{}::", seg.data.get_opt_name().unwrap());
}
+ let _ = write!(s, "{}) ", anchor);
+ s.into()
}
- };
- display_fn(move |f| write!(f, "{}", to_print))
- }
+ }
+ };
+ display_fn(move |f| write!(f, "{}", to_print))
+}
- /// This function is the same as print_with_space, except that it renders no links.
- /// It's used for macros' rendered source view, which is syntax highlighted and cannot have
- /// any HTML in it.
- pub(crate) fn to_src_with_space<'a, 'tcx: 'a>(
- self,
- tcx: TyCtxt<'tcx>,
- item_did: DefId,
- ) -> impl fmt::Display + 'a + Captures<'tcx> {
- let to_print = match self {
- clean::Public => "pub ".to_owned(),
- clean::Inherited => String::new(),
- clean::Visibility::Restricted(vis_did) => {
- // FIXME(camelid): This may not work correctly if `item_did` is a module.
- // However, rustdoc currently never displays a module's
- // visibility, so it shouldn't matter.
- let parent_module = find_nearest_parent_module(tcx, item_did);
-
- if vis_did.is_crate_root() {
- "pub(crate) ".to_owned()
- } else if parent_module == Some(vis_did) {
- // `pub(in foo)` where `foo` is the parent module
- // is the same as no visibility modifier
- String::new()
- } else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent))
- == Some(vis_did)
- {
- "pub(super) ".to_owned()
- } else {
- format!("pub(in {}) ", tcx.def_path_str(vis_did))
- }
+/// This function is the same as print_with_space, except that it renders no links.
+/// It's used for macros' rendered source view, which is syntax highlighted and cannot have
+/// any HTML in it.
+pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>(
+ visibility: Option<ty::Visibility<DefId>>,
+ tcx: TyCtxt<'tcx>,
+ item_did: DefId,
+) -> impl fmt::Display + 'a + Captures<'tcx> {
+ let to_print = match visibility {
+ None => String::new(),
+ Some(ty::Visibility::Public) => "pub ".to_owned(),
+ Some(ty::Visibility::Restricted(vis_did)) => {
+ // FIXME(camelid): This may not work correctly if `item_did` is a module.
+ // However, rustdoc currently never displays a module's
+ // visibility, so it shouldn't matter.
+ let parent_module = find_nearest_parent_module(tcx, item_did);
+
+ if vis_did.is_crate_root() {
+ "pub(crate) ".to_owned()
+ } else if parent_module == Some(vis_did) {
+ // `pub(in foo)` where `foo` is the parent module
+ // is the same as no visibility modifier
+ String::new()
+ } else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent))
+ == Some(vis_did)
+ {
+ "pub(super) ".to_owned()
+ } else {
+ format!("pub(in {}) ", tcx.def_path_str(vis_did))
}
- };
- display_fn(move |f| f.write_str(&to_print))
- }
+ }
+ };
+ display_fn(move |f| f.write_str(&to_print))
}
pub(crate) trait PrintWithSpace {
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 5e28204b2..cd8c8c463 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -72,8 +72,12 @@ pub(crate) fn render_source_with_highlighting(
line_numbers: Buffer,
href_context: HrefContext<'_, '_, '_>,
decoration_info: DecorationInfo,
+ extra: Option<&str>,
) {
write_header(out, "", Some(line_numbers), Tooltip::None);
+ if let Some(extra) = extra {
+ out.push_str(extra);
+ }
write_code(out, src, Some(href_context), Some(decoration_info));
write_footer(out, None);
}
@@ -358,7 +362,7 @@ impl Class {
match self {
Class::Comment => "comment",
Class::DocComment => "doccomment",
- Class::Attribute => "attribute",
+ Class::Attribute => "attr",
Class::KeyWord => "kw",
Class::RefKeyWord => "kw-2",
Class::Self_(_) => "self",
diff --git a/src/librustdoc/html/highlight/fixtures/sample.html b/src/librustdoc/html/highlight/fixtures/sample.html
index 4a5a3cf60..fced2eacd 100644
--- a/src/librustdoc/html/highlight/fixtures/sample.html
+++ b/src/librustdoc/html/highlight/fixtures/sample.html
@@ -3,16 +3,16 @@
.kw { color: #8959A8; }
.kw-2, .prelude-ty { color: #4271AE; }
.number, .string { color: #718C00; }
-.self, .bool-val, .prelude-val, .attribute, .attribute .ident { color: #C82829; }
+.self, .bool-val, .prelude-val, .attr, .attr .ident { color: #C82829; }
.macro, .macro-nonterminal { color: #3E999F; }
.lifetime { color: #B76514; }
.question-mark { color: #ff9011; }
</style>
-<pre><code><span class="attribute">#![crate_type = <span class="string">&quot;lib&quot;</span>]
+<pre><code><span class="attr">#![crate_type = <span class="string">&quot;lib&quot;</span>]
</span><span class="kw">use </span>std::path::{Path, PathBuf};
-<span class="attribute">#[cfg(target_os = <span class="string">&quot;linux&quot;</span>)]
+<span class="attr">#[cfg(target_os = <span class="string">&quot;linux&quot;</span>)]
#[cfg(target_os = <span class="string">&quot;windows&quot;</span>)]
</span><span class="kw">fn </span>main() -&gt; () {
<span class="kw">let </span>foo = <span class="bool-val">true </span>&amp;&amp; <span class="bool-val">false </span>|| <span class="bool-val">true</span>;
@@ -23,7 +23,7 @@
<span class="macro">mac!</span>(foo, <span class="kw-2">&amp;mut </span>bar);
<span class="macro">assert!</span>(<span class="self">self</span>.length &lt; N &amp;&amp; index &lt;= <span class="self">self</span>.length);
::std::env::var(<span class="string">&quot;gateau&quot;</span>).is_ok();
- <span class="attribute">#[rustfmt::skip]
+ <span class="attr">#[rustfmt::skip]
</span><span class="kw">let </span>s:std::path::PathBuf = std::path::PathBuf::new();
<span class="kw">let </span><span class="kw-2">mut </span>s = String::new();
diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs
index a5e633df4..2c93b9a09 100644
--- a/src/librustdoc/html/highlight/tests.rs
+++ b/src/librustdoc/html/highlight/tests.rs
@@ -9,7 +9,7 @@ const STYLE: &str = r#"
.kw { color: #8959A8; }
.kw-2, .prelude-ty { color: #4271AE; }
.number, .string { color: #718C00; }
-.self, .bool-val, .prelude-val, .attribute, .attribute .ident { color: #C82829; }
+.self, .bool-val, .prelude-val, .attr, .attr .ident { color: #C82829; }
.macro, .macro-nonterminal { color: #3E999F; }
.lifetime { color: #B76514; }
.question-mark { color: #ff9011; }
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 7d6d4b71e..a60e7cb10 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -2,13 +2,14 @@ use std::path::PathBuf;
use rustc_data_structures::fx::FxHashMap;
-use crate::error::Error;
use crate::externalfiles::ExternalHtml;
use crate::html::format::{Buffer, Print};
use crate::html::render::{ensure_trailing_slash, StylePath};
use askama::Template;
+use super::static_files::{StaticFiles, STATIC_FILES};
+
#[derive(Clone)]
pub(crate) struct Layout {
pub(crate) logo: String,
@@ -34,17 +35,23 @@ pub(crate) struct Page<'a> {
}
impl<'a> Page<'a> {
- pub(crate) fn get_static_root_path(&self) -> &str {
- self.static_root_path.unwrap_or(self.root_path)
+ pub(crate) fn get_static_root_path(&self) -> String {
+ match self.static_root_path {
+ Some(s) => s.to_string(),
+ None => format!("{}static.files/", self.root_path),
+ }
}
}
#[derive(Template)]
#[template(path = "page.html")]
struct PageLayout<'a> {
- static_root_path: &'a str,
+ static_root_path: String,
page: &'a Page<'a>,
layout: &'a Layout,
+
+ files: &'static StaticFiles,
+
themes: Vec<String>,
sidebar: String,
content: String,
@@ -61,19 +68,17 @@ pub(crate) fn render<T: Print, S: Print>(
) -> String {
let static_root_path = page.get_static_root_path();
let krate_with_trailing_slash = ensure_trailing_slash(&layout.krate).to_string();
- let mut themes: Vec<String> = style_files
- .iter()
- .map(StylePath::basename)
- .collect::<Result<_, Error>>()
- .unwrap_or_default();
+ let mut themes: Vec<String> = style_files.iter().map(|s| s.basename().unwrap()).collect();
themes.sort();
- let rustdoc_version = rustc_interface::util::version_str().unwrap_or("unknown version");
+
+ let rustdoc_version = rustc_interface::util::version_str!().unwrap_or("unknown version");
let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar.
let sidebar = Buffer::html().to_display(sidebar);
PageLayout {
static_root_path,
page,
layout,
+ files: &STATIC_FILES,
themes,
sidebar,
content,
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 5733d1f9c..73690c86f 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -32,7 +32,7 @@ use crate::html::escape::Escape;
use crate::html::format::{join_with_double_colon, Buffer};
use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap};
use crate::html::url_parts_builder::UrlPartsBuilder;
-use crate::html::{layout, sources};
+use crate::html::{layout, sources, static_files};
use crate::scrape_examples::AllCallLocations;
use crate::try_err;
@@ -69,11 +69,13 @@ pub(crate) struct Context<'tcx> {
/// the source files are present in the html rendering, then this will be
/// `true`.
pub(crate) include_sources: bool,
+ /// Collection of all types with notable traits referenced in the current module.
+ pub(crate) types_with_notable_traits: FxHashSet<clean::Type>,
}
// `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
#[cfg(all(not(windows), target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Context<'_>, 128);
+rustc_data_structures::static_assert_size!(Context<'_>, 160);
/// Shared mutable state used in [`Context`] and elsewhere.
pub(crate) struct SharedContext<'tcx> {
@@ -498,7 +500,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
);
let (sender, receiver) = channel();
- let mut scx = SharedContext {
+ let scx = SharedContext {
tcx,
src_root,
local_sources,
@@ -521,19 +523,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
call_locations,
};
- // Add the default themes to the `Vec` of stylepaths
- //
- // Note that these must be added before `sources::render` is called
- // so that the resulting source pages are styled
- //
- // `light.css` is not disabled because it is the stylesheet that stays loaded
- // by the browser as the theme stylesheet. The theme system (hackily) works by
- // changing the href to this stylesheet. All other themes are disabled to
- // prevent rule conflicts
- scx.style_files.push(StylePath { path: PathBuf::from("light.css") });
- scx.style_files.push(StylePath { path: PathBuf::from("dark.css") });
- scx.style_files.push(StylePath { path: PathBuf::from("ayu.css") });
-
let dst = output;
scx.ensure_dir(&dst)?;
@@ -545,6 +534,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
deref_id_map: FxHashMap::default(),
shared: Rc::new(scx),
include_sources,
+ types_with_notable_traits: FxHashSet::default(),
};
if emit_crate {
@@ -573,6 +563,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
id_map: IdMap::new(),
shared: Rc::clone(&self.shared),
include_sources: self.include_sources,
+ types_with_notable_traits: FxHashSet::default(),
}
}
@@ -647,10 +638,11 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
</section>\
</noscript>\
<link rel=\"stylesheet\" type=\"text/css\" \
- href=\"{root_path}settings{suffix}.css\">\
- <script defer src=\"{root_path}settings{suffix}.js\"></script>",
- root_path = page.static_root_path.unwrap_or(""),
- suffix = page.resource_suffix,
+ href=\"{static_root_path}{settings_css}\">\
+ <script defer src=\"{static_root_path}{settings_js}\"></script>",
+ static_root_path = page.get_static_root_path(),
+ settings_css = static_files::STATIC_FILES.settings_css,
+ settings_js = static_files::STATIC_FILES.settings_js,
)
},
&shared.style_files,
@@ -815,6 +807,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
}
}
}
+
Ok(())
}
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 96c57c8c8..36d15ec3b 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -59,7 +59,7 @@ use rustc_span::{
symbol::{sym, Symbol},
BytePos, FileName, RealFileName,
};
-use serde::ser::SerializeSeq;
+use serde::ser::{SerializeMap, SerializeSeq};
use serde::{Serialize, Serializer};
use crate::clean::{self, ItemId, RenderedLink, SelfTy};
@@ -70,8 +70,8 @@ use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape;
use crate::html::format::{
href, join_with_double_colon, print_abi_with_space, print_constness_with_space,
- print_default_space, print_generic_bounds, print_where_clause, Buffer, Ending, HrefError,
- PrintWithSpace,
+ print_default_space, print_generic_bounds, print_where_clause, visibility_print_with_space,
+ Buffer, Ending, HrefError, PrintWithSpace,
};
use crate::html::highlight;
use crate::html::markdown::{
@@ -747,11 +747,12 @@ fn assoc_const(
extra: &str,
cx: &Context<'_>,
) {
+ let tcx = cx.tcx();
write!(
w,
"{extra}{vis}const <a{href} class=\"constant\">{name}</a>: {ty}",
extra = extra,
- vis = it.visibility.print_with_space(it.item_id, cx),
+ vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
href = assoc_href_attr(it, link, cx),
name = it.name.as_ref().unwrap(),
ty = ty.print(cx),
@@ -764,7 +765,7 @@ fn assoc_const(
// This hurts readability in this context especially when more complex expressions
// are involved and it doesn't add much of value.
// Find a way to print constants here without all that jazz.
- write!(w, "{}", Escape(&default.value(cx.tcx()).unwrap_or_else(|| default.expr(cx.tcx()))));
+ write!(w, "{}", Escape(&default.value(tcx).unwrap_or_else(|| default.expr(tcx))));
}
}
@@ -802,17 +803,18 @@ fn assoc_method(
d: &clean::FnDecl,
link: AssocItemLink<'_>,
parent: ItemType,
- cx: &Context<'_>,
+ cx: &mut Context<'_>,
render_mode: RenderMode,
) {
- let header = meth.fn_header(cx.tcx()).expect("Trying to get header from a non-function item");
+ let tcx = cx.tcx();
+ let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item");
let name = meth.name.as_ref().unwrap();
- let vis = meth.visibility.print_with_space(meth.item_id, cx).to_string();
+ let vis = visibility_print_with_space(meth.visibility(tcx), meth.item_id, cx).to_string();
// FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove
// this condition.
let constness = match render_mode {
RenderMode::Normal => {
- print_constness_with_space(&header.constness, meth.const_stability(cx.tcx()))
+ print_constness_with_space(&header.constness, meth.const_stability(tcx))
}
RenderMode::ForDeref { .. } => "",
};
@@ -834,6 +836,8 @@ fn assoc_method(
+ name.as_str().len()
+ generics_len;
+ let notable_traits = d.output.as_return().and_then(|output| notable_traits_button(output, cx));
+
let (indent, indent_str, end_newline) = if parent == ItemType::Trait {
header_len += 4;
let indent_str = " ";
@@ -843,10 +847,10 @@ fn assoc_method(
render_attributes_in_code(w, meth);
(0, "", Ending::Newline)
};
- w.reserve(header_len + "<a href=\"\" class=\"fnname\">{".len() + "</a>".len());
+ w.reserve(header_len + "<a href=\"\" class=\"fn\">{".len() + "</a>".len());
write!(
w,
- "{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn <a{href} class=\"fnname\">{name}</a>\
+ "{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn <a{href} class=\"fn\">{name}</a>\
{generics}{decl}{notable_traits}{where_clause}",
indent = indent_str,
vis = vis,
@@ -859,9 +863,9 @@ fn assoc_method(
name = name,
generics = g.print(cx),
decl = d.full_print(header_len, indent, cx),
- notable_traits = notable_traits_decl(d, cx),
+ notable_traits = notable_traits.unwrap_or_default(),
where_clause = print_where_clause(g, cx, indent, end_newline),
- )
+ );
}
/// Writes a span containing the versions at which an item became stable and/or const-stable. For
@@ -961,7 +965,7 @@ fn render_assoc_item(
item: &clean::Item,
link: AssocItemLink<'_>,
parent: ItemType,
- cx: &Context<'_>,
+ cx: &mut Context<'_>,
render_mode: RenderMode,
) {
match &*item.kind {
@@ -1067,7 +1071,7 @@ fn write_impl_section_heading(w: &mut Buffer, title: &str, id: &str) {
w,
"<h2 id=\"{id}\" class=\"small-section-header\">\
{title}\
- <a href=\"#{id}\" class=\"anchor\"></a>\
+ <a href=\"#{id}\" class=\"anchor\">§</a>\
</h2>"
);
}
@@ -1271,88 +1275,133 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
}
}
-fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
- let mut out = Buffer::html();
+pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> Option<String> {
+ let mut has_notable_trait = false;
+
+ let did = ty.def_id(cx.cache())?;
- if let Some((did, ty)) = decl.output.as_return().and_then(|t| Some((t.def_id(cx.cache())?, t)))
+ // Box has pass-through impls for Read, Write, Iterator, and Future when the
+ // boxed type implements one of those. We don't want to treat every Box return
+ // as being notably an Iterator (etc), though, so we exempt it. Pin has the same
+ // issue, with a pass-through impl for Future.
+ if Some(did) == cx.tcx().lang_items().owned_box()
+ || Some(did) == cx.tcx().lang_items().pin_type()
{
- // Box has pass-through impls for Read, Write, Iterator, and Future when the
- // boxed type implements one of those. We don't want to treat every Box return
- // as being notably an Iterator (etc), though, so we exempt it. Pin has the same
- // issue, with a pass-through impl for Future.
- if Some(did) == cx.tcx().lang_items().owned_box()
- || Some(did) == cx.tcx().lang_items().pin_type()
- {
- return "".to_string();
- }
- if let Some(impls) = cx.cache().impls.get(&did) {
- for i in impls {
- let impl_ = i.inner_impl();
- if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache())
+ return None;
+ }
+
+ if let Some(impls) = cx.cache().impls.get(&did) {
+ for i in impls {
+ let impl_ = i.inner_impl();
+ if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache()) {
+ // Two different types might have the same did,
+ // without actually being the same.
+ continue;
+ }
+ if let Some(trait_) = &impl_.trait_ {
+ let trait_did = trait_.def_id();
+
+ if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable_trait(cx.tcx()))
{
- // Two different types might have the same did,
- // without actually being the same.
- continue;
+ has_notable_trait = true;
}
- if let Some(trait_) = &impl_.trait_ {
- let trait_did = trait_.def_id();
-
- if cx
- .cache()
- .traits
- .get(&trait_did)
- .map_or(false, |t| t.is_notable_trait(cx.tcx()))
- {
- if out.is_empty() {
- write!(
- &mut out,
- "<span class=\"notable\">Notable traits for {}</span>\
- <code class=\"content\">",
- impl_.for_.print(cx)
- );
- }
+ }
+ }
+ }
- //use the "where" class here to make it small
- write!(
+ if has_notable_trait {
+ cx.types_with_notable_traits.insert(ty.clone());
+ Some(format!(
+ " <a href=\"#\" class=\"notable-traits\" data-ty=\"{ty}\">ⓘ</a>",
+ ty = Escape(&format!("{:#}", ty.print(cx))),
+ ))
+ } else {
+ None
+ }
+}
+
+fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
+ let mut out = Buffer::html();
+
+ let did = ty.def_id(cx.cache()).expect("notable_traits_button already checked this");
+
+ let impls = cx.cache().impls.get(&did).expect("notable_traits_button already checked this");
+
+ for i in impls {
+ let impl_ = i.inner_impl();
+ if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache()) {
+ // Two different types might have the same did,
+ // without actually being the same.
+ continue;
+ }
+ if let Some(trait_) = &impl_.trait_ {
+ let trait_did = trait_.def_id();
+
+ if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable_trait(cx.tcx())) {
+ if out.is_empty() {
+ write!(
+ &mut out,
+ "<h3>Notable traits for <code>{}</code></h3>\
+ <pre class=\"content\"><code>",
+ impl_.for_.print(cx)
+ );
+ }
+
+ //use the "where" class here to make it small
+ write!(
+ &mut out,
+ "<span class=\"where fmt-newline\">{}</span>",
+ impl_.print(false, cx)
+ );
+ for it in &impl_.items {
+ if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
+ out.push_str("<span class=\"where fmt-newline\"> ");
+ let empty_set = FxHashSet::default();
+ let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set);
+ assoc_type(
&mut out,
- "<span class=\"where fmt-newline\">{}</span>",
- impl_.print(false, cx)
+ it,
+ &tydef.generics,
+ &[], // intentionally leaving out bounds
+ Some(&tydef.type_),
+ src_link,
+ 0,
+ cx,
);
- for it in &impl_.items {
- if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
- out.push_str("<span class=\"where fmt-newline\"> ");
- let empty_set = FxHashSet::default();
- let src_link =
- AssocItemLink::GotoSource(trait_did.into(), &empty_set);
- assoc_type(
- &mut out,
- it,
- &tydef.generics,
- &[], // intentionally leaving out bounds
- Some(&tydef.type_),
- src_link,
- 0,
- cx,
- );
- out.push_str(";</span>");
- }
- }
+ out.push_str(";</span>");
}
}
}
}
}
-
- if !out.is_empty() {
- out.insert_str(
- 0,
- "<span class=\"notable-traits\"><span class=\"notable-traits-tooltip\">ⓘ\
- <span class=\"notable-traits-tooltiptext\"><span class=\"docblock\">",
- );
- out.push_str("</code></span></span></span></span>");
+ if out.is_empty() {
+ write!(&mut out, "</code></pre>",);
}
- out.into_inner()
+ (format!("{:#}", ty.print(cx)), out.into_inner())
+}
+
+pub(crate) fn notable_traits_json<'a>(
+ tys: impl Iterator<Item = &'a clean::Type>,
+ cx: &Context<'_>,
+) -> String {
+ let mut mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect();
+ mp.sort_by(|(name1, _html1), (name2, _html2)| name1.cmp(name2));
+ struct NotableTraitsMap(Vec<(String, String)>);
+ impl Serialize for NotableTraitsMap {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut map = serializer.serialize_map(Some(self.0.len()))?;
+ for item in &self.0 {
+ map.serialize_entry(&item.0, &item.1)?;
+ }
+ map.end()
+ }
+ }
+ serde_json::to_string(&NotableTraitsMap(mp))
+ .expect("serialize (string, string) -> json object cannot fail")
}
#[derive(Clone, Copy, Debug)]
@@ -1487,7 +1536,7 @@ fn render_impl(
render_rightside(w, cx, item, containing_item, render_mode);
if trait_.is_some() {
// Anchors are only used on trait impls.
- write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
+ write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id);
}
w.write_str("<h4 class=\"code-header\">");
render_assoc_item(
@@ -1513,7 +1562,7 @@ fn render_impl(
render_rightside(w, cx, item, containing_item, render_mode);
if trait_.is_some() {
// Anchors are only used on trait impls.
- write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
+ write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id);
}
w.write_str("<h4 class=\"code-header\">");
assoc_const(
@@ -1538,7 +1587,7 @@ fn render_impl(
write!(w, "<section id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class);
if trait_.is_some() {
// Anchors are only used on trait impls.
- write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
+ write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id);
}
w.write_str("<h4 class=\"code-header\">");
assoc_type(
@@ -1564,7 +1613,7 @@ fn render_impl(
);
if trait_.is_some() {
// Anchors are only used on trait impls.
- write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
+ write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id);
}
w.write_str("<h4 class=\"code-header\">");
assoc_type(
@@ -1797,7 +1846,7 @@ pub(crate) fn render_impl_summary(
};
write!(w, "<section id=\"{}\" class=\"impl has-srclink\"{}>", id, aliases);
render_rightside(w, cx, &i.impl_item, containing_item, RenderMode::Normal);
- write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
+ write!(w, "<a href=\"#{}\" class=\"anchor\">§</a>", id);
write!(w, "<h3 class=\"code-header\">");
if let Some(use_absolute) = use_absolute {
@@ -2231,12 +2280,12 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
let fields = get_struct_fields_name(&s.fields);
if !fields.is_empty() {
- match s.struct_type {
- CtorKind::Fictive => {
+ match s.ctor_kind {
+ None => {
print_sidebar_block(&mut sidebar, "fields", "Fields", fields.iter());
}
- CtorKind::Fn => print_sidebar_title(&mut sidebar, "fields", "Tuple Fields"),
- CtorKind::Const => {}
+ Some(CtorKind::Fn) => print_sidebar_title(&mut sidebar, "fields", "Tuple Fields"),
+ Some(CtorKind::Const) => {}
}
}
@@ -2866,11 +2915,7 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
);
if line_ranges.len() > 1 {
- write!(w, r#"<span class="prev">&pr;</span> <span class="next">&sc;</span>"#);
- }
-
- if needs_expansion {
- write!(w, r#"<span class="expand">&varr;</span>"#);
+ write!(w, r#"<button class="prev">&pr;</button> <button class="next">&sc;</button>"#);
}
// Look for the example file in the source map if it exists, otherwise return a dummy span
@@ -2892,9 +2937,6 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
})()
.unwrap_or(rustc_span::DUMMY_SP);
- // The root path is the inverse of Context::current
- let root_path = vec!["../"; cx.current.len() - 1].join("");
-
let mut decoration_info = FxHashMap::default();
decoration_info.insert("highlight focus", vec![byte_ranges.remove(0)]);
decoration_info.insert("highlight", byte_ranges);
@@ -2904,9 +2946,9 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
contents_subset,
file_span,
cx,
- &root_path,
+ &cx.root_path(),
highlight::DecorationInfo(decoration_info),
- sources::SourceContext::Embedded { offset: line_min },
+ sources::SourceContext::Embedded { offset: line_min, needs_expansion },
);
write!(w, "</div></div>");
@@ -2915,14 +2957,23 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite
// The call locations are output in sequence, so that sequence needs to be determined.
// Ideally the most "relevant" examples would be shown first, but there's no general algorithm
- // for determining relevance. Instead, we prefer the smallest examples being likely the easiest to
- // understand at a glance.
+ // for determining relevance. We instead proxy relevance with the following heuristics:
+ // 1. Code written to be an example is better than code not written to be an example, e.g.
+ // a snippet from examples/foo.rs is better than src/lib.rs. We don't know the Cargo
+ // directory structure in Rustdoc, so we proxy this by prioritizing code that comes from
+ // a --crate-type bin.
+ // 2. Smaller examples are better than large examples. So we prioritize snippets that have
+ // the smallest number of lines in their enclosing item.
+ // 3. Finally we sort by the displayed file name, which is arbitrary but prevents the
+ // ordering of examples from randomly changing between Rustdoc invocations.
let ordered_locations = {
- let sort_criterion = |(_, call_data): &(_, &CallData)| {
+ fn sort_criterion<'a>(
+ (_, call_data): &(&PathBuf, &'a CallData),
+ ) -> (bool, u32, &'a String) {
// Use the first location because that's what the user will see initially
let (lo, hi) = call_data.locations[0].enclosing_item.byte_span;
- hi - lo
- };
+ (!call_data.is_bin, hi - lo, &call_data.display_name)
+ }
let mut locs = call_locations.iter().collect::<Vec<_>>();
locs.sort_by_key(sort_criterion);
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 632781736..acbe3f228 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -7,19 +7,20 @@ use rustc_hir::def_id::DefId;
use rustc_middle::middle::stability;
use rustc_middle::span_bug;
use rustc_middle::ty::layout::LayoutError;
-use rustc_middle::ty::{Adt, TyCtxt};
+use rustc_middle::ty::{self, Adt, TyCtxt};
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_target::abi::{Layout, Primitive, TagEncoding, Variants};
+use rustc_target::abi::{LayoutS, Primitive, TagEncoding, VariantIdx, Variants};
use std::cmp::Ordering;
use std::fmt;
use std::rc::Rc;
use super::{
collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference,
- item_ty_to_section, notable_traits_decl, render_all_impls, render_assoc_item,
- render_assoc_items, render_attributes_in_code, render_attributes_in_pre, render_impl,
- render_rightside, render_stability_since_raw, AssocItemLink, Context, ImplRenderingParameters,
+ item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls,
+ render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre,
+ render_impl, render_rightside, render_stability_since_raw,
+ render_stability_since_raw_with_extra, AssocItemLink, Context, ImplRenderingParameters,
};
use crate::clean;
use crate::config::ModuleSorting;
@@ -28,12 +29,12 @@ use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape;
use crate::html::format::{
join_with_double_colon, print_abi_with_space, print_constness_with_space, print_where_clause,
- Buffer, Ending, PrintWithSpace,
+ visibility_print_with_space, Buffer, Ending, PrintWithSpace,
};
-use crate::html::highlight;
use crate::html::layout::Page;
use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
use crate::html::url_parts_builder::UrlPartsBuilder;
+use crate::html::{highlight, static_files};
use askama::Template;
use itertools::Itertools;
@@ -52,8 +53,8 @@ struct PathComponent {
#[derive(Template)]
#[template(path = "print_item.html")]
struct ItemVars<'a> {
- page: &'a Page<'a>,
static_root_path: &'a str,
+ clipboard_svg: &'static static_files::StaticFile,
typ: &'a str,
name: &'a str,
item_type: &'a str,
@@ -147,8 +148,8 @@ pub(super) fn print_item(
};
let item_vars = ItemVars {
- page,
- static_root_path: page.get_static_root_path(),
+ static_root_path: &page.get_static_root_path(),
+ clipboard_svg: &static_files::STATIC_FILES.clipboard_svg,
typ,
name: item.name.as_ref().unwrap().as_str(),
item_type: &item.type_().to_string(),
@@ -183,6 +184,16 @@ pub(super) fn print_item(
unreachable!();
}
}
+
+ // Render notable-traits.js used for all methods in this module.
+ if !cx.types_with_notable_traits.is_empty() {
+ write!(
+ buf,
+ r#"<script type="text/json" id="notable-traits-data">{}</script>"#,
+ notable_traits_json(cx.types_with_notable_traits.iter(), cx)
+ );
+ cx.types_with_notable_traits.clear();
+ }
}
/// For large structs, enums, unions, etc, determine whether to hide their fields
@@ -318,6 +329,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
);
}
+ let tcx = cx.tcx();
match *myitem.kind {
clean::ExternCrateItem { ref src } => {
use crate::html::format::anchor;
@@ -327,14 +339,14 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
Some(src) => write!(
w,
"<div class=\"item-left\"><code>{}extern crate {} as {};",
- myitem.visibility.print_with_space(myitem.item_id, cx),
+ visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx),
anchor(myitem.item_id.expect_def_id(), src, cx),
myitem.name.unwrap(),
),
None => write!(
w,
"<div class=\"item-left\"><code>{}extern crate {};",
- myitem.visibility.print_with_space(myitem.item_id, cx),
+ visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx),
anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx),
),
}
@@ -384,7 +396,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
</div>\
{stab_tags_before}{stab_tags}{stab_tags_after}",
stab = stab.unwrap_or_default(),
- vis = myitem.visibility.print_with_space(myitem.item_id, cx),
+ vis = visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx),
imp = import.print(cx),
);
w.write_str(ITEM_TABLE_ROW_CLOSE);
@@ -408,8 +420,8 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
let stab = myitem.stability_class(cx.tcx());
let add = if stab.is_some() { " " } else { "" };
- let visibility_emoji = match myitem.visibility {
- clean::Visibility::Restricted(_) => {
+ let visibility_emoji = match myitem.visibility(tcx) {
+ Some(ty::Visibility::Restricted(_)) => {
"<span title=\"Restricted Visibility\">&nbsp;🔒</span> "
}
_ => "",
@@ -496,12 +508,13 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) ->
}
fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &clean::Function) {
- let header = it.fn_header(cx.tcx()).expect("printing a function which isn't a function");
- let constness = print_constness_with_space(&header.constness, it.const_stability(cx.tcx()));
+ let tcx = cx.tcx();
+ let header = it.fn_header(tcx).expect("printing a function which isn't a function");
+ let constness = print_constness_with_space(&header.constness, it.const_stability(tcx));
let unsafety = header.unsafety.print_with_space();
let abi = print_abi_with_space(header.abi).to_string();
let asyncness = header.asyncness.print_with_space();
- let visibility = it.visibility.print_with_space(it.item_id, cx).to_string();
+ let visibility = visibility_print_with_space(it.visibility(tcx), it.item_id, cx).to_string();
let name = it.name.unwrap();
let generics_len = format!("{:#}", f.generics.print(cx)).len();
@@ -514,6 +527,9 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
+ name.as_str().len()
+ generics_len;
+ let notable_traits =
+ f.decl.output.as_return().and_then(|output| notable_traits_button(output, cx));
+
wrap_into_item_decl(w, |w| {
wrap_item(w, "fn", |w| {
render_attributes_in_pre(w, it, "");
@@ -531,14 +547,15 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
generics = f.generics.print(cx),
where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline),
decl = f.decl.full_print(header_len, 0, cx),
- notable_traits = notable_traits_decl(&f.decl, cx),
+ notable_traits = notable_traits.unwrap_or_default(),
);
});
});
- document(w, cx, it, None, HeadingOffset::H2)
+ document(w, cx, it, None, HeadingOffset::H2);
}
fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Trait) {
+ let tcx = cx.tcx();
let bounds = bounds(&t.bounds, false, cx);
let required_types = t.items.iter().filter(|m| m.is_ty_associated_type()).collect::<Vec<_>>();
let provided_types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>();
@@ -549,8 +566,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
let count_types = required_types.len() + provided_types.len();
let count_consts = required_consts.len() + provided_consts.len();
let count_methods = required_methods.len() + provided_methods.len();
- let must_implement_one_of_functions =
- cx.tcx().trait_def(t.def_id).must_implement_one_of.clone();
+ let must_implement_one_of_functions = tcx.trait_def(t.def_id).must_implement_one_of.clone();
// Output the trait definition
wrap_into_item_decl(w, |w| {
@@ -559,9 +575,9 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
write!(
w,
"{}{}{}trait {}{}{}",
- it.visibility.print_with_space(it.item_id, cx),
- t.unsafety(cx.tcx()).print_with_space(),
- if t.is_auto(cx.tcx()) { "auto " } else { "" },
+ visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
+ t.unsafety(tcx).print_with_space(),
+ if t.is_auto(tcx) { "auto " } else { "" },
it.name.unwrap(),
t.generics.print(cx),
bounds
@@ -701,7 +717,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
write!(
w,
"<h2 id=\"{0}\" class=\"small-section-header\">\
- {1}<a href=\"#{0}\" class=\"anchor\"></a>\
+ {1}<a href=\"#{0}\" class=\"anchor\">§</a>\
</h2>{2}",
id, title, extra_content
)
@@ -1020,7 +1036,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
}
let extern_crates = extern_crates
.into_iter()
- .map(|cnum| cx.shared.tcx.crate_name(cnum).to_string())
+ .map(|cnum| tcx.crate_name(cnum).to_string())
.collect::<Vec<_>>()
.join(",");
let (extern_before, extern_after) =
@@ -1084,7 +1100,7 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea
fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
wrap_item(w, "typedef", |w| {
render_attributes_in_pre(w, it, "");
- write!(w, "{}", it.visibility.print_with_space(it.item_id, cx));
+ write!(w, "{}", visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx));
write!(
w,
"type {}{}{where_clause} = {type_};",
@@ -1131,7 +1147,7 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean:
write!(
w,
"<h2 id=\"fields\" class=\"fields small-section-header\">\
- Fields<a href=\"#fields\" class=\"anchor\"></a>\
+ Fields<a href=\"#fields\" class=\"anchor\">§</a>\
</h2>"
);
for (field, ty) in fields {
@@ -1140,7 +1156,7 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean:
write!(
w,
"<span id=\"{id}\" class=\"{shortty} small-section-header\">\
- <a href=\"#{id}\" class=\"anchor field\"></a>\
+ <a href=\"#{id}\" class=\"anchor field\">§</a>\
<code>{name}: {ty}</code>\
</span>",
id = id,
@@ -1173,6 +1189,7 @@ fn print_tuple_struct_fields(w: &mut Buffer, cx: &Context<'_>, s: &[clean::Item]
}
fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::Enum) {
+ let tcx = cx.tcx();
let count_variants = e.variants().count();
wrap_into_item_decl(w, |w| {
wrap_item(w, "enum", |w| {
@@ -1180,7 +1197,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
write!(
w,
"{}enum {}{}",
- it.visibility.print_with_space(it.item_id, cx),
+ visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
it.name.unwrap(),
e.generics.print(cx),
);
@@ -1215,7 +1232,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
w,
v,
None,
- s.struct_type,
+ s.ctor_kind,
&s.fields,
" ",
false,
@@ -1245,35 +1262,35 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
write!(
w,
"<h2 id=\"variants\" class=\"variants small-section-header\">\
- Variants{}<a href=\"#variants\" class=\"anchor\"></a>\
+ Variants{}<a href=\"#variants\" class=\"anchor\">§</a>\
</h2>",
document_non_exhaustive_header(it)
);
document_non_exhaustive(w, it);
+ write!(w, "<div class=\"variants\">");
for variant in e.variants() {
let id = cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.unwrap()));
write!(
w,
- "<h3 id=\"{id}\" class=\"variant small-section-header\">\
- <a href=\"#{id}\" class=\"anchor field\"></a>\
- <code>{name}",
+ "<section id=\"{id}\" class=\"variant\">\
+ <a href=\"#{id}\" class=\"anchor\">§</a>",
id = id,
- name = variant.name.unwrap()
);
+ render_stability_since_raw_with_extra(
+ w,
+ variant.stable_since(tcx),
+ variant.const_stability(tcx),
+ it.stable_since(tcx),
+ it.const_stable_since(tcx),
+ " rightside",
+ );
+ write!(w, "<h3 class=\"code-header\">{name}", name = variant.name.unwrap());
if let clean::VariantItem(clean::Variant::Tuple(ref s)) = *variant.kind {
w.write_str("(");
print_tuple_struct_fields(w, cx, s);
w.write_str(")");
}
- w.write_str("</code>");
- render_stability_since_raw(
- w,
- variant.stable_since(cx.tcx()),
- variant.const_stability(cx.tcx()),
- it.stable_since(cx.tcx()),
- it.const_stable_since(cx.tcx()),
- );
- w.write_str("</h3>");
+ w.write_str("</h3></section>");
use crate::clean::Variant;
@@ -1307,8 +1324,8 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
write!(
w,
"<div class=\"sub-variant-field\">\
- <span id=\"{id}\" class=\"variant small-section-header\">\
- <a href=\"#{id}\" class=\"anchor field\"></a>\
+ <span id=\"{id}\" class=\"small-section-header\">\
+ <a href=\"#{id}\" class=\"anchor field\">§</a>\
<code>{f}:&nbsp;{t}</code>\
</span>",
id = id,
@@ -1326,6 +1343,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
document(w, cx, variant, Some(it), HeadingOffset::H4);
}
+ write!(w, "</div>");
}
let def_id = it.item_id.expect_def_id();
render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
@@ -1389,12 +1407,13 @@ fn item_primitive(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &clean::Constant) {
wrap_into_item_decl(w, |w| {
wrap_item(w, "const", |w| {
+ let tcx = cx.tcx();
render_attributes_in_code(w, it);
write!(
w,
"{vis}const {name}: {typ}",
- vis = it.visibility.print_with_space(it.item_id, cx),
+ vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
name = it.name.unwrap(),
typ = c.type_.print(cx),
);
@@ -1408,9 +1427,9 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle
// ` = 100i32;`
// instead?
- let value = c.value(cx.tcx());
- let is_literal = c.is_literal(cx.tcx());
- let expr = c.expr(cx.tcx());
+ let value = c.value(tcx);
+ let is_literal = c.is_literal(tcx);
+ let expr = c.expr(tcx);
if value.is_some() || is_literal {
write!(w, " = {expr};", expr = Escape(&expr));
} else {
@@ -1439,7 +1458,7 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
wrap_into_item_decl(w, |w| {
wrap_item(w, "struct", |w| {
render_attributes_in_code(w, it);
- render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx);
+ render_struct(w, it, Some(&s.generics), s.ctor_kind, &s.fields, "", true, cx);
});
});
@@ -1453,14 +1472,14 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
_ => None,
})
.peekable();
- if let CtorKind::Fictive | CtorKind::Fn = s.struct_type {
+ if let None | Some(CtorKind::Fn) = s.ctor_kind {
if fields.peek().is_some() {
write!(
w,
"<h2 id=\"fields\" class=\"fields small-section-header\">\
- {}{}<a href=\"#fields\" class=\"anchor\"></a>\
+ {}{}<a href=\"#fields\" class=\"anchor\">§</a>\
</h2>",
- if let CtorKind::Fictive = s.struct_type { "Fields" } else { "Tuple Fields" },
+ if s.ctor_kind.is_none() { "Fields" } else { "Tuple Fields" },
document_non_exhaustive_header(it)
);
document_non_exhaustive(w, it);
@@ -1471,7 +1490,7 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
write!(
w,
"<span id=\"{id}\" class=\"{item_type} small-section-header\">\
- <a href=\"#{id}\" class=\"anchor field\"></a>\
+ <a href=\"#{id}\" class=\"anchor field\">§</a>\
<code>{name}: {ty}</code>\
</span>",
item_type = ItemType::StructField,
@@ -1495,7 +1514,7 @@ fn item_static(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
write!(
w,
"{vis}static {mutability}{name}: {typ}",
- vis = it.visibility.print_with_space(it.item_id, cx),
+ vis = visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx),
mutability = s.mutability.print_with_space(),
name = it.name.unwrap(),
typ = s.type_.print(cx)
@@ -1513,7 +1532,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
write!(
w,
" {}type {};\n}}",
- it.visibility.print_with_space(it.item_id, cx),
+ visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx),
it.name.unwrap(),
);
});
@@ -1666,7 +1685,13 @@ fn render_union(
tab: &str,
cx: &Context<'_>,
) {
- write!(w, "{}union {}", it.visibility.print_with_space(it.item_id, cx), it.name.unwrap(),);
+ let tcx = cx.tcx();
+ write!(
+ w,
+ "{}union {}",
+ visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
+ it.name.unwrap(),
+ );
let where_displayed = g
.map(|g| {
@@ -1693,7 +1718,7 @@ fn render_union(
write!(
w,
" {}{}: {},\n{}",
- field.visibility.print_with_space(field.item_id, cx),
+ visibility_print_with_space(field.visibility(tcx), field.item_id, cx),
field.name.unwrap(),
ty.print(cx),
tab
@@ -1714,16 +1739,17 @@ fn render_struct(
w: &mut Buffer,
it: &clean::Item,
g: Option<&clean::Generics>,
- ty: CtorKind,
+ ty: Option<CtorKind>,
fields: &[clean::Item],
tab: &str,
structhead: bool,
cx: &Context<'_>,
) {
+ let tcx = cx.tcx();
write!(
w,
"{}{}{}",
- it.visibility.print_with_space(it.item_id, cx),
+ visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
if structhead { "struct " } else { "" },
it.name.unwrap()
);
@@ -1731,7 +1757,7 @@ fn render_struct(
write!(w, "{}", g.print(cx))
}
match ty {
- CtorKind::Fictive => {
+ None => {
let where_diplayed = g.map(|g| print_where_clause_and_check(w, g, cx)).unwrap_or(false);
// If there wasn't a `where` clause, we add a whitespace.
@@ -1753,7 +1779,7 @@ fn render_struct(
w,
"\n{} {}{}: {},",
tab,
- field.visibility.print_with_space(field.item_id, cx),
+ visibility_print_with_space(field.visibility(tcx), field.item_id, cx),
field.name.unwrap(),
ty.print(cx),
);
@@ -1773,7 +1799,7 @@ fn render_struct(
}
w.write_str("}");
}
- CtorKind::Fn => {
+ Some(CtorKind::Fn) => {
w.write_str("(");
for (i, field) in fields.iter().enumerate() {
if i > 0 {
@@ -1785,7 +1811,7 @@ fn render_struct(
write!(
w,
"{}{}",
- field.visibility.print_with_space(field.item_id, cx),
+ visibility_print_with_space(field.visibility(tcx), field.item_id, cx),
ty.print(cx),
)
}
@@ -1801,7 +1827,7 @@ fn render_struct(
w.write_str(";");
}
}
- CtorKind::Const => {
+ Some(CtorKind::Const) => {
// Needed for PhantomData.
if let Some(g) = g {
write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline));
@@ -1866,11 +1892,11 @@ fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) {
}
fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
- fn write_size_of_layout(w: &mut Buffer, layout: Layout<'_>, tag_size: u64) {
- if layout.abi().is_unsized() {
+ fn write_size_of_layout(w: &mut Buffer, layout: &LayoutS<VariantIdx>, tag_size: u64) {
+ if layout.abi.is_unsized() {
write!(w, "(unsized)");
} else {
- let bytes = layout.size().bytes() - tag_size;
+ let bytes = layout.size.bytes() - tag_size;
write!(w, "{size} byte{pl}", size = bytes, pl = if bytes == 1 { "" } else { "s" },);
}
}
@@ -1882,7 +1908,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
writeln!(
w,
"<h2 id=\"layout\" class=\"small-section-header\"> \
- Layout<a href=\"#layout\" class=\"anchor\"></a></h2>"
+ Layout<a href=\"#layout\" class=\"anchor\">§</a></h2>"
);
writeln!(w, "<div class=\"docblock\">");
@@ -1901,7 +1927,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
chapter for details on type layout guarantees.</p></div>"
);
w.write_str("<p><strong>Size:</strong> ");
- write_size_of_layout(w, ty_layout.layout, 0);
+ write_size_of_layout(w, &ty_layout.layout.0, 0);
writeln!(w, "</p>");
if let Variants::Multiple { variants, tag, tag_encoding, .. } =
&ty_layout.layout.variants()
@@ -1927,7 +1953,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
for (index, layout) in variants.iter_enumerated() {
let name = adt.variant(index).name;
write!(w, "<li><code>{name}</code>: ", name = name);
- write_size_of_layout(w, *layout, tag_size);
+ write_size_of_layout(w, layout, tag_size);
writeln!(w, "</li>");
}
w.write_str("</ul>");
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 151ec2b28..4514894ca 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -140,7 +140,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
self.tcx.hir()
}
- fn visit_path(&mut self, path: &'tcx rustc_hir::Path<'tcx>, _id: HirId) {
+ fn visit_path(&mut self, path: &rustc_hir::Path<'tcx>, _id: HirId) {
if self.handle_macro(path.span) {
return;
}
@@ -190,12 +190,4 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
}
intravisit::walk_expr(self, expr);
}
-
- fn visit_use(&mut self, path: &'tcx rustc_hir::Path<'tcx>, id: HirId) {
- if self.handle_macro(path.span) {
- return;
- }
- self.handle_path(path);
- intravisit::walk_use(self, path, id);
- }
}
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 85f63c985..94d8a9fec 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -1,10 +1,8 @@
-use std::ffi::OsStr;
use std::fs::{self, File};
use std::io::prelude::*;
use std::io::{self, BufReader};
-use std::path::{Component, Path, PathBuf};
+use std::path::{Component, Path};
use std::rc::Rc;
-use std::sync::LazyLock as Lazy;
use itertools::Itertools;
use rustc_data_structures::flock;
@@ -20,123 +18,20 @@ use crate::error::Error;
use crate::html::{layout, static_files};
use crate::{try_err, try_none};
-static FILES_UNVERSIONED: Lazy<FxHashMap<&str, &[u8]>> = Lazy::new(|| {
- map! {
- "FiraSans-Regular.woff2" => static_files::fira_sans::REGULAR,
- "FiraSans-Medium.woff2" => static_files::fira_sans::MEDIUM,
- "FiraSans-LICENSE.txt" => static_files::fira_sans::LICENSE,
- "SourceSerif4-Regular.ttf.woff2" => static_files::source_serif_4::REGULAR,
- "SourceSerif4-Bold.ttf.woff2" => static_files::source_serif_4::BOLD,
- "SourceSerif4-It.ttf.woff2" => static_files::source_serif_4::ITALIC,
- "SourceSerif4-LICENSE.md" => static_files::source_serif_4::LICENSE,
- "SourceCodePro-Regular.ttf.woff2" => static_files::source_code_pro::REGULAR,
- "SourceCodePro-Semibold.ttf.woff2" => static_files::source_code_pro::SEMIBOLD,
- "SourceCodePro-It.ttf.woff2" => static_files::source_code_pro::ITALIC,
- "SourceCodePro-LICENSE.txt" => static_files::source_code_pro::LICENSE,
- "NanumBarunGothic.ttf.woff2" => static_files::nanum_barun_gothic::REGULAR,
- "NanumBarunGothic-LICENSE.txt" => static_files::nanum_barun_gothic::LICENSE,
- "LICENSE-MIT.txt" => static_files::LICENSE_MIT,
- "LICENSE-APACHE.txt" => static_files::LICENSE_APACHE,
- "COPYRIGHT.txt" => static_files::COPYRIGHT,
- }
-});
-
-enum SharedResource<'a> {
- /// This file will never change, no matter what toolchain is used to build it.
- ///
- /// It does not have a resource suffix.
- Unversioned { name: &'static str },
- /// This file may change depending on the toolchain.
- ///
- /// It has a resource suffix.
- ToolchainSpecific { basename: &'static str },
- /// This file may change for any crate within a build, or based on the CLI arguments.
- ///
- /// This differs from normal invocation-specific files because it has a resource suffix.
- InvocationSpecific { basename: &'a str },
-}
-
-impl SharedResource<'_> {
- fn extension(&self) -> Option<&OsStr> {
- use SharedResource::*;
- match self {
- Unversioned { name }
- | ToolchainSpecific { basename: name }
- | InvocationSpecific { basename: name } => Path::new(name).extension(),
- }
- }
-
- fn path(&self, cx: &Context<'_>) -> PathBuf {
- match self {
- SharedResource::Unversioned { name } => cx.dst.join(name),
- SharedResource::ToolchainSpecific { basename } => cx.suffix_path(basename),
- SharedResource::InvocationSpecific { basename } => cx.suffix_path(basename),
- }
- }
-
- fn should_emit(&self, emit: &[EmitType]) -> bool {
- if emit.is_empty() {
- return true;
- }
- let kind = match self {
- SharedResource::Unversioned { .. } => EmitType::Unversioned,
- SharedResource::ToolchainSpecific { .. } => EmitType::Toolchain,
- SharedResource::InvocationSpecific { .. } => EmitType::InvocationSpecific,
- };
- emit.contains(&kind)
- }
-}
-
-impl Context<'_> {
- fn suffix_path(&self, filename: &str) -> PathBuf {
- // We use splitn vs Path::extension here because we might get a filename
- // like `style.min.css` and we want to process that into
- // `style-suffix.min.css`. Path::extension would just return `css`
- // which would result in `style.min-suffix.css` which isn't what we
- // want.
- let (base, ext) = filename.split_once('.').unwrap();
- let filename = format!("{}{}.{}", base, self.shared.resource_suffix, ext);
- self.dst.join(&filename)
- }
-
- fn write_shared(
- &self,
- resource: SharedResource<'_>,
- contents: impl 'static + Send + AsRef<[u8]>,
- emit: &[EmitType],
- ) -> Result<(), Error> {
- if resource.should_emit(emit) {
- self.shared.fs.write(resource.path(self), contents)
- } else {
- Ok(())
- }
- }
-
- fn write_minify(
- &self,
- resource: SharedResource<'_>,
- contents: impl 'static + Send + AsRef<str> + AsRef<[u8]>,
- minify: bool,
- emit: &[EmitType],
- ) -> Result<(), Error> {
- if minify {
- let contents = contents.as_ref();
- let contents = if resource.extension() == Some(OsStr::new("css")) {
- minifier::css::minify(contents)
- .map_err(|e| {
- Error::new(format!("failed to minify CSS file: {}", e), resource.path(self))
- })?
- .to_string()
- } else {
- minifier::js::minify(contents).to_string()
- };
- self.write_shared(resource, contents, emit)
- } else {
- self.write_shared(resource, contents, emit)
- }
- }
-}
-
+/// Rustdoc writes out two kinds of shared files:
+/// - Static files, which are embedded in the rustdoc binary and are written with a
+/// filename that includes a hash of their contents. These will always have a new
+/// URL if the contents change, so they are safe to cache with the
+/// `Cache-Control: immutable` directive. They are written under the static.files/
+/// directory and are written when --emit-type is empty (default) or contains
+/// "toolchain-specific". If using the --static-root-path flag, it should point
+/// to a URL path prefix where each of these filenames can be fetched.
+/// - Invocation specific files. These are generated based on the crate(s) being
+/// documented. Their filenames need to be predictable without knowing their
+/// contents, so they do not include a hash in their filename and are not safe to
+/// cache with `Cache-Control: immutable`. They include the contents of the
+/// --resource-suffix flag and are emitted when --emit-type is empty (default)
+/// or contains "invocation-specific".
pub(super) fn write_shared(
cx: &mut Context<'_>,
krate: &Crate,
@@ -149,139 +44,52 @@ pub(super) fn write_shared(
let lock_file = cx.dst.join(".lock");
let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file);
- // Minified resources are usually toolchain resources. If they're not, they should use `cx.write_minify` directly.
- fn write_minify(
- basename: &'static str,
- contents: impl 'static + Send + AsRef<str> + AsRef<[u8]>,
- cx: &Context<'_>,
- options: &RenderOptions,
- ) -> Result<(), Error> {
- cx.write_minify(
- SharedResource::ToolchainSpecific { basename },
- contents,
- options.enable_minification,
- &options.emit,
- )
- }
-
- // Toolchain resources should never be dynamic.
- let write_toolchain = |p: &'static _, c: &'static _| {
- cx.write_shared(SharedResource::ToolchainSpecific { basename: p }, c, &options.emit)
- };
-
- // Crate resources should always be dynamic.
- let write_crate = |p: &_, make_content: &dyn Fn() -> Result<Vec<u8>, Error>| {
+ // InvocationSpecific resources should always be dynamic.
+ let write_invocation_specific = |p: &str, make_content: &dyn Fn() -> Result<Vec<u8>, Error>| {
let content = make_content()?;
- cx.write_shared(SharedResource::InvocationSpecific { basename: p }, content, &options.emit)
+ if options.emit.is_empty() || options.emit.contains(&EmitType::InvocationSpecific) {
+ let output_filename = static_files::suffix_path(p, &cx.shared.resource_suffix);
+ cx.shared.fs.write(cx.dst.join(output_filename), content)
+ } else {
+ Ok(())
+ }
};
- // Given "foo.svg", return e.g. "url(\"foo1.58.0.svg\")"
- fn ver_url(cx: &Context<'_>, basename: &'static str) -> String {
- format!(
- "url(\"{}\")",
- SharedResource::ToolchainSpecific { basename }
- .path(cx)
- .file_name()
- .unwrap()
- .to_str()
- .unwrap()
- )
- }
-
- // We use the AUTOREPLACE mechanism to inject into our static JS and CSS certain
- // values that are only known at doc build time. Since this mechanism is somewhat
- // surprising when reading the code, please limit it to rustdoc.css.
- write_minify(
- "rustdoc.css",
- static_files::RUSTDOC_CSS
- .replace(
- "/* AUTOREPLACE: */url(\"toggle-minus.svg\")",
- &ver_url(cx, "toggle-minus.svg"),
- )
- .replace("/* AUTOREPLACE: */url(\"toggle-plus.svg\")", &ver_url(cx, "toggle-plus.svg"))
- .replace("/* AUTOREPLACE: */url(\"down-arrow.svg\")", &ver_url(cx, "down-arrow.svg")),
- cx,
- options,
- )?;
-
- // Add all the static files. These may already exist, but we just
- // overwrite them anyway to make sure that they're fresh and up-to-date.
- write_minify("settings.css", static_files::SETTINGS_CSS, cx, options)?;
- write_minify("noscript.css", static_files::NOSCRIPT_CSS, cx, options)?;
-
- // To avoid "light.css" to be overwritten, we'll first run over the received themes and only
- // then we'll run over the "official" styles.
- let mut themes: FxHashSet<String> = FxHashSet::default();
+ cx.shared
+ .fs
+ .create_dir_all(cx.dst.join("static.files"))
+ .map_err(|e| PathError::new(e, "static.files"))?;
+ // Handle added third-party themes
for entry in &cx.shared.style_files {
let theme = entry.basename()?;
let extension =
try_none!(try_none!(entry.path.extension(), &entry.path).to_str(), &entry.path);
- // Handle the official themes
- match theme.as_str() {
- "light" => write_minify("light.css", static_files::themes::LIGHT, cx, options)?,
- "dark" => write_minify("dark.css", static_files::themes::DARK, cx, options)?,
- "ayu" => write_minify("ayu.css", static_files::themes::AYU, cx, options)?,
- _ => {
- // Handle added third-party themes
- let filename = format!("{}.{}", theme, extension);
- write_crate(&filename, &|| Ok(try_err!(fs::read(&entry.path), &entry.path)))?;
- }
- };
-
- themes.insert(theme.to_owned());
- }
-
- if (*cx.shared).layout.logo.is_empty() {
- write_toolchain("rust-logo.svg", static_files::RUST_LOGO_SVG)?;
- }
- if (*cx.shared).layout.favicon.is_empty() {
- write_toolchain("favicon.svg", static_files::RUST_FAVICON_SVG)?;
- write_toolchain("favicon-16x16.png", static_files::RUST_FAVICON_PNG_16)?;
- write_toolchain("favicon-32x32.png", static_files::RUST_FAVICON_PNG_32)?;
- }
- write_toolchain("wheel.svg", static_files::WHEEL_SVG)?;
- write_toolchain("clipboard.svg", static_files::CLIPBOARD_SVG)?;
- write_toolchain("down-arrow.svg", static_files::DOWN_ARROW_SVG)?;
- write_toolchain("toggle-minus.svg", static_files::TOGGLE_MINUS_PNG)?;
- write_toolchain("toggle-plus.svg", static_files::TOGGLE_PLUS_PNG)?;
-
- let mut themes: Vec<&String> = themes.iter().collect();
- themes.sort();
-
- write_minify("main.js", static_files::MAIN_JS, cx, options)?;
- write_minify("search.js", static_files::SEARCH_JS, cx, options)?;
- write_minify("settings.js", static_files::SETTINGS_JS, cx, options)?;
-
- if cx.include_sources {
- write_minify("source-script.js", static_files::sidebar::SOURCE_SCRIPT, cx, options)?;
- }
-
- write_minify("storage.js", static_files::STORAGE_JS, cx, options)?;
+ // Skip the official themes. They are written below as part of STATIC_FILES_LIST.
+ if matches!(theme.as_str(), "light" | "dark" | "ayu") {
+ continue;
+ }
- if cx.shared.layout.scrape_examples_extension {
- cx.write_minify(
- SharedResource::InvocationSpecific { basename: "scrape-examples.js" },
- static_files::SCRAPE_EXAMPLES_JS,
- options.enable_minification,
- &options.emit,
- )?;
+ let bytes = try_err!(fs::read(&entry.path), &entry.path);
+ let filename = format!("{}{}.{}", theme, cx.shared.resource_suffix, extension);
+ cx.shared.fs.write(cx.dst.join(filename), bytes)?;
}
+ // When the user adds their own CSS files with --extend-css, we write that as an
+ // invocation-specific file (that is, with a resource suffix).
if let Some(ref css) = cx.shared.layout.css_file_extension {
let buffer = try_err!(fs::read_to_string(css), css);
- // This varies based on the invocation, so it can't go through the write_minify wrapper.
- cx.write_minify(
- SharedResource::InvocationSpecific { basename: "theme.css" },
- buffer,
- options.enable_minification,
- &options.emit,
- )?;
+ let path = static_files::suffix_path("theme.css", &cx.shared.resource_suffix);
+ cx.shared.fs.write(cx.dst.join(path), buffer)?;
}
- write_minify("normalize.css", static_files::NORMALIZE_CSS, cx, options)?;
- for (name, contents) in &*FILES_UNVERSIONED {
- cx.write_shared(SharedResource::Unversioned { name }, contents, &options.emit)?;
+
+ if options.emit.is_empty() || options.emit.contains(&EmitType::Toolchain) {
+ let static_dir = cx.dst.join(Path::new("static.files"));
+ static_files::for_each(|f: &static_files::StaticFile| {
+ let filename = static_dir.join(f.output_filename());
+ cx.shared.fs.write(filename, f.minified())
+ })?;
}
/// Read a file and return all lines that match the `"{crate}":{data},` format,
@@ -463,7 +271,7 @@ pub(super) fn write_shared(
v.push_str("\\\n}');\ncreateSourceSidebar();\n");
Ok(v.into_bytes())
};
- write_crate("source-files.js", &make_sources)?;
+ write_invocation_specific("source-files.js", &make_sources)?;
}
// Update the search index and crate list.
@@ -477,7 +285,7 @@ pub(super) fn write_shared(
// Sort the indexes by crate so the file will be generated identically even
// with rustdoc running in parallel.
all_indexes.sort();
- write_crate("search-index.js", &|| {
+ write_invocation_specific("search-index.js", &|| {
let mut v = String::from("var searchIndex = JSON.parse('{\\\n");
v.push_str(&all_indexes.join(",\\\n"));
v.push_str(
@@ -490,7 +298,7 @@ if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
Ok(v.into_bytes())
})?;
- write_crate("crates.js", &|| {
+ write_invocation_specific("crates.js", &|| {
let krates = krates.iter().map(|k| format!("\"{}\"", k)).join(",");
Ok(format!("window.ALL_CRATES = [{}];", krates).into_bytes())
})?;
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 7ab65bff3..54e296959 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -258,7 +258,7 @@ where
pub(crate) enum SourceContext {
Standalone,
- Embedded { offset: usize },
+ Embedded { offset: usize, needs_expansion: bool },
}
/// Wrapper struct to render the source code of a file. This will do things like
@@ -274,28 +274,37 @@ pub(crate) fn print_src(
) {
let lines = s.lines().count();
let mut line_numbers = Buffer::empty_from(buf);
+ let extra;
line_numbers.write_str("<pre class=\"src-line-numbers\">");
+ let current_href = &context
+ .href_from_span(clean::Span::new(file_span), false)
+ .expect("only local crates should have sources emitted");
match source_context {
SourceContext::Standalone => {
+ extra = None;
for line in 1..=lines {
- writeln!(line_numbers, "<span id=\"{0}\">{0}</span>", line)
+ writeln!(line_numbers, "<a href=\"#{line}\" id=\"{line}\">{line}</a>")
}
}
- SourceContext::Embedded { offset } => {
- for line in 1..=lines {
- writeln!(line_numbers, "<span>{0}</span>", line + offset)
+ SourceContext::Embedded { offset, needs_expansion } => {
+ extra = if needs_expansion {
+ Some(r#"<button class="expand">&varr;</button>"#)
+ } else {
+ None
+ };
+ for line_number in 1..=lines {
+ let line = line_number + offset;
+ writeln!(line_numbers, "<span>{line}</span>")
}
}
}
line_numbers.write_str("</pre>");
- let current_href = &context
- .href_from_span(clean::Span::new(file_span), false)
- .expect("only local crates should have sources emitted");
highlight::render_source_with_highlighting(
s,
buf,
line_numbers,
highlight::HrefContext { context, file_span, root_path, current_href },
decoration_info,
+ extra,
);
}
diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css
index 301f03a16..54e8b6561 100644
--- a/src/librustdoc/html/static/css/noscript.css
+++ b/src/librustdoc/html/static/css/noscript.css
@@ -22,3 +22,9 @@ nav.sub {
.source .sidebar {
display: none;
}
+
+.notable-traits {
+ /* layout requires javascript
+ https://github.com/rust-lang/rust/issues/102576 */
+ display: none;
+}
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 1cc954a98..afcb40224 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -4,7 +4,7 @@
font-style: normal;
font-weight: 400;
src: local('Fira Sans'),
- url("FiraSans-Regular.woff2") format("woff2");
+ url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");
font-display: swap;
}
@font-face {
@@ -12,7 +12,7 @@
font-style: normal;
font-weight: 500;
src: local('Fira Sans Medium'),
- url("FiraSans-Medium.woff2") format("woff2");
+ url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");
font-display: swap;
}
@@ -22,7 +22,7 @@
font-style: normal;
font-weight: 400;
src: local('Source Serif 4'),
- url("SourceSerif4-Regular.ttf.woff2") format("woff2");
+ url("SourceSerif4-Regular-1f7d512b176f0f72.ttf.woff2") format("woff2");
font-display: swap;
}
@font-face {
@@ -30,7 +30,7 @@
font-style: italic;
font-weight: 400;
src: local('Source Serif 4 Italic'),
- url("SourceSerif4-It.ttf.woff2") format("woff2");
+ url("SourceSerif4-It-d034fe4ef9d0fa00.ttf.woff2") format("woff2");
font-display: swap;
}
@font-face {
@@ -38,7 +38,7 @@
font-style: normal;
font-weight: 700;
src: local('Source Serif 4 Bold'),
- url("SourceSerif4-Bold.ttf.woff2") format("woff2");
+ url("SourceSerif4-Bold-124a1ca42af929b6.ttf.woff2") format("woff2");
font-display: swap;
}
@@ -49,28 +49,28 @@
font-weight: 400;
/* Avoid using locally installed font because bad versions are in circulation:
* see https://github.com/rust-lang/rust/issues/24355 */
- src: url("SourceCodePro-Regular.ttf.woff2") format("woff2");
+ src: url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");
font-display: swap;
}
@font-face {
font-family: 'Source Code Pro';
font-style: italic;
font-weight: 400;
- src: url("SourceCodePro-It.ttf.woff2") format("woff2");
+ src: url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");
font-display: swap;
}
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 600;
- src: url("SourceCodePro-Semibold.ttf.woff2") format("woff2");
+ src: url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");
font-display: swap;
}
/* Avoid using legacy CJK serif fonts in Windows like Batang. */
@font-face {
font-family: 'NanumBarunGothic';
- src: url("NanumBarunGothic.ttf.woff2") format("woff2");
+ src: url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");
font-display: swap;
unicode-range: U+AC00-D7AF, U+1100-11FF, U+3130-318F, U+A960-A97F, U+D7B0-D7FF;
}
@@ -159,13 +159,9 @@ h1.fqn {
.main-heading {
display: flex;
flex-wrap: wrap;
- justify-content: space-between;
padding-bottom: 6px;
margin-bottom: 15px;
}
-#toggle-all-docs {
- text-decoration: none;
-}
/* The only headings that get underlines are:
Markdown-generated headings within the top-doc
Rustdoc-generated h2 section headings (e.g. "Implementations", "Required Methods", etc)
@@ -199,17 +195,14 @@ h1, h2, h3, h4, h5, h6,
span.since,
a.srclink,
#help-button > a,
-details.rustdoc-toggle.top-doc > summary,
-details.rustdoc-toggle.non-exhaustive > summary,
-.scraped-example-title,
-.more-examples-toggle summary, .more-examples-toggle .hide-more,
-.example-links a,
+summary.hideme,
+.scraped-example-list,
/* This selector is for the items listed in the "all items" page. */
ul.all-items {
font-family: "Fira Sans", Arial, NanumBarunGothic, sans-serif;
}
-a#toggle-all-docs,
+#toggle-all-docs,
a.anchor,
.small-section-header a,
#source-sidebar a,
@@ -219,12 +212,8 @@ pre.rust a,
.mobile-topbar h2 a,
h1 a,
.search-results a,
-.module-item .stab,
-.import-item .stab,
-.result-name .primitive > i, .result-name .keyword > i,
-.method .where,
-.fn .where,
-.where.fmt-newline {
+.item-left .stab,
+.result-name .primitive > i, .result-name .keyword > i {
color: var(--main-color);
}
@@ -249,7 +238,6 @@ h1 a,
}
.content span.fn, .content a.fn,
-.content .fnname,
.content span.method, .content a.method,
.content span.tymethod, .content a.tymethod {
color: var(--function-link-color);
@@ -297,10 +285,21 @@ p:last-child {
button {
/* Buttons on Safari have different default padding than other platforms. Make them the same. */
padding: 1px 6px;
+ /* Opinionated tweak: use pointer cursor as clickability signifier. */
+ cursor: pointer;
}
/* end tweaks for normalize.css 8 */
+button#toggle-all-docs {
+ padding: 0;
+ background: none;
+ border: none;
+ /* iOS button gradient: https://stackoverflow.com/q/5438567 */
+ -webkit-appearance: none;
+ opacity: 1;
+}
+
.rustdoc {
display: flex;
flex-direction: row;
@@ -311,7 +310,7 @@ main {
position: relative;
flex-grow: 1;
padding: 10px 15px 40px 45px;
- min-width: 0;
+ min-width: 0; /* avoid growing beyond the size limit */
}
.source main {
@@ -360,7 +359,8 @@ img {
overflow: visible;
}
-.sub-logo-container {
+.sub-logo-container, .logo-container {
+ /* zero text boxes so that computed line height = image height exactly */
line-height: 0;
}
@@ -370,14 +370,17 @@ img {
object-fit: contain;
}
+.rust-logo {
+ filter: var(--rust-logo-filter);
+}
+
.sidebar, .mobile-topbar, .sidebar-menu-toggle {
background-color: var(--sidebar-background-color);
}
.sidebar {
font-size: 0.875rem;
- width: 200px;
- min-width: 200px;
+ flex: 0 0 200px;
overflow-y: scroll;
position: sticky;
height: 100vh;
@@ -386,12 +389,7 @@ img {
}
.rustdoc.source .sidebar {
- width: 50px;
- min-width: 0px;
- max-width: 300px;
- flex-grow: 0;
- flex-shrink: 0;
- flex-basis: auto;
+ flex-basis: 50px;
border-right: 1px solid;
overflow-x: hidden;
/* The sidebar is by default hidden */
@@ -412,7 +410,7 @@ img {
.source-sidebar-expanded .source .sidebar {
overflow-y: auto;
- width: 300px;
+ flex-basis: 300px;
}
.source-sidebar-expanded .source .sidebar > *:not(#sidebar-toggle) {
@@ -458,10 +456,9 @@ img {
}
.sidebar .logo-container {
- display: flex;
margin-top: 10px;
margin-bottom: 10px;
- justify-content: center;
+ text-align: center;
}
.version {
@@ -479,23 +476,17 @@ ul.block, .block li {
list-style: none;
}
-.block a,
-.sidebar h2 a,
-.sidebar h3 a {
+.sidebar-elems a,
+.sidebar > h2 a {
display: block;
- padding: 0.25rem;
+ padding: 0.25rem; /* 4px */
margin-left: -0.25rem;
-
- text-overflow: ellipsis;
- overflow: hidden;
}
.sidebar h2 {
overflow-wrap: anywhere;
padding: 0;
- margin: 0;
- margin-top: 0.7rem;
- margin-bottom: 0.7rem;
+ margin: 0.7rem 0;
}
.sidebar h3 {
@@ -523,6 +514,8 @@ ul.block, .block li {
.sidebar-elems .block li a {
white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
}
.mobile-topbar {
@@ -570,15 +563,16 @@ ul.block, .block li {
border-color: var(--example-line-numbers-border-color);
}
-.src-line-numbers span {
- cursor: pointer;
+.src-line-numbers a, .src-line-numbers span {
color: var(--src-line-numbers-span-color);
}
-.src-line-numbers .line-highlighted {
- background-color: var(--src-line-number-highlighted-background-color);
-}
.src-line-numbers :target {
background-color: transparent;
+ border-right: none;
+ padding-right: 0;
+}
+.src-line-numbers .line-highlighted {
+ background-color: var(--src-line-number-highlighted-background-color);
}
.search-loading {
@@ -636,22 +630,16 @@ pre, .rustdoc.source .example-wrap {
.docblock table {
margin: .5em 0;
- width: calc(100% - 2px);
- overflow-x: auto;
- display: block;
border-collapse: collapse;
}
-.docblock table td {
+.docblock table td, .docblock table th {
padding: .5em;
- border: 1px dashed var(--border-color);
- vertical-align: top;
+ border: 1px solid var(--border-color);
}
-.docblock table th {
- padding: .5em;
- text-align: left;
- border: 1px solid var(--border-color);
+.docblock table tbody tr:nth-child(2n) {
+ background: var(--table-alt-row-background-color);
}
/* Shift "where ..." part of method or fn definition down a line */
@@ -672,7 +660,6 @@ pre, .rustdoc.source .example-wrap {
}
#main-content > .item-info {
- margin-top: 0;
margin-left: 0;
}
@@ -701,8 +688,8 @@ a {
}
.small-section-header {
- display: flex;
- justify-content: space-between;
+ /* fields use <span> tags, but should get their own lines */
+ display: block;
position: relative;
}
@@ -710,7 +697,7 @@ a {
display: initial;
}
-.impl:hover > .anchor, .trait-impl:hover > .anchor {
+.impl:hover > .anchor, .trait-impl:hover > .anchor, .variant:hover > .anchor {
display: inline-block;
position: absolute;
}
@@ -730,9 +717,6 @@ a {
h2.small-section-header > .anchor {
padding-right: 6px;
}
-.anchor::before {
- content: '§';
-}
.main-heading a:hover,
.example-wrap > pre.rust a:hover,
@@ -787,14 +771,12 @@ table,
margin-top: 0;
white-space: nowrap;
/* flex layout allows shrinking the <select> appropriately if it becomes too large */
- display: inline-flex;
- max-width: 100%;
+ display: flex;
/* make things look like in a line, despite the fact that we're using a layout
with boxes (i.e. from the flex layout) */
align-items: baseline;
}
#crate-search-div {
- display: inline-block;
/* ensures that 100% in properties of #crate-search-div:after
are relative to the size of this div */
position: relative;
@@ -803,10 +785,8 @@ table,
}
#crate-search {
min-width: 115px;
- padding: 0;
/* keep these two in sync with "@-moz-document url-prefix()" below */
- padding-left: 4px;
- padding-right: 23px;
+ padding: 0 23px 0 4px;
/* prevents the <select> from overflowing the containing div in case it's shrunk */
max-width: 100%;
/* contents can overflow because of max-width limit, then show ellipsis */
@@ -824,6 +804,9 @@ table,
line-height: 1.5;
font-weight: 500;
}
+#crate-search:hover, #crate-search:focus {
+ border-color: var(--crate-search-hover-border);
+}
/* cancel stylistic differences in padding in firefox
for "appearance: none"-style (or equivalent) <select>s */
@-moz-document url-prefix() {
@@ -847,8 +830,13 @@ so that we can apply CSS-filters to change the arrow color in themes */
background-repeat: no-repeat;
background-size: 20px;
background-position: calc(100% - 2px) 56%;
- /* image is black color, themes should apply a "filter" property to change the color */
- background-image: /* AUTOREPLACE: */url("down-arrow.svg");
+ /* image is black color */
+ background-image: url("down-arrow-927217e04c7463ac.svg");
+ /* changes the arrow image color */
+ filter: var(--crate-search-div-filter);
+}
+#crate-search-div:hover::after, #crate-search-div:focus-within::after {
+ filter: var(--crate-search-div-hover-filter);
}
#crate-search > option {
font-size: 1rem;
@@ -873,40 +861,29 @@ so that we can apply CSS-filters to change the arrow color in themes */
.search-results {
display: none;
- padding-bottom: 2em;
}
.search-results.active {
display: block;
- /* prevent overhanging tabs from moving the first result */
- clear: both;
-}
-
-.search-results .desc > span {
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
- display: block;
}
.search-results > a {
- display: block;
+ display: flex;
/* A little margin ensures the browser's outlining of focused links has room to display. */
margin-left: 2px;
margin-right: 2px;
- border-bottom: 1px solid #aaa3;
+ border-bottom: 1px solid var(--search-result-border-color);
+ gap: 1em;
}
.search-results > a > div {
- display: flex;
- flex-flow: row wrap;
+ flex: 1;
}
-.search-results .result-name, .search-results div.desc {
- width: 50%;
-}
-.search-results .result-name {
- padding-right: 1em;
+.search-results > a > div.desc {
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
}
.search-results a:hover,
@@ -914,26 +891,32 @@ so that we can apply CSS-filters to change the arrow color in themes */
background-color: var(--search-result-link-focus-background-color);
}
+.search-results .result-name span.alias {
+ color: var(--search-results-alias-color);
+}
+.search-results .result-name span.grey {
+ color: var(--search-results-grey-color);
+}
+
.popover {
- font-size: 1rem;
position: absolute;
+ top: 100%;
right: 0;
z-index: 2;
display: block;
margin-top: 7px;
border-radius: 3px;
border: 1px solid var(--border-color);
- font-size: 1rem;
+ --popover-arrow-offset: 11px;
}
/* This rule is to draw the little arrow connecting the settings menu to the gear icon. */
.popover::before {
content: '';
position: absolute;
- right: 11px;
+ right: var(--popover-arrow-offset);
border: solid var(--border-color);
border-width: 1px 1px 0 0;
- display: inline-block;
padding: 4px;
transform: rotate(-45deg);
top: -5px;
@@ -947,16 +930,12 @@ so that we can apply CSS-filters to change the arrow color in themes */
/* use larger max-width for help popover, but not for help.html */
#help.popover {
max-width: 600px;
-}
-
-#help.popover::before {
- right: 48px;
+ --popover-arrow-offset: 48px;
}
#help dt {
float: left;
clear: left;
- display: block;
margin-right: 0.5rem;
}
#help span.top, #help span.bottom {
@@ -1024,11 +1003,9 @@ so that we can apply CSS-filters to change the arrow color in themes */
0 -1px 0 black;
}
-.module-item .stab,
-.import-item .stab {
+.item-left .stab {
border-radius: 3px;
display: inline-block;
- font-size: 0.875rem;
line-height: 1.2;
margin-bottom: 0;
margin-left: 0.3125em;
@@ -1048,7 +1025,6 @@ so that we can apply CSS-filters to change the arrow color in themes */
.rightside {
padding-left: 12px;
- padding-right: 2px;
float: right;
}
@@ -1090,7 +1066,7 @@ pre.rust .bool-val {
pre.rust .self {
color: var(--code-highlight-self-color);
}
-pre.rust .attribute {
+pre.rust .attr {
color: var(--code-highlight-attribute-color);
}
pre.rust .macro,
@@ -1147,7 +1123,6 @@ pre.rust .doccomment {
.example-wrap .tooltip {
position: absolute;
display: block;
- cursor: pointer;
left: -25px;
top: 5px;
}
@@ -1164,6 +1139,8 @@ pre.rust .doccomment {
width: max-content;
top: -2px;
z-index: 1;
+ background-color: var(--tooltip-background-color);
+ color: var(--tooltip-color);
}
.example-wrap .tooltip::before {
@@ -1172,10 +1149,10 @@ pre.rust .doccomment {
top: 50%;
left: 16px;
margin-top: -5px;
- border-width: 5px;
- border-style: solid;
display: none;
z-index: 1;
+ border: 5px solid transparent;
+ border-right-color: var(--tooltip-background-color);
}
.example-wrap.ignore .tooltip::after {
@@ -1203,7 +1180,6 @@ pre.rust .doccomment {
}
a.test-arrow {
- display: inline-block;
visibility: hidden;
position: absolute;
padding: 5px 10px 5px 10px;
@@ -1212,6 +1188,12 @@ a.test-arrow {
top: 5px;
right: 5px;
z-index: 1;
+ color: var(--test-arrow-color);
+ background-color: var(--test-arrow-background-color);
+}
+a.test-arrow:hover {
+ color: var(--test-arrow-hover-color);
+ background-color: var(--test-arrow-hover-background-color);
}
.example-wrap:hover .test-arrow {
visibility: visible;
@@ -1231,12 +1213,6 @@ a.test-arrow {
font-size: 1.25rem;
}
-h3.variant {
- font-weight: 600;
- font-size: 1.125rem;
- margin-bottom: 10px;
-}
-
.sub-variant h4 {
font-size: 1rem;
font-weight: 400;
@@ -1253,59 +1229,40 @@ h3.variant {
margin-left: 24px;
}
-:target > code, :target > .code-header {
- opacity: 1;
-}
-
:target {
padding-right: 3px;
+ background-color: var(--target-background-color);
+ border-right: 3px solid var(--target-border-color);
}
-.notable-traits-tooltip {
- display: inline-block;
- cursor: pointer;
-}
-
-.notable-traits:hover .notable-traits-tooltiptext,
-.notable-traits .notable-traits-tooltiptext.force-tooltip {
- display: inline-block;
+.notable-traits {
+ color: inherit;
+ margin-right: 15px;
+ position: relative;
}
-.notable-traits .notable-traits-tooltiptext {
- display: none;
- padding: 5px 3px 3px 3px;
- border-radius: 6px;
- margin-left: 5px;
- z-index: 10;
- font-size: 1rem;
- cursor: default;
+/* placeholder thunk so that the mouse can easily travel from "(i)" to popover
+ the resulting "hover tunnel" is a stepped triangle, approximating
+ https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown */
+.notable-traits:hover::after {
position: absolute;
- border: 1px solid;
-}
-
-.notable-traits-tooltip::after {
- /* The margin on the tooltip does not capture hover events,
- this extends the area of hover enough so that mouse hover is not
- lost when moving the mouse to the tooltip */
- content: "\00a0\00a0\00a0";
-}
-
-.notable-traits .docblock {
- margin: 0;
+ top: calc(100% - 10px);
+ left: -15px;
+ right: -15px;
+ height: 20px;
+ content: "\00a0";
}
-.notable-traits .notable {
- margin: 0;
- margin-bottom: 13px;
- font-size: 1.1875rem;
- font-weight: 600;
- display: block;
+.notable .docblock {
+ margin: 0.25em 0.5em;
}
-.notable-traits .docblock code.content {
+.notable .docblock pre, .notable .docblock code {
+ background: transparent;
margin: 0;
padding: 0;
font-size: 1.25rem;
+ white-space: pre-wrap;
}
.search-failed {
@@ -1335,7 +1292,6 @@ h3.variant {
#titles > button {
text-align: center;
font-size: 1.125rem;
- cursor: pointer;
border: 0;
border-top: 2px solid;
flex: 1;
@@ -1348,12 +1304,6 @@ h3.variant {
font-size: 1rem;
}
-.notable-traits {
- cursor: pointer;
- z-index: 2;
- margin-left: 5px;
-}
-
#sidebar-toggle {
position: sticky;
top: 0;
@@ -1362,8 +1312,8 @@ h3.variant {
border-bottom: 1px solid;
display: flex;
height: 40px;
- justify-content: center;
- align-items: center;
+ justify-content: stretch;
+ align-items: stretch;
z-index: 10;
}
#source-sidebar {
@@ -1376,44 +1326,51 @@ h3.variant {
border-bottom: 1px solid var(--border-color);
margin-bottom: 6px;
}
+#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
+#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
+ background-color: var(--source-sidebar-background-hover);
+}
+#source-sidebar div.files > a.selected {
+ background-color: var(--source-sidebar-background-selected);
+}
#sidebar-toggle > button {
font-size: inherit;
font-weight: bold;
background: none;
color: inherit;
- cursor: pointer;
text-align: center;
border: none;
outline: none;
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- /* work around button layout strangeness: https://stackoverflow.com/q/7271561 */
- width: 100%;
+ flex: 1 1;
/* iOS button gradient: https://stackoverflow.com/q/5438567 */
-webkit-appearance: none;
opacity: 1;
}
#settings-menu, #help-button {
margin-left: 4px;
- outline: none;
+ display: flex;
}
#settings-menu > a, #help-button > a, #copy-path {
width: 33px;
- cursor: pointer;
- line-height: 1.5;
}
#settings-menu > a, #help-button > a {
- padding: 5px;
- height: 100%;
- display: block;
+ display: flex;
+ align-items: center;
+ justify-content: center;
background-color: var(--button-background-color);
border: 1px solid var(--border-color);
border-radius: 2px;
+ color: var(--settings-button-color);
+ /* Rare exception to specifying font sizes in rem. Since this is acting
+ as an icon, it's okay to specify their sizes in pixels. */
+ font-size: 20px;
+}
+
+#settings-menu > a:hover, #settings-menu > a:focus,
+#help-button > a:hover, #help-button > a:focus {
+ border-color: var(--settings-button-border-focus);
}
#copy-path {
@@ -1444,14 +1401,6 @@ h3.variant {
animation: rotating 2s linear infinite;
}
-#help-button > a {
- text-align: center;
- /* Rare exception to specifying font sizes in rem. Since this is acting
- as an icon, it's okay to specify their sizes in pixels. */
- font-size: 20px;
- padding-top: 2px;
-}
-
kbd {
display: inline-block;
padding: 3px 5px;
@@ -1461,6 +1410,9 @@ kbd {
border: solid 1px var(--border-color);
border-radius: 3px;
cursor: default;
+ color: var(--kbd--color);
+ background-color: var(--kbd-background);
+ box-shadow: inset 0 -1px 0 var(--kbd-box-shadow-color);
}
ul.all-items > li {
@@ -1522,6 +1474,7 @@ details.rustdoc-toggle {
"Expand description" or "Show methods". */
details.rustdoc-toggle > summary.hideme {
cursor: pointer;
+ font-size: 1rem;
}
details.rustdoc-toggle > summary {
@@ -1539,15 +1492,15 @@ details.rustdoc-toggle > summary.hideme > span {
}
details.rustdoc-toggle > summary::before {
+ background: url("toggle-plus-1092eb4930d581b0.svg") no-repeat top left;
content: "";
cursor: pointer;
width: 16px;
height: 16px;
- background-repeat: no-repeat;
- background-position: top left;
display: inline-block;
vertical-align: middle;
opacity: .5;
+ filter: var(--toggle-filter);
}
details.rustdoc-toggle > summary.hideme > span,
@@ -1584,13 +1537,6 @@ details.rustdoc-toggle > summary:focus-visible::before {
outline-offset: 1px;
}
-details.rustdoc-toggle.top-doc > summary,
-details.rustdoc-toggle.top-doc > summary::before,
-details.rustdoc-toggle.non-exhaustive > summary,
-details.rustdoc-toggle.non-exhaustive > summary::before {
- font-size: 1rem;
-}
-
details.non-exhaustive {
margin-bottom: 8px;
}
@@ -1623,27 +1569,11 @@ details.rustdoc-toggle[open] > summary.hideme > span {
display: none;
}
-details.rustdoc-toggle[open] > summary::before,
-details.rustdoc-toggle[open] > summary.hideme::before {
- background-image: /* AUTOREPLACE: */url("toggle-minus.svg");
+details.rustdoc-toggle[open] > summary::before {
+ background: url("toggle-minus-31bbd6e4c77f5c96.svg") no-repeat top left;
}
-details.rustdoc-toggle > summary::before {
- background-image: /* AUTOREPLACE: */url("toggle-plus.svg");
-}
-
-details.rustdoc-toggle[open] > summary::before,
-details.rustdoc-toggle[open] > summary.hideme::before {
- width: 16px;
- height: 16px;
- background-repeat: no-repeat;
- background-position: top left;
- display: inline-block;
- content: "";
-}
-
-details.rustdoc-toggle[open] > summary::after,
-details.rustdoc-toggle[open] > summary.hideme::after {
+details.rustdoc-toggle[open] > summary::after {
content: "Collapse";
}
@@ -1677,7 +1607,6 @@ in storage.js
}
.rustdoc {
- padding-top: 0px;
/* Sidebar should overlay main content, rather than pushing main content to the right.
Turn off `display: flex` on the body element. */
display: block;
@@ -1702,10 +1631,6 @@ in storage.js
content: "Since ";
}
- #copy-path {
- display: none;
- }
-
/* Hide the logo and item name from the sidebar. Those are displayed
in the mobile-topbar instead. */
.sidebar .sidebar-logo,
@@ -1719,12 +1644,10 @@ in storage.js
/* Hide the sidebar offscreen while not in use. Doing this instead of display: none means
the sidebar stays visible for screen readers, which is useful for navigation. */
left: -1000px;
- margin-left: 0;
- margin: 0;
- padding: 0;
z-index: 11;
/* Reduce height slightly to account for mobile topbar. */
height: calc(100vh - 45px);
+ width: 200px;
}
/* The source view uses a different design for the sidebar toggle, and doesn't have a topbar,
@@ -1765,16 +1688,10 @@ in storage.js
white-space: nowrap;
}
- .mobile-topbar .logo-container {
- max-height: 45px;
- }
-
.mobile-topbar .logo-container > img {
max-width: 35px;
max-height: 35px;
- margin-left: 20px;
- margin-top: 5px;
- margin-bottom: 5px;
+ margin: 5px 0 5px 20px;
}
.mobile-topbar {
@@ -1800,7 +1717,6 @@ in storage.js
.sidebar-elems {
margin-top: 1em;
- background-color: var(--sidebar-background-color);
}
.content {
@@ -1815,21 +1731,6 @@ in storage.js
display: block;
}
- /* Because of ios, we need to actually have a full height sidebar title so the
- * actual sidebar can show up. But then we need to make it transparent so we don't
- * hide content. The filler just allows to create the background for the sidebar
- * title. But because of the absolute position, I had to lower the z-index.
- */
- #sidebar-filler {
- position: fixed;
- left: 45px;
- width: calc(100% - 45px);
- top: 0;
- height: 45px;
- z-index: -1;
- border-bottom: 1px solid;
- }
-
#main-content > details.rustdoc-toggle > summary::before,
#main-content > div > details.rustdoc-toggle > summary::before {
left: -11px;
@@ -1846,7 +1747,6 @@ in storage.js
z-index: 10;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
- cursor: pointer;
border: 1px solid;
border-left: 0;
}
@@ -1862,37 +1762,22 @@ in storage.js
border-bottom: 1px solid;
}
- .notable-traits .notable-traits-tooltiptext {
- left: 0;
- top: 100%;
- }
-
- /* We don't display the help button on mobile devices. */
- #help-button {
+ /* We don't display these buttons on mobile devices. */
+ #copy-path, #help-button {
display: none;
}
/* Display an alternating layout on tablets and phones */
- .item-table {
+ .item-table, .item-row, .item-left, .item-right,
+ .search-results > a, .search-results > a > div {
display: block;
}
- .item-row {
- display: flex;
- flex-flow: column wrap;
- }
- .item-left, .item-right {
- width: 100%;
- }
/* Display an alternating layout on tablets and phones */
.search-results > a {
- border-bottom: 1px solid #aaa9;
padding: 5px 0px;
}
- .search-results .result-name, .search-results div.desc {
- width: 100%;
- }
- .search-results div.desc, .item-right {
+ .search-results > a > div.desc, .item-right {
padding-left: 2em;
}
@@ -1922,6 +1807,22 @@ in storage.js
}
}
+/* Should have min-width: (N + 1)px where N is the mobile breakpoint above. */
+@media (min-width: 701px) {
+ /* Places file-link for a scraped example on top of the example to save space.
+ We only do this on large screens so the file-link doesn't overlap too much
+ with the example's content. */
+ .scraped-example-title {
+ position: absolute;
+ z-index: 10;
+ background: var(--main-background-color);
+ bottom: 8px;
+ right: 5px;
+ padding: 2px 4px;
+ box-shadow: 0 0 4px var(--main-background-color);
+ }
+}
+
@media print {
nav.sidebar, nav.sub, .out-of-band, a.srclink, #copy-path,
details.rustdoc-toggle[open] > summary::before, details.rustdoc-toggle > summary::before,
@@ -1969,24 +1870,28 @@ in storage.js
}
}
-.method-toggle > summary,
+.variant,
.implementors-toggle > summary,
.impl,
#implementors-list > .docblock,
.impl-items > section,
-.methods > section
+.impl-items > .rustdoc-toggle > summary,
+.methods > section,
+.methods > .rustdoc-toggle > summary
{
margin-bottom: 0.75em;
}
-.method-toggle[open]:not(:last-child),
+.variants > .docblock,
+.impl-items > .rustdoc-toggle[open]:not(:last-child),
+.methods > .rustdoc-toggle[open]:not(:last-child),
.implementors-toggle[open]:not(:last-child) {
margin-bottom: 2em;
}
-#trait-implementations-list .method-toggle:not(:last-child),
-#synthetic-implementations-list .method-toggle:not(:last-child),
-#blanket-implementations-list .method-toggle:not(:last-child) {
+#trait-implementations-list .impl-items > .rustdoc-toggle:not(:last-child),
+#synthetic-implementations-list .impl-items > .rustdoc-toggle:not(:last-child),
+#blanket-implementations-list .impl-items > .rustdoc-toggle:not(:last-child) {
margin-bottom: 1em;
}
@@ -1999,12 +1904,16 @@ in storage.js
font-size: 12px;
position: relative;
bottom: 1px;
- background: transparent;
border-width: 1px;
border-style: solid;
border-radius: 50px;
}
+.scraped-example {
+ /* So .scraped-example-title can be positioned absolutely */
+ position: relative;
+}
+
.scraped-example .code-wrapper {
position: relative;
display: flex;
@@ -2014,54 +1923,62 @@ in storage.js
}
.scraped-example:not(.expanded) .code-wrapper {
- max-height: 240px;
+ /* scrape-examples.js has a constant DEFAULT_MAX_LINES (call it N) for the number
+ * of lines shown in the un-expanded example code viewer. This pre needs to have
+ * a max-height equal to line-height * N. The line-height is currently 1.5em,
+ * and we include additional 10px for padding. */
+ max-height: calc(1.5em * 5 + 10px);
}
.scraped-example:not(.expanded) .code-wrapper pre {
overflow-y: hidden;
- max-height: 240px;
padding-bottom: 0;
+ /* See above comment, should be the same max-height. */
+ max-height: calc(1.5em * 5 + 10px);
}
-.scraped-example .code-wrapper .prev {
+.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,
+.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre {
+ /* See above comment, except this height is based on HIDDEN_MAX_LINES. */
+ max-height: calc(1.5em * 10 + 10px);
+}
+
+.scraped-example .code-wrapper .next,
+.scraped-example .code-wrapper .prev,
+.scraped-example .code-wrapper .expand {
+ color: var(--main-color);
position: absolute;
top: 0.25em;
+ z-index: 1;
+ padding: 0;
+ background: none;
+ border: none;
+ /* iOS button gradient: https://stackoverflow.com/q/5438567 */
+ -webkit-appearance: none;
+ opacity: 1;
+}
+.scraped-example .code-wrapper .prev {
right: 2.25em;
- z-index: 100;
- cursor: pointer;
}
-
.scraped-example .code-wrapper .next {
- position: absolute;
- top: 0.25em;
right: 1.25em;
- z-index: 100;
- cursor: pointer;
}
-
.scraped-example .code-wrapper .expand {
- position: absolute;
- top: 0.25em;
right: 0.25em;
- z-index: 100;
- cursor: pointer;
}
-.scraped-example:not(.expanded) .code-wrapper:before {
+.scraped-example:not(.expanded) .code-wrapper:before,
+.scraped-example:not(.expanded) .code-wrapper:after {
content: " ";
width: 100%;
height: 5px;
position: absolute;
- z-index: 100;
+ z-index: 1;
+}
+.scraped-example:not(.expanded) .code-wrapper:before {
top: 0;
}
-
.scraped-example:not(.expanded) .code-wrapper:after {
- content: " ";
- width: 100%;
- height: 5px;
- position: absolute;
- z-index: 100;
bottom: 0;
}
@@ -2070,12 +1987,15 @@ in storage.js
padding: 14px 0;
}
+.scraped-example .code-wrapper .src-line-numbers a,
.scraped-example .code-wrapper .src-line-numbers span {
padding: 0 14px;
}
.scraped-example .code-wrapper .example-wrap {
- flex: 1;
+ display: grid;
+ grid-template-columns: max-content auto;
+ width: 100%;
overflow-x: auto;
overflow-y: hidden;
margin-bottom: 0;
diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css
index 83939f63b..1f6fb961e 100644
--- a/src/librustdoc/html/static/css/settings.css
+++ b/src/librustdoc/html/static/css/settings.css
@@ -8,7 +8,8 @@
flex-wrap: wrap;
}
-.setting-line .radio-line input {
+.setting-line .radio-line input,
+.setting-line .toggle input {
margin-right: 0.3em;
height: 1.2rem;
width: 1.2rem;
@@ -17,9 +18,18 @@
outline: none;
-webkit-appearance: none;
cursor: pointer;
+}
+.setting-line .radio-line input {
border-radius: 50%;
}
-.setting-line .radio-line input + span {
+.setting-line .toggle input:checked {
+ content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">\
+ <path d="M7,25L17,32L33,12" fill="none" stroke="black" stroke-width="5"/>\
+ <path d="M7,23L17,30L33,10" fill="none" stroke="white" stroke-width="5"/></svg>');
+}
+
+.setting-line .radio-line input + span,
+.setting-line .toggle span {
padding-bottom: 1px;
}
@@ -49,37 +59,6 @@
cursor: pointer;
}
-.toggle input {
- opacity: 0;
- position: absolute;
-}
-
-.slider {
- position: relative;
- width: 45px;
- min-width: 45px;
- display: block;
- height: 28px;
- margin-right: 20px;
- cursor: pointer;
- background-color: #ccc;
- transition: .3s;
-}
-
-.slider:before {
- position: absolute;
- content: "";
- height: 19px;
- width: 19px;
- left: 4px;
- bottom: 4px;
- transition: .3s;
-}
-
-input:checked + .slider:before {
- transform: translateX(19px);
-}
-
.setting-line > .sub-settings {
padding-left: 42px;
width: 100%;
@@ -94,7 +73,11 @@ input:checked + .slider:before {
box-shadow: inset 0 0 0 3px var(--main-background-color);
background-color: var(--settings-input-color);
}
-.setting-line .radio-line input:focus {
+.setting-line .toggle input:checked {
+ background-color: var(--settings-input-color);
+}
+.setting-line .radio-line input:focus,
+.setting-line .toggle input:focus {
box-shadow: 0 0 1px 1px var(--settings-input-color);
}
/* In here we combine both `:focus` and `:checked` properties. */
@@ -102,9 +85,7 @@ input:checked + .slider:before {
box-shadow: inset 0 0 0 3px var(--main-background-color),
0 0 2px 2px var(--settings-input-color);
}
-.setting-line .radio-line input:hover {
+.setting-line .radio-line input:hover,
+.setting-line .toggle input:hover {
border-color: var(--settings-input-color) !important;
}
-input:checked + .slider {
- background-color: var(--settings-input-color);
-}
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index fdfdb3e19..0436fe013 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -7,6 +7,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
--main-background-color: #0f1419;
--main-color: #c5c5c5;
--settings-input-color: #ffb454;
+ --settings-button-color: #fff;
+ --settings-button-border-focus: #e0e0e0;
--sidebar-background-color: #14191f;
--sidebar-background-color-hover: rgba(70, 70, 70, 0.33);
--code-block-background-color: #191f26;
@@ -19,6 +21,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
--right-side-color: grey;
--code-attribute-color: #999;
--toggles-color: #999;
+ --toggle-filter: invert(100%);
--search-input-focused-border-color: #5c6773; /* Same as `--border-color`. */
--copy-path-button-color: #fff;
--copy-path-img-filter: invert(70%);
@@ -38,9 +41,12 @@ Original by Dempfi (https://github.com/dempfi/ayu)
--sidebar-link-color: #53b1db;
--sidebar-current-link-background-color: transparent;
--search-result-link-focus-background-color: #3c3c3c;
+ --search-result-border-color: #aaa3;
+ --search-color: #fff;
+ --search-results-alias-color: #c5c5c5;
+ --search-results-grey-color: #999;
--stab-background-color: #314559;
--stab-code-color: #e6e1cf;
- --search-color: #fff;
--code-highlight-kw-color: #ff7733;
--code-highlight-kw-2-color: #ff7733;
--code-highlight-lifetime-color: #ff7733;
@@ -58,16 +64,30 @@ Original by Dempfi (https://github.com/dempfi/ayu)
--example-line-numbers-border-color: none;
--src-line-numbers-span-color: #5c6773;
--src-line-number-highlighted-background-color: rgba(255, 236, 164, 0.06);
-}
-
-.slider {
- background-color: #ccc;
-}
-.slider:before {
- background-color: white;
-}
-input:focus + .slider {
- box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
+ --test-arrow-color: #788797;
+ --test-arrow-background-color: rgba(57, 175, 215, 0.09);
+ --test-arrow-hover-color: #c5c5c5;
+ --test-arrow-hover-background-color: rgba(57, 175, 215, 0.368);
+ --target-background-color: rgba(255, 236, 164, 0.06);
+ --target-border-color: rgba(255, 180, 76, 0.85);
+ --tooltip-background-color: #314559;
+ --tooltip-color: #c5c5c5;
+ --kbd-color: #c5c5c5;
+ --kbd-background: #314559;
+ --kbd-box-shadow-color: #5c6773;
+ --rust-logo-filter: drop-shadow(1px 0 0px #fff)
+ drop-shadow(0 1px 0 #fff)
+ drop-shadow(-1px 0 0 #fff)
+ drop-shadow(0 -1px 0 #fff);
+ /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
+ --crate-search-div-filter: invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg)
+ brightness(94%) contrast(94%);
+ --crate-search-div-hover-filter: invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg)
+ brightness(113%) contrast(76%);
+ --crate-search-hover-border: #e0e0e0;
+ --source-sidebar-background-selected: #14191f;
+ --source-sidebar-background-hover: #14191f;
+ --table-alt-row-background-color: #191f26;
}
h1, h2, h3, h4 {
@@ -99,13 +119,6 @@ pre, .rustdoc.source .example-wrap {
color: #e6e1cf;
}
-.rust-logo {
- filter: drop-shadow(1px 0 0px #fff)
- drop-shadow(0 1px 0 #fff)
- drop-shadow(-1px 0 0 #fff)
- drop-shadow(0 -1px 0 #fff);
-}
-
.sidebar .current,
.sidebar a:hover {
color: #ffb44c;
@@ -147,21 +160,6 @@ body.source .example-wrap pre.rust a {
background: #333;
}
-details.rustdoc-toggle > summary::before {
- filter: invert(100%);
-}
-
-#crate-search-div::after {
- /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
- filter: invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);
-}
-#crate-search:hover, #crate-search:focus {
- border-color: #e0e0e0 !important;
-}
-#crate-search-div:hover::after, #crate-search-div:focus-within::after {
- filter: invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);
-}
-
.module-item .stab,
.import-item .stab {
color: #000;
@@ -171,40 +169,6 @@ details.rustdoc-toggle > summary::before {
color: #788797;
}
-a.test-arrow {
- font-size: 100%;
- color: #788797;
- border-radius: 4px;
- background-color: rgba(57, 175, 215, 0.09);
-}
-
-a.test-arrow:hover {
- background-color: rgba(57, 175, 215, 0.368);
- color: #c5c5c5;
-}
-
-:target {
- background: rgba(255, 236, 164, 0.06);
- border-right: 3px solid rgba(255, 180, 76, 0.85);
-}
-
-.search-failed a {
- color: #39AFD7;
-}
-
-.tooltip::after {
- background-color: #314559;
- color: #c5c5c5;
-}
-
-.tooltip::before {
- border-color: transparent #314559 transparent transparent;
-}
-
-.notable-traits-tooltiptext {
- background-color: #314559;
-}
-
#titles > button.selected {
background-color: #141920 !important;
border-bottom: 1px solid #ffb44c !important;
@@ -236,42 +200,16 @@ pre.rust .kw {}
pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, pre.rust .attribute {}
pre.rust .kw-2, pre.rust .prelude-ty {}
-kbd {
- color: #c5c5c5;
- background-color: #314559;
- box-shadow: inset 0 -1px 0 #5c6773;
-}
-
-#settings-menu > a, #help-button > a {
- color: #fff;
-}
-
#settings-menu > a img {
filter: invert(100);
}
-#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button > a:hover, #help-button > a:focus {
- border-color: #e0e0e0;
-}
-
-.search-results .result-name span.alias {
- color: #c5c5c5;
-}
-.search-results .result-name span.grey {
- color: #999;
-}
-
#source-sidebar > .title {
color: #fff;
}
#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
-#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
- background-color: #14191f;
- color: #ffb44c;
-}
+#source-sidebar div.files > a:focus, details.dir-entry summary:focus,
#source-sidebar div.files > a.selected {
- background-color: #14191f;
color: #ffb44c;
}
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 361d3d4a2..d945e956c 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -2,6 +2,8 @@
--main-background-color: #353535;
--main-color: #ddd;
--settings-input-color: #2196f3;
+ --settings-button-color: #000;
+ --settings-button-border-focus: #ffb900;
--sidebar-background-color: #505050;
--sidebar-background-color-hover: #676767;
--code-block-background-color: #2A2A2A;
@@ -14,6 +16,7 @@
--right-side-color: grey;
--code-attribute-color: #999;
--toggles-color: #999;
+ --toggle-filter: invert(100%);
--search-input-focused-border-color: #008dfd;
--copy-path-button-color: #999;
--copy-path-img-filter: invert(50%);
@@ -33,9 +36,12 @@
--sidebar-link-color: #fdbf35;
--sidebar-current-link-background-color: #444;
--search-result-link-focus-background-color: #616161;
+ --search-result-border-color: #aaa3;
+ --search-color: #111;
+ --search-results-alias-color: #fff;
+ --search-results-grey-color: #ccc;
--stab-background-color: #314559;
--stab-code-color: #e6e1cf;
- --search-color: #111;
--code-highlight-kw-color: #ab8ac1;
--code-highlight-kw-2-color: #769acb;
--code-highlight-lifetime-color: #d97f26;
@@ -53,23 +59,30 @@
--example-line-numbers-border-color: #4a4949;
--src-line-numbers-span-color: #3b91e2;
--src-line-number-highlighted-background-color: #0a042f;
-}
-
-.slider {
- background-color: #ccc;
-}
-.slider:before {
- background-color: white;
-}
-input:focus + .slider {
- box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
-}
-
-.rust-logo {
- filter: drop-shadow(1px 0 0px #fff)
+ --test-arrow-color: #dedede;
+ --test-arrow-background-color: rgba(78, 139, 202, 0.2);
+ --test-arrow-hover-color: #dedede;
+ --test-arrow-hover-background-color: #4e8bca;
+ --target-background-color: #494a3d;
+ --target-border-color: #bb7410;
+ --tooltip-background-color: #000;
+ --tooltip-color: #fff;
+ --kbd-color: #000;
+ --kbd-background: #fafbfc;
+ --kbd-box-shadow-color: #c6cbd1;
+ --rust-logo-filter: drop-shadow(1px 0 0px #fff)
drop-shadow(0 1px 0 #fff)
drop-shadow(-1px 0 0 #fff)
- drop-shadow(0 -1px 0 #fff)
+ drop-shadow(0 -1px 0 #fff);
+ /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
+ --crate-search-div-filter: invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg)
+ brightness(90%) contrast(90%);
+ --crate-search-div-hover-filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg)
+ brightness(100%) contrast(91%);
+ --crate-search-hover-border: #2196f3;
+ --source-sidebar-background-selected: #333;
+ --source-sidebar-background-hover: #444;
+ --table-alt-row-background-color: #2A2A2A;
}
.content .item-info::before { color: #ccc; }
@@ -78,53 +91,6 @@ body.source .example-wrap pre.rust a {
background: #333;
}
-details.rustdoc-toggle > summary::before {
- filter: invert(100%);
-}
-
-#crate-search-div::after {
- /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
- filter: invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);
-}
-#crate-search:hover, #crate-search:focus {
- border-color: #2196f3 !important;
-}
-#crate-search-div:hover::after, #crate-search-div:focus-within::after {
- filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);
-}
-
-a.test-arrow {
- color: #dedede;
- background-color: rgba(78, 139, 202, 0.2);
-}
-
-a.test-arrow:hover{
- background-color: #4e8bca;
-}
-
-:target {
- background-color: #494a3d;
- border-right: 3px solid #bb7410;
-}
-
-.search-failed a {
- color: #0089ff;
-}
-
-.tooltip::after {
- background-color: #000;
- color: #fff;
- border-color: #000;
-}
-
-.tooltip::before {
- border-color: transparent black transparent transparent;
-}
-
-.notable-traits-tooltiptext {
- background-color: #111;
-}
-
#titles > button:not(.selected) {
background-color: #252525;
border-top-color: #252525;
@@ -139,36 +105,6 @@ a.test-arrow:hover{
color: #888;
}
-kbd {
- color: #000;
- background-color: #fafbfc;
- box-shadow: inset 0 -1px 0 #c6cbd1;
-}
-
-#settings-menu > a, #help-button > a {
- color: #000;
-}
-
-#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button > a:hover, #help-button > a:focus {
- border-color: #ffb900;
-}
-
-.search-results .result-name span.alias {
- color: #fff;
-}
-.search-results .result-name span.grey {
- color: #ccc;
-}
-
-#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
-#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
- background-color: #444;
-}
-#source-sidebar div.files > a.selected {
- background-color: #333;
-}
-
.scraped-example-list .scrape-help {
border-color: #aaa;
color: #eee;
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index 5eb4bbcf8..58955a793 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -2,6 +2,8 @@
--main-background-color: white;
--main-color: black;
--settings-input-color: #2196f3;
+ --settings-button-color: #000;
+ --settings-button-border-focus: #717171;
--sidebar-background-color: #F5F5F5;
--sidebar-background-color-hover: #E0E0E0;
--code-block-background-color: #F5F5F5;
@@ -14,6 +16,7 @@
--right-side-color: grey;
--code-attribute-color: #999;
--toggles-color: #999;
+ --toggle-filter: none;
--search-input-focused-border-color: #66afe9;
--copy-path-button-color: #999;
--copy-path-img-filter: invert(50%);
@@ -33,9 +36,12 @@
--sidebar-link-color: #356da4;
--sidebar-current-link-background-color: #fff;
--search-result-link-focus-background-color: #ccc;
+ --search-result-border-color: #aaa3;
+ --search-color: #000;
+ --search-results-alias-color: #000;
+ --search-results-grey-color: #999;
--stab-background-color: #fff5d6;
--stab-code-color: #000;
- --search-color: #000;
--code-highlight-kw-color: #8959a8;
--code-highlight-kw-2-color: #4271ae;
--code-highlight-lifetime-color: #b76514;
@@ -53,22 +59,27 @@
--example-line-numbers-border-color: #c7c7c7;
--src-line-numbers-span-color: #c67e2d;
--src-line-number-highlighted-background-color: #fdffd3;
-}
-
-.slider {
- background-color: #ccc;
-}
-.slider:before {
- background-color: white;
-}
-input:focus + .slider {
- box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
-}
-
-.rust-logo {
- /* This rule exists to force other themes to explicitly style the logo.
- * Rustdoc has a custom linter for this purpose.
- */
+ --test-arrow-color: #f5f5f5;
+ --test-arrow-background-color: rgba(78, 139, 202, 0.2);
+ --test-arrow-hover-color: #f5f5f5;
+ --test-arrow-hover-background-color: #4e8bca;
+ --target-background-color: #fdffd3;
+ --target-border-color: #ad7c37;
+ --tooltip-background-color: #000;
+ --tooltip-color: #fff;
+ --kbd-color: #000;
+ --kbd-background: #fafbfc;
+ --kbd-box-shadow-color: #c6cbd1;
+ --rust-logo-filter: initial;
+ /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
+ --crate-search-div-filter: invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg)
+ brightness(114%) contrast(76%);
+ --crate-search-div-hover-filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg)
+ brightness(96%) contrast(93%);
+ --crate-search-hover-border: #717171;
+ --source-sidebar-background-selected: #fff;
+ --source-sidebar-background-hover: #e0e0e0;
+ --table-alt-row-background-color: #F5F5F5;
}
.content .item-info::before { color: #ccc; }
@@ -77,48 +88,6 @@ body.source .example-wrap pre.rust a {
background: #eee;
}
-#crate-search-div::after {
- /* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
- filter: invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);
-}
-#crate-search:hover, #crate-search:focus {
- border-color: #717171 !important;
-}
-#crate-search-div:hover::after, #crate-search-div:focus-within::after {
- filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);
-}
-
-a.test-arrow {
- color: #f5f5f5;
- background-color: rgba(78, 139, 202, 0.2);
-}
-
-a.test-arrow:hover{
- background-color: #4e8bca;
-}
-
-:target {
- background: #FDFFD3;
- border-right: 3px solid #AD7C37;
-}
-
-.search-failed a {
- color: #3873AD;
-}
-
-.tooltip::after {
- background-color: #000;
- color: #fff;
-}
-
-.tooltip::before {
- border-color: transparent black transparent transparent;
-}
-
-.notable-traits-tooltiptext {
- background-color: #eee;
-}
-
#titles > button:not(.selected) {
background-color: #e6e6e6;
border-top-color: #e6e6e6;
@@ -133,35 +102,6 @@ a.test-arrow:hover{
color: #888;
}
-kbd {
- color: #000;
- background-color: #fafbfc;
- box-shadow: inset 0 -1px 0 #c6cbd1;
-}
-
-#settings-menu > a, #help-button > a {
- color: #000;
-}
-
-#settings-menu > a:hover, #settings-menu > a:focus,
-#help-button > a:hover, #help-button > a:focus {
- border-color: #717171;
-}
-
-.search-results .result-name span.alias {
- color: #000;
-}
-.search-results .result-name span.grey {
- color: #999;
-}
-
-#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
-#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
- background-color: #E0E0E0;
-}
-#source-sidebar div.files > a.selected {
- background-color: #fff;
-}
.scraped-example-list .scrape-help {
border-color: #555;
color: #333;
diff --git a/src/librustdoc/html/static/fonts/README.txt b/src/librustdoc/html/static/fonts/README.txt
new file mode 100644
index 000000000..0db15996d
--- /dev/null
+++ b/src/librustdoc/html/static/fonts/README.txt
@@ -0,0 +1,12 @@
+The Nanum Barun Gothic fonts are shipped with rustdoc because the default fonts
+on many Windows installs render Korean very badly. See:
+ - https://github.com/rust-lang/rust/pull/84048,
+ - https://github.com/rust-lang/rust/issues/84035
+ - https://github.com/rust-lang/rust/pull/90232
+
+The font files were generated with these commands:
+
+```sh
+pyftsubset NanumBarunGothic.ttf \
+--unicodes=U+AC00-D7AF:U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF \
+--output-file=NanumBarunGothic.ttf.woff2 --flavor=woff2
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 33480fa41..152116089 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -47,10 +47,8 @@ function blurHandler(event, parentElem, hideCallback) {
}
}
-(function() {
- window.rootPath = getVar("root-path");
- window.currentCrate = getVar("current-crate");
-}());
+window.rootPath = getVar("root-path");
+window.currentCrate = getVar("current-crate");
function setMobileTopbar() {
// FIXME: It would be nicer to generate this text content directly in HTML,
@@ -183,9 +181,9 @@ function browserSupportsHistoryApi() {
}
// eslint-disable-next-line no-unused-vars
-function loadCss(cssFileName) {
+function loadCss(cssUrl) {
const link = document.createElement("link");
- link.href = resourcePath(cssFileName, ".css");
+ link.href = cssUrl;
link.type = "text/css";
link.rel = "stylesheet";
document.getElementsByTagName("head")[0].appendChild(link);
@@ -204,12 +202,13 @@ function loadCss(cssFileName) {
if (event.ctrlKey || event.altKey || event.metaKey) {
return;
}
+ window.hideAllModals(false);
addClass(getSettingsButton(), "rotate");
event.preventDefault();
// Sending request for the CSS and the JS files at the same time so it will
// hopefully be loaded when the JS will generate the settings content.
- loadCss("settings");
- loadScript(resourcePath("settings", ".js"));
+ loadCss(getVar("static-root-path") + getVar("settings-css"));
+ loadScript(getVar("static-root-path") + getVar("settings-js"));
};
window.searchState = {
@@ -286,7 +285,7 @@ function loadCss(cssFileName) {
function loadSearch() {
if (!searchLoaded) {
searchLoaded = true;
- loadScript(resourcePath("search", ".js"));
+ loadScript(getVar("static-root-path") + getVar("search-js"));
loadScript(resourcePath("search-index", ".js"));
}
}
@@ -303,13 +302,15 @@ function loadCss(cssFileName) {
const params = searchState.getQueryStringParams();
if (params.search !== undefined) {
- const search = searchState.outputElement();
- search.innerHTML = "<h3 class=\"search-loading\">" +
- searchState.loadingText + "</h3>";
- searchState.showResults(search);
+ searchState.setLoadingSearch();
loadSearch();
}
},
+ setLoadingSearch: () => {
+ const search = searchState.outputElement();
+ search.innerHTML = "<h3 class=\"search-loading\">" + searchState.loadingText + "</h3>";
+ searchState.showResults(search);
+ },
};
function getPageId() {
@@ -379,7 +380,7 @@ function loadCss(cssFileName) {
}
ev.preventDefault();
searchState.defocus();
- window.hidePopoverMenus();
+ window.hideAllModals(true); // true = reset focus for notable traits
}
function handleShortcut(ev) {
@@ -621,7 +622,7 @@ function loadCss(cssFileName) {
const innerToggle = document.getElementById(toggleAllDocsId);
removeClass(innerToggle, "will-expand");
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
- if (!hasClass(e, "type-contents-toggle")) {
+ if (!hasClass(e, "type-contents-toggle") && !hasClass(e, "more-examples-toggle")) {
e.open = true;
}
});
@@ -725,12 +726,9 @@ function loadCss(cssFileName) {
});
};
- (function() {
- // To avoid checking on "rustdoc-line-numbers" value on every loop...
- if (getSettingValue("line-numbers") === "true") {
- window.rustdoc_add_line_numbers_to_examples();
- }
- }());
+ if (getSettingValue("line-numbers") === "true") {
+ window.rustdoc_add_line_numbers_to_examples();
+ }
let oldSidebarScrollPosition = null;
@@ -772,6 +770,7 @@ function loadCss(cssFileName) {
};
function showSidebar() {
+ window.hideAllModals(false);
window.rustdocMobileScrollLock();
const sidebar = document.getElementsByClassName("sidebar")[0];
addClass(sidebar, "shown");
@@ -790,6 +789,19 @@ function loadCss(cssFileName) {
// we need to switch away from mobile mode and make the main content area scrollable.
hideSidebar();
}
+ if (window.CURRENT_NOTABLE_ELEMENT) {
+ // As a workaround to the behavior of `contains: layout` used in doc togglers, the
+ // notable traits popup is positioned using javascript.
+ //
+ // This means when the window is resized, we need to redo the layout.
+ const base = window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE;
+ const force_visible = base.NOTABLE_FORCE_VISIBLE;
+ hideNotable(false);
+ if (force_visible) {
+ showNotable(base);
+ base.NOTABLE_FORCE_VISIBLE = true;
+ }
+ }
});
function handleClick(id, f) {
@@ -822,10 +834,123 @@ function loadCss(cssFileName) {
});
});
+ function showNotable(e) {
+ if (!window.NOTABLE_TRAITS) {
+ const data = document.getElementById("notable-traits-data");
+ if (data) {
+ window.NOTABLE_TRAITS = JSON.parse(data.innerText);
+ } else {
+ throw new Error("showNotable() called on page without any notable traits!");
+ }
+ }
+ if (window.CURRENT_NOTABLE_ELEMENT && window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE === e) {
+ // Make this function idempotent.
+ return;
+ }
+ window.hideAllModals(false);
+ const ty = e.getAttribute("data-ty");
+ const wrapper = document.createElement("div");
+ wrapper.innerHTML = "<div class=\"docblock\">" + window.NOTABLE_TRAITS[ty] + "</div>";
+ wrapper.className = "notable popover";
+ const focusCatcher = document.createElement("div");
+ focusCatcher.setAttribute("tabindex", "0");
+ focusCatcher.onfocus = hideNotable;
+ wrapper.appendChild(focusCatcher);
+ const pos = e.getBoundingClientRect();
+ // 5px overlap so that the mouse can easily travel from place to place
+ wrapper.style.top = (pos.top + window.scrollY + pos.height) + "px";
+ wrapper.style.left = 0;
+ wrapper.style.right = "auto";
+ wrapper.style.visibility = "hidden";
+ const body = document.getElementsByTagName("body")[0];
+ body.appendChild(wrapper);
+ const wrapperPos = wrapper.getBoundingClientRect();
+ // offset so that the arrow points at the center of the "(i)"
+ const finalPos = pos.left + window.scrollX - wrapperPos.width + 24;
+ if (finalPos > 0) {
+ wrapper.style.left = finalPos + "px";
+ } else {
+ wrapper.style.setProperty(
+ "--popover-arrow-offset",
+ (wrapperPos.right - pos.right + 4) + "px"
+ );
+ }
+ wrapper.style.visibility = "";
+ window.CURRENT_NOTABLE_ELEMENT = wrapper;
+ window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE = e;
+ wrapper.onpointerleave = function(ev) {
+ // If this is a synthetic touch event, ignore it. A click event will be along shortly.
+ if (ev.pointerType !== "mouse") {
+ return;
+ }
+ if (!e.NOTABLE_FORCE_VISIBLE && !elemIsInParent(event.relatedTarget, e)) {
+ hideNotable(true);
+ }
+ };
+ }
+
+ function notableBlurHandler(event) {
+ if (window.CURRENT_NOTABLE_ELEMENT &&
+ !elemIsInParent(document.activeElement, window.CURRENT_NOTABLE_ELEMENT) &&
+ !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT) &&
+ !elemIsInParent(document.activeElement, window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE) &&
+ !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE)
+ ) {
+ // Work around a difference in the focus behaviour between Firefox, Chrome, and Safari.
+ // When I click the button on an already-opened notable trait popover, Safari
+ // hides the popover and then immediately shows it again, while everyone else hides it
+ // and it stays hidden.
+ //
+ // To work around this, make sure the click finishes being dispatched before
+ // hiding the popover. Since `hideNotable()` is idempotent, this makes Safari behave
+ // consistently with the other two.
+ setTimeout(() => hideNotable(false), 0);
+ }
+ }
+
+ function hideNotable(focus) {
+ if (window.CURRENT_NOTABLE_ELEMENT) {
+ if (window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE) {
+ if (focus) {
+ window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.focus();
+ }
+ window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false;
+ }
+ const body = document.getElementsByTagName("body")[0];
+ body.removeChild(window.CURRENT_NOTABLE_ELEMENT);
+ window.CURRENT_NOTABLE_ELEMENT = null;
+ }
+ }
+
onEachLazy(document.getElementsByClassName("notable-traits"), e => {
e.onclick = function() {
- this.getElementsByClassName("notable-traits-tooltiptext")[0]
- .classList.toggle("force-tooltip");
+ this.NOTABLE_FORCE_VISIBLE = this.NOTABLE_FORCE_VISIBLE ? false : true;
+ if (window.CURRENT_NOTABLE_ELEMENT && !this.NOTABLE_FORCE_VISIBLE) {
+ hideNotable(true);
+ } else {
+ showNotable(this);
+ window.CURRENT_NOTABLE_ELEMENT.setAttribute("tabindex", "0");
+ window.CURRENT_NOTABLE_ELEMENT.focus();
+ window.CURRENT_NOTABLE_ELEMENT.onblur = notableBlurHandler;
+ }
+ return false;
+ };
+ e.onpointerenter = function(ev) {
+ // If this is a synthetic touch event, ignore it. A click event will be along shortly.
+ if (ev.pointerType !== "mouse") {
+ return;
+ }
+ showNotable(this);
+ };
+ e.onpointerleave = function(ev) {
+ // If this is a synthetic touch event, ignore it. A click event will be along shortly.
+ if (ev.pointerType !== "mouse") {
+ return;
+ }
+ if (!this.NOTABLE_FORCE_VISIBLE &&
+ !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT)) {
+ hideNotable(true);
+ }
};
});
@@ -929,6 +1054,17 @@ function loadCss(cssFileName) {
}
/**
+ * Hide popover menus, notable trait tooltips, and the sidebar (if applicable).
+ *
+ * Pass "true" to reset focus for notable traits.
+ */
+ window.hideAllModals = function(switchFocus) {
+ hideSidebar();
+ window.hidePopoverMenus();
+ hideNotable(switchFocus);
+ };
+
+ /**
* Hide all the popover menus.
*/
window.hidePopoverMenus = function() {
@@ -959,7 +1095,7 @@ function loadCss(cssFileName) {
function showHelp() {
const menu = getHelpMenu(true);
if (menu.style.display === "none") {
- window.hidePopoverMenus();
+ window.hideAllModals();
menu.style.display = "";
}
}
diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js
index d0fd115fd..7a3a9c5f3 100644
--- a/src/librustdoc/html/static/js/scrape-examples.js
+++ b/src/librustdoc/html/static/js/scrape-examples.js
@@ -3,25 +3,33 @@
"use strict";
(function() {
- // Number of lines shown when code viewer is not expanded
- const MAX_LINES = 10;
+ // Number of lines shown when code viewer is not expanded.
+ // DEFAULT is the first example shown by default, while HIDDEN is
+ // the examples hidden beneath the "More examples" toggle.
+ //
+ // NOTE: these values MUST be synchronized with certain rules in rustdoc.css!
+ const DEFAULT_MAX_LINES = 5;
+ const HIDDEN_MAX_LINES = 10;
// Scroll code block to the given code location
- function scrollToLoc(elt, loc) {
+ function scrollToLoc(elt, loc, isHidden) {
const lines = elt.querySelector(".src-line-numbers");
let scrollOffset;
// If the block is greater than the size of the viewer,
// then scroll to the top of the block. Otherwise scroll
// to the middle of the block.
- if (loc[1] - loc[0] > MAX_LINES) {
+ const maxLines = isHidden ? HIDDEN_MAX_LINES : DEFAULT_MAX_LINES;
+ if (loc[1] - loc[0] > maxLines) {
const line = Math.max(0, loc[0] - 1);
scrollOffset = lines.children[line].offsetTop;
} else {
const wrapper = elt.querySelector(".code-wrapper");
const halfHeight = wrapper.offsetHeight / 2;
- const offsetMid = (lines.children[loc[0]].offsetTop
- + lines.children[loc[1]].offsetTop) / 2;
+ const offsetTop = lines.children[loc[0]].offsetTop;
+ const lastLine = lines.children[loc[1]];
+ const offsetBot = lastLine.offsetTop + lastLine.offsetHeight;
+ const offsetMid = (offsetTop + offsetBot) / 2;
scrollOffset = offsetMid - halfHeight;
}
@@ -29,7 +37,7 @@
elt.querySelector(".rust").scrollTo(0, scrollOffset);
}
- function updateScrapedExample(example) {
+ function updateScrapedExample(example, isHidden) {
const locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
let locIndex = 0;
const highlights = Array.prototype.slice.call(example.querySelectorAll(".highlight"));
@@ -40,7 +48,7 @@
const onChangeLoc = changeIndex => {
removeClass(highlights[locIndex], "focus");
changeIndex();
- scrollToLoc(example, locs[locIndex][0]);
+ scrollToLoc(example, locs[locIndex][0], isHidden);
addClass(highlights[locIndex], "focus");
const url = locs[locIndex][1];
@@ -57,7 +65,7 @@
});
});
- example.querySelector("next")
+ example.querySelector(".next")
.addEventListener("click", () => {
onChangeLoc(() => {
locIndex = (locIndex + 1) % locs.length;
@@ -70,7 +78,7 @@
expandButton.addEventListener("click", () => {
if (hasClass(example, "expanded")) {
removeClass(example, "expanded");
- scrollToLoc(example, locs[0][0]);
+ scrollToLoc(example, locs[0][0], isHidden);
} else {
addClass(example, "expanded");
}
@@ -78,11 +86,11 @@
}
// Start with the first example in view
- scrollToLoc(example, locs[0][0]);
+ scrollToLoc(example, locs[0][0], isHidden);
}
const firstExamples = document.querySelectorAll(".scraped-example-list > .scraped-example");
- onEachLazy(firstExamples, updateScrapedExample);
+ onEachLazy(firstExamples, el => updateScrapedExample(el, false));
onEachLazy(document.querySelectorAll(".more-examples-toggle"), toggle => {
// Allow users to click the left border of the <details> section to close it,
// since the section can be large and finding the [+] button is annoying.
@@ -99,7 +107,7 @@
// depends on offsetHeight, a property that requires an element to be visible to
// compute correctly.
setTimeout(() => {
- onEachLazy(moreExamples, updateScrapedExample);
+ onEachLazy(moreExamples, el => updateScrapedExample(el, true));
});
}, {once: true});
});
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index d04ec357c..23ae4e970 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -1491,6 +1491,7 @@ function initSearch(rawSearchIndex) {
const target = searchState.focusedByTab[searchState.currentTab] ||
document.querySelectorAll(".search-results.active a").item(0) ||
document.querySelectorAll("#titles > button").item(searchState.currentTab);
+ searchState.focusedByTab[searchState.currentTab] = null;
if (target) {
target.focus();
}
@@ -1593,7 +1594,6 @@ function initSearch(rawSearchIndex) {
link.className = "result-" + type;
link.href = item.href;
- const wrapper = document.createElement("div");
const resultName = document.createElement("div");
resultName.className = "result-name";
@@ -1614,16 +1614,13 @@ function initSearch(rawSearchIndex) {
resultName.insertAdjacentHTML(
"beforeend",
item.displayPath + "<span class=\"" + type + "\">" + name + extra + "</span>");
- wrapper.appendChild(resultName);
+ link.appendChild(resultName);
const description = document.createElement("div");
description.className = "desc";
- const spanDesc = document.createElement("span");
- spanDesc.insertAdjacentHTML("beforeend", item.desc);
+ description.insertAdjacentHTML("beforeend", item.desc);
- description.appendChild(spanDesc);
- wrapper.appendChild(description);
- link.appendChild(wrapper);
+ link.appendChild(description);
output.appendChild(link);
});
} else if (query.error === null) {
@@ -1769,13 +1766,13 @@ function initSearch(rawSearchIndex) {
* @param {boolean} [forced]
*/
function search(e, forced) {
- const params = searchState.getQueryStringParams();
- const query = parseQuery(searchState.input.value.trim());
-
if (e) {
e.preventDefault();
}
+ const query = parseQuery(searchState.input.value.trim());
+ let filterCrates = getFilterCrates();
+
if (!forced && query.userQuery === currentResults) {
if (query.userQuery.length > 0) {
putBackSearch();
@@ -1783,7 +1780,9 @@ function initSearch(rawSearchIndex) {
return;
}
- let filterCrates = getFilterCrates();
+ searchState.setLoadingSearch();
+
+ const params = searchState.getQueryStringParams();
// In case we have no information about the saved crate and there is a URL query parameter,
// we override it with the URL query parameter.
diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js
index 5e1c7e6f0..589bfc793 100644
--- a/src/librustdoc/html/static/js/settings.js
+++ b/src/librustdoc/html/static/js/settings.js
@@ -9,13 +9,16 @@
const isSettingsPage = window.location.pathname.endsWith("/settings.html");
function changeSetting(settingName, value) {
+ if (settingName === "theme") {
+ const useSystem = value === "system preference" ? "true" : "false";
+ updateLocalStorage("use-system-theme", useSystem);
+ }
updateLocalStorage(settingName, value);
switch (settingName) {
case "theme":
case "preferred-dark-theme":
case "preferred-light-theme":
- case "use-system-theme":
updateSystemTheme();
updateLightAndDark();
break;
@@ -45,7 +48,6 @@
}
function showLightAndDark() {
- addClass(document.getElementById("theme").parentElement, "hidden");
removeClass(document.getElementById("preferred-light-theme").parentElement, "hidden");
removeClass(document.getElementById("preferred-dark-theme").parentElement, "hidden");
}
@@ -53,11 +55,11 @@
function hideLightAndDark() {
addClass(document.getElementById("preferred-light-theme").parentElement, "hidden");
addClass(document.getElementById("preferred-dark-theme").parentElement, "hidden");
- removeClass(document.getElementById("theme").parentElement, "hidden");
}
function updateLightAndDark() {
- if (getSettingValue("use-system-theme") !== "false") {
+ const useSystem = getSettingValue("use-system-theme");
+ if (useSystem === "true" || (useSystem === null && getSettingValue("theme") === null)) {
showLightAndDark();
} else {
hideLightAndDark();
@@ -66,8 +68,7 @@
function setEvents(settingsElement) {
updateLightAndDark();
- onEachLazy(settingsElement.getElementsByClassName("slider"), elem => {
- const toggle = elem.previousElementSibling;
+ onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"), toggle => {
const settingId = toggle.id;
const settingValue = getSettingValue(settingId);
if (settingValue !== null) {
@@ -92,7 +93,18 @@
});
onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"), elem => {
const settingId = elem.name;
- const settingValue = getSettingValue(settingId);
+ let settingValue = getSettingValue(settingId);
+ if (settingId === "theme") {
+ const useSystem = getSettingValue("use-system-theme");
+ if (useSystem === "true" || settingValue === null) {
+ if (useSystem !== "false") {
+ settingValue = "system preference";
+ } else {
+ // This is the default theme.
+ settingValue = "light";
+ }
+ }
+ }
if (settingValue !== null && settingValue !== "null") {
elem.checked = settingValue === elem.value;
}
@@ -121,27 +133,30 @@
if (setting["options"] !== undefined) {
// This is a select setting.
- output += `<div class="radio-line" id="${js_data_name}">\
- <span class="setting-name">${setting_name}</span>\
- <div class="choices">`;
+ output += `\
+<div class="radio-line" id="${js_data_name}">
+ <span class="setting-name">${setting_name}</span>
+<div class="choices">`;
onEach(setting["options"], option => {
const checked = option === setting["default"] ? " checked" : "";
+ const full = `${js_data_name}-${option.replace(/ /g,"-")}`;
- output += `<label for="${js_data_name}-${option}" class="choice">\
- <input type="radio" name="${js_data_name}" \
- id="${js_data_name}-${option}" value="${option}"${checked}>\
- <span>${option}</span>\
- </label>`;
+ output += `\
+<label for="${full}" class="choice">
+ <input type="radio" name="${js_data_name}"
+ id="${full}" value="${option}"${checked}>
+ <span>${option}</span>
+</label>`;
});
output += "</div></div>";
} else {
// This is a toggle.
const checked = setting["default"] === true ? " checked" : "";
- output += `<label class="toggle">\
- <input type="checkbox" id="${js_data_name}"${checked}>\
- <span class="slider"></span>\
- <span class="label">${setting_name}</span>\
- </label>`;
+ output += `\
+<label class="toggle">\
+ <input type="checkbox" id="${js_data_name}"${checked}>\
+ <span class="label">${setting_name}</span>\
+</label>`;
}
output += "</div>";
}
@@ -154,30 +169,27 @@
* @return {HTMLElement}
*/
function buildSettingsPage() {
- const themes = getVar("themes").split(",");
+ const theme_names = getVar("themes").split(",").filter(t => t);
+ theme_names.push("light", "dark", "ayu");
+
const settings = [
{
- "name": "Use system theme",
- "js_name": "use-system-theme",
- "default": true,
- },
- {
"name": "Theme",
"js_name": "theme",
- "default": "light",
- "options": themes,
+ "default": "system preference",
+ "options": theme_names.concat("system preference"),
},
{
"name": "Preferred light theme",
"js_name": "preferred-light-theme",
"default": "light",
- "options": themes,
+ "options": theme_names,
},
{
"name": "Preferred dark theme",
"js_name": "preferred-dark-theme",
"default": "dark",
- "options": themes,
+ "options": theme_names,
},
{
"name": "Auto-hide item contents for large items",
@@ -256,7 +268,7 @@
event.preventDefault();
const shouldDisplaySettings = settingsMenu.style.display === "none";
- window.hidePopoverMenus();
+ window.hideAllModals();
if (shouldDisplaySettings) {
displaySettings();
}
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index 0b9368dd8..5db768c1c 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -157,7 +157,7 @@ function highlightSourceLines(match) {
x.scrollIntoView();
}
onEachLazy(document.getElementsByClassName("src-line-numbers"), e => {
- onEachLazy(e.getElementsByTagName("span"), i_e => {
+ onEachLazy(e.getElementsByTagName("a"), i_e => {
removeClass(i_e, "line-highlighted");
});
});
@@ -188,8 +188,13 @@ const handleSourceHighlight = (function() {
return ev => {
let cur_line_id = parseInt(ev.target.id, 10);
- // It can happen when clicking not on a line number span.
- if (isNaN(cur_line_id)) {
+ // This event handler is attached to the entire line number column, but it should only
+ // be run if one of the anchors is clicked. It also shouldn't do anything if the anchor
+ // is clicked with a modifier key (to open a new browser tab).
+ if (isNaN(cur_line_id) ||
+ ev.ctrlKey ||
+ ev.altKey ||
+ ev.metaKey) {
return;
}
ev.preventDefault();
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index b462a2c50..db2db83ca 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -126,33 +126,29 @@ function getCurrentValue(name) {
}
}
-function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
- const newHref = mainStyleElem.href.replace(
- /\/rustdoc([^/]*)\.css/, "/" + newTheme + "$1" + ".css");
-
+function switchTheme(styleElem, mainStyleElem, newThemeName, saveTheme) {
// If this new value comes from a system setting or from the previously
// saved theme, no need to save it.
if (saveTheme) {
- updateLocalStorage("theme", newTheme);
- }
-
- if (styleElem.href === newHref) {
- return;
+ updateLocalStorage("theme", newThemeName);
}
- let found = false;
if (savedHref.length === 0) {
onEachLazy(document.getElementsByTagName("link"), el => {
savedHref.push(el.href);
});
}
- onEach(savedHref, el => {
- if (el === newHref) {
- found = true;
+ const newHref = savedHref.find(url => {
+ const m = url.match(/static\.files\/(.*)-[a-f0-9]{16}\.css$/);
+ if (m && m[1] === newThemeName) {
+ return true;
+ }
+ const m2 = url.match(/\/([^/]*)\.css$/);
+ if (m2 && m2[1].startsWith(newThemeName)) {
return true;
}
});
- if (found) {
+ if (newHref && newHref !== styleElem.href) {
styleElem.href = newHref;
}
}
diff --git a/src/librustdoc/html/static/scrape-examples-help.md b/src/librustdoc/html/static/scrape-examples-help.md
index 035b2e18b..002d19ec9 100644
--- a/src/librustdoc/html/static/scrape-examples-help.md
+++ b/src/librustdoc/html/static/scrape-examples-help.md
@@ -1,4 +1,4 @@
-Rustdoc will automatically scrape examples of documented items from the `examples/` directory of a project. These examples will be included within the generated documentation for that item. For example, if your library contains a public function:
+Rustdoc will automatically scrape examples of documented items from a project's source code. These examples will be included within the generated documentation for that item. For example, if your library contains a public function:
```rust
// src/lib.rs
@@ -16,6 +16,7 @@ fn main() {
Then this code snippet will be included in the documentation for `a_func`.
+
## How to read scraped examples
Scraped examples are shown as blocks of code from a given file. The relevant item will be highlighted. If the file is larger than a couple lines, only a small window will be shown which you can expand by clicking &varr; in the top-right. If a file contains multiple instances of an item, you can use the &pr; and &sc; buttons to toggle through each instance.
@@ -25,7 +26,7 @@ If there is more than one file that contains examples, then you should click "Mo
## How Rustdoc scrapes examples
-When you run `cargo doc`, Rustdoc will analyze all the crates that match Cargo's `--examples` filter for instances of items that occur in the crates being documented. Then Rustdoc will include the source code of these instances in the generated documentation.
+When you run `cargo doc -Zunstable-options -Zrustdoc-scrape-examples`, Rustdoc will analyze all the documented crates for uses of documented items. Then Rustdoc will include the source code of these instances in the generated documentation.
Rustdoc has a few techniques to ensure this doesn't overwhelm documentation readers, and that it doesn't blow up the page size:
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index 75f2b7e35..b48b82307 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -2,167 +2,132 @@
//!
//! All the static files are included here for centralized access in case anything other than the
//! HTML rendering code (say, the theme checker) needs to access one of these files.
-//!
-//! Note about types: CSS and JavaScript files are included as `&'static str` to allow for the
-//! minifier to run on them. All other files are included as `&'static [u8]` so they can be
-//! directly written to a `Write` handle.
-
-/// The file contents of the main `rustdoc.css` file, responsible for the core layout of the page.
-pub(crate) static RUSTDOC_CSS: &str = include_str!("static/css/rustdoc.css");
-
-/// The file contents of `settings.css`, responsible for the items on the settings page.
-pub(crate) static SETTINGS_CSS: &str = include_str!("static/css/settings.css");
-
-/// The file contents of the `noscript.css` file, used in case JS isn't supported or is disabled.
-pub(crate) static NOSCRIPT_CSS: &str = include_str!("static/css/noscript.css");
-
-/// The file contents of `normalize.css`, included to even out standard elements between browser
-/// implementations.
-pub(crate) static NORMALIZE_CSS: &str = include_str!("static/css/normalize.css");
-
-/// The file contents of `main.js`, which contains the core JavaScript used on documentation pages,
-/// including search behavior and docblock folding, among others.
-pub(crate) static MAIN_JS: &str = include_str!("static/js/main.js");
-
-/// The file contents of `search.js`, which contains the search behavior.
-pub(crate) static SEARCH_JS: &str = include_str!("static/js/search.js");
-
-/// The file contents of `settings.js`, which contains the JavaScript used to handle the settings
-/// page.
-pub(crate) static SETTINGS_JS: &str = include_str!("static/js/settings.js");
-
-/// The file contents of `storage.js`, which contains functionality related to browser Local
-/// Storage, used to store documentation settings.
-pub(crate) static STORAGE_JS: &str = include_str!("static/js/storage.js");
-
-/// The file contents of `scraped-examples.js`, which contains functionality related to the
-/// --scrape-examples flag that inserts automatically-found examples of usages of items.
-pub(crate) static SCRAPE_EXAMPLES_JS: &str = include_str!("static/js/scrape-examples.js");
-
-pub(crate) static SCRAPE_EXAMPLES_HELP_MD: &str = include_str!("static/scrape-examples-help.md");
-
-/// The file contents of `wheel.svg`, the icon used for the settings button.
-pub(crate) static WHEEL_SVG: &[u8] = include_bytes!("static/images/wheel.svg");
-
-/// The file contents of `clipboard.svg`, the icon used for the "copy path" button.
-pub(crate) static CLIPBOARD_SVG: &[u8] = include_bytes!("static/images/clipboard.svg");
-
-/// The file contents of `down-arrow.svg`, the icon used for the crate choice combobox.
-pub(crate) static DOWN_ARROW_SVG: &[u8] = include_bytes!("static/images/down-arrow.svg");
-
-/// The file contents of `toggle-minus.svg`, the icon used for opened toggles.
-pub(crate) static TOGGLE_MINUS_PNG: &[u8] = include_bytes!("static/images/toggle-minus.svg");
-
-/// The file contents of `toggle-plus.svg`, the icon used for closed toggles.
-pub(crate) static TOGGLE_PLUS_PNG: &[u8] = include_bytes!("static/images/toggle-plus.svg");
-/// The contents of `COPYRIGHT.txt`, the license listing for files distributed with documentation
-/// output.
-pub(crate) static COPYRIGHT: &[u8] = include_bytes!("static/COPYRIGHT.txt");
+use rustc_data_structures::fx::FxHasher;
+use std::hash::Hasher;
+use std::path::{Path, PathBuf};
+use std::{fmt, str};
-/// The contents of `LICENSE-APACHE.txt`, the text of the Apache License, version 2.0.
-pub(crate) static LICENSE_APACHE: &[u8] = include_bytes!("static/LICENSE-APACHE.txt");
-
-/// The contents of `LICENSE-MIT.txt`, the text of the MIT License.
-pub(crate) static LICENSE_MIT: &[u8] = include_bytes!("static/LICENSE-MIT.txt");
-
-/// The contents of `rust-logo.svg`, the default icon of the documentation.
-pub(crate) static RUST_LOGO_SVG: &[u8] = include_bytes!("static/images/rust-logo.svg");
-
-/// The default documentation favicons (SVG and PNG fallbacks)
-pub(crate) static RUST_FAVICON_SVG: &[u8] = include_bytes!("static/images/favicon.svg");
-pub(crate) static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/images/favicon-16x16.png");
-pub(crate) static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/images/favicon-32x32.png");
-
-/// The built-in themes given to every documentation site.
-pub(crate) mod themes {
- /// The "light" theme, selected by default when no setting is available. Used as the basis for
- /// the `--check-theme` functionality.
- pub(crate) static LIGHT: &str = include_str!("static/css/themes/light.css");
-
- /// The "dark" theme.
- pub(crate) static DARK: &str = include_str!("static/css/themes/dark.css");
-
- /// The "ayu" theme.
- pub(crate) static AYU: &str = include_str!("static/css/themes/ayu.css");
+pub(crate) struct StaticFile {
+ pub(crate) filename: PathBuf,
+ pub(crate) bytes: &'static [u8],
}
-/// Files related to the Fira Sans font.
-pub(crate) mod fira_sans {
- /// The file `FiraSans-Regular.woff2`, the Regular variant of the Fira Sans font in woff2.
- pub(crate) static REGULAR: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff2");
-
- /// The file `FiraSans-Medium.woff2`, the Medium variant of the Fira Sans font in woff2.
- pub(crate) static MEDIUM: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff2");
-
- /// The file `FiraSans-LICENSE.txt`, the license text for the Fira Sans font.
- pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/FiraSans-LICENSE.txt");
+impl StaticFile {
+ fn new(filename: &str, bytes: &'static [u8]) -> StaticFile {
+ Self { filename: static_filename(filename, bytes), bytes }
+ }
+
+ pub(crate) fn minified(&self) -> Vec<u8> {
+ let extension = match self.filename.extension() {
+ Some(e) => e,
+ None => return self.bytes.to_owned(),
+ };
+ if extension == "css" {
+ minifier::css::minify(str::from_utf8(self.bytes).unwrap()).unwrap().to_string().into()
+ } else if extension == "js" {
+ minifier::js::minify(str::from_utf8(self.bytes).unwrap()).to_string().into()
+ } else {
+ self.bytes.to_owned()
+ }
+ }
+
+ pub(crate) fn output_filename(&self) -> &Path {
+ &self.filename
+ }
}
-/// Files related to the Source Serif 4 font.
-pub(crate) mod source_serif_4 {
- /// The file `SourceSerif4-Regular.ttf.woff2`, the Regular variant of the Source Serif 4 font in
- /// woff2.
- pub(crate) static REGULAR: &[u8] =
- include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff2");
-
- /// The file `SourceSerif4-Bold.ttf.woff2`, the Bold variant of the Source Serif 4 font in
- /// woff2.
- pub(crate) static BOLD: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff2");
-
- /// The file `SourceSerif4-It.ttf.woff2`, the Italic variant of the Source Serif 4 font in
- /// woff2.
- pub(crate) static ITALIC: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff2");
-
- /// The file `SourceSerif4-LICENSE.txt`, the license text for the Source Serif 4 font.
- pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/SourceSerif4-LICENSE.md");
+/// The Display implementation for a StaticFile outputs its filename. This makes it
+/// convenient to interpolate static files into HTML templates.
+impl fmt::Display for StaticFile {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.output_filename().display())
+ }
}
-/// Files related to the Source Code Pro font.
-pub(crate) mod source_code_pro {
- /// The file `SourceCodePro-Regular.ttf.woff2`, the Regular variant of the Source Code Pro font
- /// in woff2.
- pub(crate) static REGULAR: &[u8] =
- include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff2");
-
- /// The file `SourceCodePro-Semibold.ttf.woff2`, the Semibold variant of the Source Code Pro
- /// font in woff2.
- pub(crate) static SEMIBOLD: &[u8] =
- include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff2");
-
- /// The file `SourceCodePro-It.ttf.woff2`, the Italic variant of the Source Code Pro font in
- /// woff2.
- pub(crate) static ITALIC: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff2");
+/// Insert the provided suffix into a filename just before the extension.
+pub(crate) fn suffix_path(filename: &str, suffix: &str) -> PathBuf {
+ // We use splitn vs Path::extension here because we might get a filename
+ // like `style.min.css` and we want to process that into
+ // `style-suffix.min.css`. Path::extension would just return `css`
+ // which would result in `style.min-suffix.css` which isn't what we
+ // want.
+ let (base, ext) = filename.split_once('.').unwrap();
+ let filename = format!("{}{}.{}", base, suffix, ext);
+ filename.into()
+}
- /// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font.
- pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/SourceCodePro-LICENSE.txt");
+pub(crate) fn static_filename(filename: &str, contents: &[u8]) -> PathBuf {
+ let filename = filename.rsplit('/').next().unwrap();
+ suffix_path(filename, &static_suffix(contents))
}
-/// Files related to the Nanum Barun Gothic font.
-///
-/// These files are used to avoid some legacy CJK serif fonts in Windows.
-///
-/// Note that the Noto Sans KR font, which was used previously but was not very readable on Windows,
-/// has been replaced by the Nanum Barun Gothic font. This is due to Windows' implementation of font
-/// rendering that distorts OpenType fonts too much.
-///
-/// The font files were generated with these commands:
-///
-/// ```sh
-/// pyftsubset NanumBarunGothic.ttf \
-/// --unicodes=U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF \
-/// --output-file=NanumBarunGothic.ttf.woff2 --flavor=woff2
-/// ```
-pub(crate) mod nanum_barun_gothic {
- /// The file `NanumBarunGothic.ttf.woff2`, the Regular variant of the Nanum Barun Gothic font.
- pub(crate) static REGULAR: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff2");
+fn static_suffix(bytes: &[u8]) -> String {
+ let mut hasher = FxHasher::default();
+ hasher.write(bytes);
+ format!("-{:016x}", hasher.finish())
+}
- /// The file `NanumBarunGothic-LICENSE.txt`, the license text of the Nanum Barun Gothic font.
- pub(crate) static LICENSE: &[u8] = include_bytes!("static/fonts/NanumBarunGothic-LICENSE.txt");
+macro_rules! static_files {
+ ($($field:ident => $file_path:literal,)+) => {
+ pub(crate) struct StaticFiles {
+ $(pub $field: StaticFile,)+
+ }
+
+ pub(crate) static STATIC_FILES: std::sync::LazyLock<StaticFiles> = std::sync::LazyLock::new(|| StaticFiles {
+ $($field: StaticFile::new($file_path, include_bytes!($file_path)),)+
+ });
+
+ pub(crate) fn for_each<E>(f: impl Fn(&StaticFile) -> Result<(), E>) -> Result<(), E> {
+ for sf in [
+ $(&STATIC_FILES.$field,)+
+ ] {
+ f(sf)?
+ }
+ Ok(())
+ }
+ }
}
-/// Files related to the sidebar in rustdoc sources.
-pub(crate) mod sidebar {
- /// File script to handle sidebar.
- pub(crate) static SOURCE_SCRIPT: &str = include_str!("static/js/source-script.js");
+static_files! {
+ rustdoc_css => "static/css/rustdoc.css",
+ settings_css => "static/css/settings.css",
+ noscript_css => "static/css/noscript.css",
+ normalize_css => "static/css/normalize.css",
+ main_js => "static/js/main.js",
+ search_js => "static/js/search.js",
+ settings_js => "static/js/settings.js",
+ source_script_js => "static/js/source-script.js",
+ storage_js => "static/js/storage.js",
+ scrape_examples_js => "static/js/scrape-examples.js",
+ wheel_svg => "static/images/wheel.svg",
+ clipboard_svg => "static/images/clipboard.svg",
+ down_arrow_svg => "static/images/down-arrow.svg",
+ toggle_minus_png => "static/images/toggle-minus.svg",
+ toggle_plus_png => "static/images/toggle-plus.svg",
+ copyright => "static/COPYRIGHT.txt",
+ license_apache => "static/LICENSE-APACHE.txt",
+ license_mit => "static/LICENSE-MIT.txt",
+ rust_logo_svg => "static/images/rust-logo.svg",
+ rust_favicon_svg => "static/images/favicon.svg",
+ rust_favicon_png_16 => "static/images/favicon-16x16.png",
+ rust_favicon_png_32 => "static/images/favicon-32x32.png",
+ theme_light_css => "static/css/themes/light.css",
+ theme_dark_css => "static/css/themes/dark.css",
+ theme_ayu_css => "static/css/themes/ayu.css",
+ fira_sans_regular => "static/fonts/FiraSans-Regular.woff2",
+ fira_sans_medium => "static/fonts/FiraSans-Medium.woff2",
+ fira_sans_license => "static/fonts/FiraSans-LICENSE.txt",
+ source_serif_4_regular => "static/fonts/SourceSerif4-Regular.ttf.woff2",
+ source_serif_4_bold => "static/fonts/SourceSerif4-Bold.ttf.woff2",
+ source_serif_4_italic => "static/fonts/SourceSerif4-It.ttf.woff2",
+ source_serif_4_license => "static/fonts/SourceSerif4-LICENSE.md",
+ source_code_pro_regular => "static/fonts/SourceCodePro-Regular.ttf.woff2",
+ source_code_pro_semibold => "static/fonts/SourceCodePro-Semibold.ttf.woff2",
+ source_code_pro_italic => "static/fonts/SourceCodePro-It.ttf.woff2",
+ source_code_pro_license => "static/fonts/SourceCodePro-LICENSE.txt",
+ nanum_barun_gothic_regular => "static/fonts/NanumBarunGothic.ttf.woff2",
+ nanum_barun_gothic_license => "static/fonts/NanumBarunGothic-LICENSE.txt",
}
+
+pub(crate) static SCRAPE_EXAMPLES_HELP_MD: &str = include_str!("static/scrape-examples-help.md");
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index c32386916..aa3bf827d 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -7,48 +7,44 @@
<meta name="description" content="{{page.description}}"> {#- -#}
<meta name="keywords" content="{{page.keywords}}"> {#- -#}
<title>{{page.title}}</title> {#- -#}
- <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceSerif4-Regular.ttf.woff2"> {#- -#}
- <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}FiraSans-Regular.woff2"> {#- -#}
- <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}FiraSans-Medium.woff2"> {#- -#}
- <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceCodePro-Regular.ttf.woff2"> {#- -#}
- <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceSerif4-Bold.ttf.woff2"> {#- -#}
- <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}SourceCodePro-Semibold.ttf.woff2"> {#- -#}
+ <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.source_serif_4_regular}}"> {#- -#}
+ <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.fira_sans_regular}}"> {#- -#}
+ <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.fira_sans_medium}}"> {#- -#}
+ <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.source_code_pro_regular}}"> {#- -#}
+ <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.source_serif_4_bold}}"> {#- -#}
+ <link rel="preload" as="font" type="font/woff2" crossorigin href="{{static_root_path|safe}}{{files.source_code_pro_semibold}}"> {#- -#}
<link rel="stylesheet" {# -#}
- href="{{static_root_path|safe}}normalize{{page.resource_suffix}}.css"> {#- -#}
+ href="{{static_root_path|safe}}{{files.normalize_css}}"> {#- -#}
<link rel="stylesheet" {# -#}
- href="{{static_root_path|safe}}rustdoc{{page.resource_suffix}}.css" {# -#}
+ href="{{static_root_path|safe}}{{files.rustdoc_css}}" {# -#}
id="mainThemeStyle"> {#- -#}
+ <link rel="stylesheet" id="themeStyle" href="{{static_root_path|safe}}{{files.theme_light_css}}"> {#- -#}
+ <link rel="stylesheet" disabled href="{{static_root_path|safe}}{{files.theme_dark_css}}"> {#- -#}
+ <link rel="stylesheet" disabled href="{{static_root_path|safe}}{{files.theme_ayu_css}}"> {#- -#}
{%- for theme in themes -%}
- <link rel="stylesheet" {# -#}
- href="{{static_root_path|safe}}{{theme}}{{page.resource_suffix}}.css" {# -#}
- {%- if theme == "light" -%}
- id="themeStyle"
- {%- else -%}
- disabled
- {%- endif -%}
- >
+ <link rel="stylesheet" disabled href="{{page.root_path|safe}}{{theme}}{{page.resource_suffix}}.css"> {#- -#}
{%- endfor -%}
<script id="default-settings" {# -#}
{% for (k, v) in layout.default_settings %}
data-{{k}}="{{v}}"
{%- endfor -%}
></script> {#- -#}
- <script src="{{static_root_path|safe}}storage{{page.resource_suffix}}.js"></script> {#- -#}
+ <script src="{{static_root_path|safe}}{{files.storage_js}}"></script> {#- -#}
{%- if page.css_class.contains("crate") -%}
<script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {#- -#}
{%- else if page.css_class == "source" -%}
- <script defer src="{{static_root_path|safe}}source-script{{page.resource_suffix}}.js"></script> {#- -#}
+ <script defer src="{{static_root_path|safe}}{{files.source_script_js}}"></script> {#- -#}
<script defer src="{{page.root_path|safe}}source-files{{page.resource_suffix}}.js"></script> {#- -#}
{%- else if !page.css_class.contains("mod") -%}
<script defer src="sidebar-items{{page.resource_suffix}}.js"></script> {#- -#}
{%- endif -%}
- <script defer src="{{static_root_path|safe}}main{{page.resource_suffix}}.js"></script> {#- -#}
+ <script defer src="{{static_root_path|safe}}{{files.main_js}}"></script> {#- -#}
{%- if layout.scrape_examples_extension -%}
- <script defer src="{{page.root_path|safe}}scrape-examples{{page.resource_suffix}}.js"></script> {#- -#}
+ <script defer src="{{static_root_path|safe}}{{files.scrape_examples_js}}"></script> {#- -#}
{%- endif -%}
<noscript> {#- -#}
<link rel="stylesheet" {# -#}
- href="{{static_root_path|safe}}noscript{{page.resource_suffix}}.css"> {#- -#}
+ href="{{static_root_path|safe}}{{files.noscript_css}}"> {#- -#}
</noscript> {#- -#}
{%- if layout.css_file_extension.is_some() -%}
<link rel="stylesheet" {# -#}
@@ -58,11 +54,11 @@
<link rel="icon" href="{{layout.favicon}}"> {#- -#}
{%- else -%}
<link rel="alternate icon" type="image/png" {# -#}
- href="{{static_root_path|safe}}favicon-16x16{{page.resource_suffix}}.png"> {#- -#}
+ href="{{static_root_path|safe}}{{files.rust_favicon_png_16}}"> {#- -#}
<link rel="alternate icon" type="image/png" {# -#}
- href="{{static_root_path|safe}}favicon-32x32{{page.resource_suffix}}.png"> {#- -#}
+ href="{{static_root_path|safe}}{{files.rust_favicon_png_32}}"> {#- -#}
<link rel="icon" type="image/svg+xml" {# -#}
- href="{{static_root_path|safe}}favicon{{page.resource_suffix}}.svg"> {#- -#}
+ href="{{static_root_path|safe}}{{files.rust_favicon_svg}}"> {#- -#}
{%- endif -%}
{{- layout.external_html.in_header|safe -}}
</head> {#- -#}
@@ -81,7 +77,7 @@
{%- if !layout.logo.is_empty() -%}
<img src="{{layout.logo}}" alt="logo"> {#- -#}
{%- else -%}
- <img class="rust-logo" src="{{static_root_path|safe}}rust-logo{{page.resource_suffix}}.svg" alt="logo"> {#- -#}
+ <img class="rust-logo" src="{{static_root_path|safe}}{{files.rust_logo_svg}}" alt="logo"> {#- -#}
{%- endif -%}
</div> {#- -#}
</a> {#- -#}
@@ -95,7 +91,7 @@
{%- if !layout.logo.is_empty() %}
<img src="{{layout.logo}}" alt="logo"> {#- -#}
{%- else -%}
- <img class="rust-logo" src="{{static_root_path|safe}}rust-logo{{page.resource_suffix}}.svg" alt="logo"> {#- -#}
+ <img class="rust-logo" src="{{static_root_path|safe}}{{files.rust_logo_svg}}" alt="logo"> {#- -#}
{%- endif -%}
</div> {#- -#}
</a> {#- -#}
@@ -110,7 +106,7 @@
{%- if !layout.logo.is_empty() %}
<img src="{{layout.logo}}" alt="logo"> {#- -#}
{%- else -%}
- <img class="rust-logo" src="{{static_root_path|safe}}rust-logo{{page.resource_suffix}}.svg" alt="logo"> {#- -#}
+ <img class="rust-logo" src="{{static_root_path|safe}}{{files.rust_logo_svg}}" alt="logo"> {#- -#}
{%- endif -%}
</a> {#- -#}
{%- endif -%}
@@ -119,6 +115,7 @@
<input {# -#}
class="search-input" {# -#}
name="search" {# -#}
+ aria-label="Run search in the documentation" {# -#}
autocomplete="off" {# -#}
spellcheck="false" {# -#}
placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
@@ -129,7 +126,7 @@
<div id="settings-menu" tabindex="-1"> {#- -#}
<a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
<img width="22" height="22" alt="Change settings" {# -#}
- src="{{static_root_path|safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
+ src="{{static_root_path|safe}}{{files.wheel_svg}}"> {#- -#}
</a> {#- -#}
</div> {#- -#}
</form> {#- -#}
@@ -140,10 +137,14 @@
{{- layout.external_html.after_content|safe -}}
<div id="rustdoc-vars" {# -#}
data-root-path="{{page.root_path|safe}}" {# -#}
+ data-static-root-path="{{static_root_path|safe}}" {# -#}
data-current-crate="{{layout.krate}}" {# -#}
data-themes="{{themes|join(",") }}" {# -#}
data-resource-suffix="{{page.resource_suffix}}" {# -#}
data-rustdoc-version="{{rustdoc_version}}" {# -#}
+ data-search-js="{{files.search_js}}" {# -#}
+ data-settings-js="{{files.settings_js}}" {# -#}
+ data-settings-css="{{files.settings_css}}" {# -#}
> {#- -#}
</div> {#- -#}
</body> {#- -#}
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html
index b6ce3ea3d..611d124d4 100644
--- a/src/librustdoc/html/templates/print_item.html
+++ b/src/librustdoc/html/templates/print_item.html
@@ -7,7 +7,7 @@
{%- endfor -%}
<a class="{{item_type}}" href="#">{{name}}</a> {#- -#}
<button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"> {#- -#}
- <img src="{{static_root_path|safe}}clipboard{{page.resource_suffix}}.svg" {# -#}
+ <img src="{{static_root_path|safe}}{{clipboard_svg}}" {# -#}
width="19" height="18" {# -#}
alt="Copy item path"> {#- -#}
</button> {#- -#}
@@ -21,8 +21,8 @@
<a class="srclink" href="{{href|safe}}">source</a> · {# -#}
{%- else -%}
{%- endmatch -%}
- <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs"> {#- -#}
- [<span class="inner">&#x2212;</span>] {#- -#}
- </a> {#- -#}
+ <button id="toggle-all-docs" title="collapse all docs"> {#- -#}
+ [<span>&#x2212;</span>] {#- -#}
+ </button> {#- -#}
</span> {#- -#}
</div> {#- -#}
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index cdf59cdd3..d7184053c 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -48,7 +48,8 @@ impl JsonRenderer<'_> {
.map(rustc_ast_pretty::pprust::attribute_to_string)
.collect();
let span = item.span(self.tcx);
- let clean::Item { name, attrs: _, kind: _, visibility, item_id, cfg: _ } = item;
+ let visibility = item.visibility(self.tcx);
+ let clean::Item { name, attrs: _, kind: _, item_id, cfg: _, .. } = item;
let inner = match *item.kind {
clean::KeywordItem => return None,
clean::StrippedItem(ref inner) => {
@@ -99,13 +100,12 @@ impl JsonRenderer<'_> {
}
}
- fn convert_visibility(&self, v: clean::Visibility) -> Visibility {
- use clean::Visibility::*;
+ fn convert_visibility(&self, v: Option<ty::Visibility<DefId>>) -> Visibility {
match v {
- Public => Visibility::Public,
- Inherited => Visibility::Default,
- Restricted(did) if did.is_crate_root() => Visibility::Crate,
- Restricted(did) => Visibility::Restricted {
+ None => Visibility::Default,
+ Some(ty::Visibility::Public) => Visibility::Public,
+ Some(ty::Visibility::Restricted(did)) if did.is_crate_root() => Visibility::Crate,
+ Some(ty::Visibility::Restricted(did)) => Visibility::Restricted {
parent: from_item_id(did.into(), self.tcx),
path: self.tcx.def_path(did).to_string_no_crate_verbose(),
},
@@ -257,12 +257,12 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
StructFieldItem(f) => ItemEnum::StructField(f.into_tcx(tcx)),
EnumItem(e) => ItemEnum::Enum(e.into_tcx(tcx)),
VariantItem(v) => ItemEnum::Variant(v.into_tcx(tcx)),
- FunctionItem(f) => ItemEnum::Function(from_function(f, header.unwrap(), tcx)),
- ForeignFunctionItem(f) => ItemEnum::Function(from_function(f, header.unwrap(), tcx)),
+ FunctionItem(f) => ItemEnum::Function(from_function(f, true, header.unwrap(), tcx)),
+ ForeignFunctionItem(f) => ItemEnum::Function(from_function(f, false, header.unwrap(), tcx)),
TraitItem(t) => ItemEnum::Trait((*t).into_tcx(tcx)),
TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_tcx(tcx)),
- MethodItem(m, _) => ItemEnum::Method(from_function_method(m, true, header.unwrap(), tcx)),
- TyMethodItem(m) => ItemEnum::Method(from_function_method(m, false, header.unwrap(), tcx)),
+ MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), tcx)),
+ TyMethodItem(m) => ItemEnum::Function(from_function(m, false, header.unwrap(), tcx)),
ImplItem(i) => ItemEnum::Impl((*i).into_tcx(tcx)),
StaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
ForeignStaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
@@ -283,7 +283,7 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
ItemEnum::AssocConst { type_: ty.into_tcx(tcx), default: Some(default.expr(tcx)) }
}
TyAssocTypeItem(g, b) => ItemEnum::AssocType {
- generics: (*g).into_tcx(tcx),
+ generics: g.into_tcx(tcx),
bounds: b.into_tcx(tcx),
default: None,
},
@@ -315,15 +315,15 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
impl FromWithTcx<clean::Struct> for Struct {
fn from_tcx(struct_: clean::Struct, tcx: TyCtxt<'_>) -> Self {
let fields_stripped = struct_.has_stripped_entries();
- let clean::Struct { struct_type, generics, fields } = struct_;
+ let clean::Struct { ctor_kind, generics, fields } = struct_;
- let kind = match struct_type {
- CtorKind::Fn => StructKind::Tuple(ids_keeping_stripped(fields, tcx)),
- CtorKind::Const => {
+ let kind = match ctor_kind {
+ Some(CtorKind::Fn) => StructKind::Tuple(ids_keeping_stripped(fields, tcx)),
+ Some(CtorKind::Const) => {
assert!(fields.is_empty());
StructKind::Unit
}
- CtorKind::Fictive => StructKind::Plain { fields: ids(fields, tcx), fields_stripped },
+ None => StructKind::Plain { fields: ids(fields, tcx), fields_stripped },
};
Struct {
@@ -485,7 +485,7 @@ impl FromWithTcx<clean::Type> for Type {
BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
Tuple(t) => Type::Tuple(t.into_tcx(tcx)),
Slice(t) => Type::Slice(Box::new((*t).into_tcx(tcx))),
- Array(t, s) => Type::Array { type_: Box::new((*t).into_tcx(tcx)), len: s },
+ Array(t, s) => Type::Array { type_: Box::new((*t).into_tcx(tcx)), len: s.to_string() },
ImplTrait(g) => Type::ImplTrait(g.into_tcx(tcx)),
Infer => Type::Infer,
RawPointer(mutability, type_) => Type::RawPointer {
@@ -618,6 +618,7 @@ impl FromWithTcx<clean::Impl> for Impl {
pub(crate) fn from_function(
function: Box<clean::Function>,
+ has_body: bool,
header: rustc_hir::FnHeader,
tcx: TyCtxt<'_>,
) -> Function {
@@ -626,20 +627,6 @@ pub(crate) fn from_function(
decl: decl.into_tcx(tcx),
generics: generics.into_tcx(tcx),
header: from_fn_header(&header),
- }
-}
-
-pub(crate) fn from_function_method(
- function: Box<clean::Function>,
- has_body: bool,
- header: rustc_hir::FnHeader,
- tcx: TyCtxt<'_>,
-) -> Method {
- let clean::Function { decl, generics } = *function;
- Method {
- decl: decl.into_tcx(tcx),
- generics: generics.into_tcx(tcx),
- header: from_fn_header(&header),
has_body,
}
}
@@ -674,7 +661,7 @@ impl FromWithTcx<clean::Variant> for Variant {
impl FromWithTcx<clean::Discriminant> for Discriminant {
fn from_tcx(disr: clean::Discriminant, tcx: TyCtxt<'_>) -> Self {
Discriminant {
- // expr is only none if going throught the inlineing path, which gets
+ // expr is only none if going through the inlineing path, which gets
// `rustc_middle` types, not `rustc_hir`, but because JSON never inlines
// the expr is always some.
expr: disr.expr(tcx).unwrap(),
@@ -759,14 +746,13 @@ impl FromWithTcx<ItemType> for ItemKind {
Struct => ItemKind::Struct,
Union => ItemKind::Union,
Enum => ItemKind::Enum,
- Function => ItemKind::Function,
+ Function | TyMethod | Method => ItemKind::Function,
Typedef => ItemKind::Typedef,
OpaqueTy => ItemKind::OpaqueTy,
Static => ItemKind::Static,
Constant => ItemKind::Constant,
Trait => ItemKind::Trait,
Impl => ItemKind::Impl,
- TyMethod | Method => ItemKind::Method,
StructField => ItemKind::StructField,
Variant => ItemKind::Variant,
Macro => ItemKind::Macro,
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index d13efe6c1..1196f944f 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -99,53 +99,6 @@ impl<'tcx> JsonRenderer<'tcx> {
})
.unwrap_or_default()
}
-
- fn get_trait_items(&mut self) -> Vec<(types::Id, types::Item)> {
- debug!("Adding foreign trait items");
- Rc::clone(&self.cache)
- .traits
- .iter()
- .filter_map(|(&id, trait_item)| {
- // only need to synthesize items for external traits
- if !id.is_local() {
- for item in &trait_item.items {
- trace!("Adding subitem to {id:?}: {:?}", item.item_id);
- self.item(item.clone()).unwrap();
- }
- let item_id = from_item_id(id.into(), self.tcx);
- Some((
- item_id.clone(),
- types::Item {
- id: item_id,
- crate_id: id.krate.as_u32(),
- name: self
- .cache
- .paths
- .get(&id)
- .unwrap_or_else(|| {
- self.cache
- .external_paths
- .get(&id)
- .expect("Trait should either be in local or external paths")
- })
- .0
- .last()
- .map(|s| s.to_string()),
- visibility: types::Visibility::Public,
- inner: types::ItemEnum::Trait(trait_item.clone().into_tcx(self.tcx)),
- span: None,
- docs: Default::default(),
- links: Default::default(),
- attrs: Default::default(),
- deprecation: Default::default(),
- },
- ))
- } else {
- None
- }
- })
- .collect()
- }
}
impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
@@ -223,15 +176,14 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
false
}
- types::ItemEnum::Method(_)
+ types::ItemEnum::Function(_)
| types::ItemEnum::Module(_)
+ | types::ItemEnum::Import(_)
| types::ItemEnum::AssocConst { .. }
| types::ItemEnum::AssocType { .. } => true,
types::ItemEnum::ExternCrate { .. }
- | types::ItemEnum::Import(_)
| types::ItemEnum::StructField(_)
| types::ItemEnum::Variant(_)
- | types::ItemEnum::Function(_)
| types::ItemEnum::TraitAlias(_)
| types::ItemEnum::Impl(_)
| types::ItemEnum::Typedef(_)
@@ -277,11 +229,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
let e = ExternalCrate { crate_num: LOCAL_CRATE };
- // FIXME(adotinthevoid): Remove this, as it's not consistant with not
- // inlining foreign items.
- let foreign_trait_items = self.get_trait_items();
- let mut index = (*self.index).clone().into_inner();
- index.extend(foreign_trait_items);
+ let index = (*self.index).clone().into_inner();
debug!("Constructing Output");
// This needs to be the default HashMap for compatibility with the public interface for
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 4cf9435d9..ef1d7da5a 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -8,6 +8,7 @@
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(drain_filter)]
+#![feature(is_terminal)]
#![feature(let_chains)]
#![feature(test)]
#![feature(never_type)]
@@ -69,7 +70,7 @@ extern crate jemalloc_sys;
use std::default::Default;
use std::env::{self, VarError};
-use std::io;
+use std::io::{self, IsTerminal};
use std::process;
use rustc_driver::abort_on_err;
@@ -179,7 +180,7 @@ fn init_logging() {
let color_logs = match std::env::var("RUSTDOC_LOG_COLOR").as_deref() {
Ok("always") => true,
Ok("never") => false,
- Ok("auto") | Err(VarError::NotPresent) => atty::is(atty::Stream::Stdout),
+ Ok("auto") | Err(VarError::NotPresent) => io::stdout().is_terminal(),
Ok(value) => early_error(
ErrorOutputType::default(),
&format!("invalid log color value '{}': expected one of always, never, or auto", value),
@@ -469,9 +470,6 @@ fn opts() -> Vec<RustcOptGroup> {
stable("json", |o| {
o.optopt("", "json", "Configure the structure of JSON diagnostics", "CONFIG")
}),
- unstable("disable-minification", |o| {
- o.optflagmulti("", "disable-minification", "Disable minification applied on JS files")
- }),
stable("allow", |o| o.optmulti("A", "allow", "Set lint allowed", "LINT")),
stable("warn", |o| o.optmulti("W", "warn", "Set lint warnings", "LINT")),
stable("force-warn", |o| o.optmulti("", "force-warn", "Set lint force-warn", "LINT")),
@@ -610,6 +608,7 @@ fn opts() -> Vec<RustcOptGroup> {
)
}),
// deprecated / removed options
+ unstable("disable-minification", |o| o.optflagmulti("", "disable-minification", "removed")),
stable("plugin-path", |o| {
o.optmulti(
"",
@@ -675,7 +674,7 @@ type MainResult = Result<(), ErrorGuaranteed>;
fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainResult {
match res {
- Ok(()) => Ok(()),
+ Ok(()) => diag.has_errors().map_or(Ok(()), Err),
Err(err) => {
let reported = diag.struct_err(&err).emit();
Err(reported)
@@ -690,7 +689,7 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
tcx: TyCtxt<'tcx>,
) -> MainResult {
match formats::run_format::<T>(krate, renderopts, cache, tcx) {
- Ok(_) => Ok(()),
+ Ok(_) => tcx.sess.has_errors().map_or(Ok(()), Err),
Err(e) => {
let mut msg =
tcx.sess.struct_err(&format!("couldn't generate documentation: {}", e.error));
@@ -775,6 +774,7 @@ fn main_args(at_args: &[String]) -> MainResult {
let output_format = options.output_format;
let externs = options.externs.clone();
let scrape_examples_options = options.scrape_examples_options.clone();
+ let bin_crate = options.bin_crate;
let config = core::create_config(options);
@@ -782,10 +782,7 @@ fn main_args(at_args: &[String]) -> MainResult {
let sess = compiler.session();
if sess.opts.describe_lints {
- let mut lint_store = rustc_lint::new_lint_store(
- sess.opts.unstable_opts.no_interleave_lints,
- sess.enable_internal_lints(),
- );
+ let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
let registered_lints = if let Some(register_lints) = compiler.register_lints() {
register_lints(sess, &mut lint_store);
true
@@ -836,7 +833,14 @@ fn main_args(at_args: &[String]) -> MainResult {
info!("finished with rustc");
if let Some(options) = scrape_examples_options {
- return scrape_examples::run(krate, render_opts, cache, tcx, options);
+ return scrape_examples::run(
+ krate,
+ render_opts,
+ cache,
+ tcx,
+ options,
+ bin_crate,
+ );
}
cache.crate_version = crate_version;
diff --git a/src/librustdoc/passes/bare_urls.rs b/src/librustdoc/passes/bare_urls.rs
deleted file mode 100644
index 7ff3ccef9..000000000
--- a/src/librustdoc/passes/bare_urls.rs
+++ /dev/null
@@ -1,110 +0,0 @@
-//! Detects links that are not linkified, e.g., in Markdown such as `Go to https://example.com/.`
-//! Suggests wrapping the link with angle brackets: `Go to <https://example.com/>.` to linkify it.
-use super::Pass;
-use crate::clean::*;
-use crate::core::DocContext;
-use crate::html::markdown::main_body_opts;
-use crate::visit::DocVisitor;
-use core::ops::Range;
-use pulldown_cmark::{Event, Parser, Tag};
-use regex::Regex;
-use rustc_errors::Applicability;
-use std::mem;
-use std::sync::LazyLock;
-
-pub(crate) const CHECK_BARE_URLS: Pass = Pass {
- name: "check-bare-urls",
- run: check_bare_urls,
- description: "detects URLs that are not hyperlinks",
-};
-
-static URL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
- Regex::new(concat!(
- r"https?://", // url scheme
- r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains
- r"[a-zA-Z]{2,63}", // root domain
- r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)" // optional query or url fragments
- ))
- .expect("failed to build regex")
-});
-
-struct BareUrlsLinter<'a, 'tcx> {
- cx: &'a mut DocContext<'tcx>,
-}
-
-impl<'a, 'tcx> BareUrlsLinter<'a, 'tcx> {
- fn find_raw_urls(
- &self,
- text: &str,
- range: Range<usize>,
- f: &impl Fn(&DocContext<'_>, &str, &str, Range<usize>),
- ) {
- trace!("looking for raw urls in {}", text);
- // For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
- for match_ in URL_REGEX.find_iter(text) {
- let url = match_.as_str();
- let url_range = match_.range();
- f(
- self.cx,
- "this URL is not a hyperlink",
- url,
- Range { start: range.start + url_range.start, end: range.start + url_range.end },
- );
- }
- }
-}
-
-pub(crate) fn check_bare_urls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
- BareUrlsLinter { cx }.visit_crate(&krate);
- krate
-}
-
-impl<'a, 'tcx> DocVisitor for BareUrlsLinter<'a, 'tcx> {
- fn visit_item(&mut self, item: &Item) {
- let Some(hir_id) = DocContext::as_local_hir_id(self.cx.tcx, item.item_id)
- else {
- // If non-local, no need to check anything.
- return;
- };
- let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
- if !dox.is_empty() {
- let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range<usize>| {
- let sp = super::source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs)
- .unwrap_or_else(|| item.attr_span(cx.tcx));
- cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| {
- lint.note("bare URLs are not automatically turned into clickable links")
- .span_suggestion(
- sp,
- "use an automatic link instead",
- format!("<{}>", url),
- Applicability::MachineApplicable,
- )
- });
- };
-
- let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
-
- while let Some((event, range)) = p.next() {
- match event {
- Event::Text(s) => self.find_raw_urls(&s, range, &report_diag),
- // We don't want to check the text inside code blocks or links.
- Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link(..))) => {
- while let Some((event, _)) = p.next() {
- match event {
- Event::End(end)
- if mem::discriminant(&end) == mem::discriminant(&tag) =>
- {
- break;
- }
- _ => {}
- }
- }
- }
- _ => {}
- }
- }
- }
-
- self.visit_item_recur(item)
- }
-}
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs
index 48835abf9..02b227896 100644
--- a/src/librustdoc/passes/calculate_doc_coverage.rs
+++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -244,10 +244,10 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> {
matches!(
node,
hir::Node::Variant(hir::Variant {
- data: hir::VariantData::Tuple(_, _),
+ data: hir::VariantData::Tuple(_, _, _),
..
}) | hir::Node::Item(hir::Item {
- kind: hir::ItemKind::Struct(hir::VariantData::Tuple(_, _), _),
+ kind: hir::ItemKind::Struct(hir::VariantData::Tuple(_, _, _), _),
..
})
)
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
deleted file mode 100644
index 2e651b538..000000000
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ /dev/null
@@ -1,209 +0,0 @@
-//! Validates syntax inside Rust code blocks (\`\`\`rust).
-use rustc_data_structures::sync::{Lock, Lrc};
-use rustc_errors::{
- emitter::Emitter,
- translation::{to_fluent_args, Translate},
- Applicability, Diagnostic, Handler, LazyFallbackBundle,
-};
-use rustc_parse::parse_stream_from_source_str;
-use rustc_session::parse::ParseSess;
-use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
-use rustc_span::source_map::{FilePathMapping, SourceMap};
-use rustc_span::{FileName, InnerSpan, DUMMY_SP};
-
-use crate::clean;
-use crate::core::DocContext;
-use crate::html::markdown::{self, RustCodeBlock};
-use crate::passes::Pass;
-use crate::visit::DocVisitor;
-
-pub(crate) const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass {
- name: "check-code-block-syntax",
- run: check_code_block_syntax,
- description: "validates syntax inside Rust code blocks",
-};
-
-pub(crate) fn check_code_block_syntax(
- krate: clean::Crate,
- cx: &mut DocContext<'_>,
-) -> clean::Crate {
- SyntaxChecker { cx }.visit_crate(&krate);
- krate
-}
-
-struct SyntaxChecker<'a, 'tcx> {
- cx: &'a DocContext<'tcx>,
-}
-
-impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
- fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeBlock) {
- let buffer = Lrc::new(Lock::new(Buffer::default()));
- let fallback_bundle =
- rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
- let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle };
-
- let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
- let handler = Handler::with_emitter(false, None, Box::new(emitter));
- let source = dox[code_block.code].to_owned();
- let sess = ParseSess::with_span_handler(handler, sm);
-
- let edition = code_block.lang_string.edition.unwrap_or_else(|| self.cx.tcx.sess.edition());
- let expn_data = ExpnData::default(
- ExpnKind::AstPass(AstPass::TestHarness),
- DUMMY_SP,
- edition,
- None,
- None,
- );
- let expn_id =
- self.cx.tcx.with_stable_hashing_context(|hcx| LocalExpnId::fresh(expn_data, hcx));
- let span = DUMMY_SP.fresh_expansion(expn_id);
-
- let is_empty = rustc_driver::catch_fatal_errors(|| {
- parse_stream_from_source_str(
- FileName::Custom(String::from("doctest")),
- source,
- &sess,
- Some(span),
- )
- .is_empty()
- })
- .unwrap_or(false);
- let buffer = buffer.borrow();
-
- if !buffer.has_errors && !is_empty {
- // No errors in a non-empty program.
- return;
- }
-
- let Some(local_id) = item.item_id.as_def_id().and_then(|x| x.as_local())
- else {
- // We don't need to check the syntax for other crates so returning
- // without doing anything should not be a problem.
- return;
- };
-
- let hir_id = self.cx.tcx.hir().local_def_id_to_hir_id(local_id);
- let empty_block = code_block.lang_string == Default::default() && code_block.is_fenced;
- let is_ignore = code_block.lang_string.ignore != markdown::Ignore::None;
-
- // The span and whether it is precise or not.
- let (sp, precise_span) = match super::source_span_for_markdown_range(
- self.cx.tcx,
- dox,
- &code_block.range,
- &item.attrs,
- ) {
- Some(sp) => (sp, true),
- None => (item.attr_span(self.cx.tcx), false),
- };
-
- let msg = if buffer.has_errors {
- "could not parse code block as Rust code"
- } else {
- "Rust code block is empty"
- };
-
- // Finally build and emit the completed diagnostic.
- // All points of divergence have been handled earlier so this can be
- // done the same way whether the span is precise or not.
- self.cx.tcx.struct_span_lint_hir(
- crate::lint::INVALID_RUST_CODEBLOCKS,
- hir_id,
- sp,
- msg,
- |lint| {
- let explanation = if is_ignore {
- "`ignore` code blocks require valid Rust code for syntax highlighting; \
- mark blocks that do not contain Rust code as text"
- } else {
- "mark blocks that do not contain Rust code as text"
- };
-
- if precise_span {
- if is_ignore {
- // giving an accurate suggestion is hard because `ignore` might not have come first in the list.
- // just give a `help` instead.
- lint.span_help(
- sp.from_inner(InnerSpan::new(0, 3)),
- &format!("{}: ```text", explanation),
- );
- } else if empty_block {
- lint.span_suggestion(
- sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(),
- explanation,
- "text",
- Applicability::MachineApplicable,
- );
- }
- } else if empty_block || is_ignore {
- lint.help(&format!("{}: ```text", explanation));
- }
-
- // FIXME(#67563): Provide more context for these errors by displaying the spans inline.
- for message in buffer.messages.iter() {
- lint.note(message);
- }
-
- lint
- },
- );
- }
-}
-
-impl<'a, 'tcx> DocVisitor for SyntaxChecker<'a, 'tcx> {
- fn visit_item(&mut self, item: &clean::Item) {
- if let Some(dox) = &item.attrs.collapsed_doc_value() {
- let sp = item.attr_span(self.cx.tcx);
- let extra = crate::html::markdown::ExtraInfo::new_did(
- self.cx.tcx,
- item.item_id.expect_def_id(),
- sp,
- );
- for code_block in markdown::rust_code_blocks(dox, &extra) {
- self.check_rust_syntax(item, dox, code_block);
- }
- }
-
- self.visit_item_recur(item)
- }
-}
-
-#[derive(Default)]
-struct Buffer {
- messages: Vec<String>,
- has_errors: bool,
-}
-
-struct BufferEmitter {
- buffer: Lrc<Lock<Buffer>>,
- fallback_bundle: LazyFallbackBundle,
-}
-
-impl Translate for BufferEmitter {
- fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
- None
- }
-
- fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
- &**self.fallback_bundle
- }
-}
-
-impl Emitter for BufferEmitter {
- fn emit_diagnostic(&mut self, diag: &Diagnostic) {
- let mut buffer = self.buffer.borrow_mut();
-
- let fluent_args = to_fluent_args(diag.args());
- let translated_main_message = self.translate_message(&diag.message[0].0, &fluent_args);
-
- buffer.messages.push(format!("error from rustc: {}", translated_main_message));
- if diag.is_error() {
- buffer.has_errors = true;
- }
- }
-
- fn source_map(&self) -> Option<&Lrc<SourceMap>> {
- None
- }
-}
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 7740c6d5b..057d2fdd9 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -56,7 +56,7 @@ impl crate::doctest::Tester for Tests {
}
pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
- if !cx.cache.effective_visibilities.is_directly_public(item.item_id.expect_def_id())
+ if !cx.cache.effective_visibilities.is_directly_public(cx.tcx, item.item_id.expect_def_id())
|| matches!(
*item.kind,
clean::StructFieldItem(_)
@@ -130,7 +130,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
);
}
} else if tests.found_tests > 0
- && !cx.cache.effective_visibilities.is_exported(item.item_id.expect_def_id())
+ && !cx.cache.effective_visibilities.is_exported(cx.tcx, item.item_id.expect_def_id())
{
cx.tcx.struct_span_lint_hir(
crate::lint::PRIVATE_DOC_TESTS,
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 8aa0abd36..37a28b6b7 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -402,6 +402,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
})
.and_then(|self_id| match tcx.def_kind(self_id) {
DefKind::Impl => self.def_id_to_res(self_id),
+ DefKind::Use => None,
def_kind => Some(Res::Def(def_kind, self_id)),
})
}
@@ -1772,7 +1773,6 @@ fn resolution_failure(
// Otherwise, it must be an associated item or variant
let res = partial_res.expect("None case was handled by `last_found_module`");
- let name = res.name(tcx);
let kind = match res {
Res::Def(kind, _) => Some(kind),
Res::Primitive(_) => None,
@@ -1814,6 +1814,7 @@ fn resolution_failure(
} else {
"associated item"
};
+ let name = res.name(tcx);
let note = format!(
"the {} `{}` has no {} named `{}`",
res.descr(),
@@ -1893,7 +1894,7 @@ fn disambiguator_error(
diag_info.link_range = disambiguator_range;
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, _sp| {
let msg = format!(
- "see {}/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators",
+ "see {}/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators",
crate::DOC_RUST_LANG_ORG_CHANNEL
);
diag.note(&msg);
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 6b699c790..d57f981d5 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -8,7 +8,7 @@ use crate::formats::cache::Cache;
use crate::visit::DocVisitor;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::ty::{self, DefIdTree};
use rustc_span::symbol::sym;
@@ -25,7 +25,9 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
synth.impls
});
- let prims: FxHashSet<PrimitiveType> = krate.primitives.iter().map(|p| p.1).collect();
+ let local_crate = ExternalCrate { crate_num: LOCAL_CRATE };
+ let prims: FxHashSet<PrimitiveType> =
+ local_crate.primitives(cx.tcx).iter().map(|p| p.1).collect();
let crate_items = {
let mut coll = ItemCollector::new();
diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs
new file mode 100644
index 000000000..97031c4f0
--- /dev/null
+++ b/src/librustdoc/passes/lint.rs
@@ -0,0 +1,33 @@
+//! Runs several rustdoc lints, consolidating them into a single pass for
+//! efficiency and simplicity.
+
+mod bare_urls;
+mod check_code_block_syntax;
+mod html_tags;
+
+use super::Pass;
+use crate::clean::*;
+use crate::core::DocContext;
+use crate::visit::DocVisitor;
+
+pub(crate) const RUN_LINTS: Pass =
+ Pass { name: "run-lints", run: run_lints, description: "runs some of rustdoc's lints" };
+
+struct Linter<'a, 'tcx> {
+ cx: &'a mut DocContext<'tcx>,
+}
+
+pub(crate) fn run_lints(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
+ Linter { cx }.visit_crate(&krate);
+ krate
+}
+
+impl<'a, 'tcx> DocVisitor for Linter<'a, 'tcx> {
+ fn visit_item(&mut self, item: &Item) {
+ bare_urls::visit_item(self.cx, item);
+ check_code_block_syntax::visit_item(self.cx, item);
+ html_tags::visit_item(self.cx, item);
+
+ self.visit_item_recur(item)
+ }
+}
diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs
new file mode 100644
index 000000000..423230cfe
--- /dev/null
+++ b/src/librustdoc/passes/lint/bare_urls.rs
@@ -0,0 +1,89 @@
+//! Detects links that are not linkified, e.g., in Markdown such as `Go to https://example.com/.`
+//! Suggests wrapping the link with angle brackets: `Go to <https://example.com/>.` to linkify it.
+
+use crate::clean::*;
+use crate::core::DocContext;
+use crate::html::markdown::main_body_opts;
+use crate::passes::source_span_for_markdown_range;
+use core::ops::Range;
+use pulldown_cmark::{Event, Parser, Tag};
+use regex::Regex;
+use rustc_errors::Applicability;
+use std::mem;
+use std::sync::LazyLock;
+
+pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) {
+ let Some(hir_id) = DocContext::as_local_hir_id(cx.tcx, item.item_id)
+ else {
+ // If non-local, no need to check anything.
+ return;
+ };
+ let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
+ if !dox.is_empty() {
+ let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range<usize>| {
+ let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs)
+ .unwrap_or_else(|| item.attr_span(cx.tcx));
+ cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| {
+ lint.note("bare URLs are not automatically turned into clickable links")
+ .span_suggestion(
+ sp,
+ "use an automatic link instead",
+ format!("<{}>", url),
+ Applicability::MachineApplicable,
+ )
+ });
+ };
+
+ let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
+
+ while let Some((event, range)) = p.next() {
+ match event {
+ Event::Text(s) => find_raw_urls(cx, &s, range, &report_diag),
+ // We don't want to check the text inside code blocks or links.
+ Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link(..))) => {
+ while let Some((event, _)) = p.next() {
+ match event {
+ Event::End(end)
+ if mem::discriminant(&end) == mem::discriminant(&tag) =>
+ {
+ break;
+ }
+ _ => {}
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+}
+
+static URL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
+ Regex::new(concat!(
+ r"https?://", // url scheme
+ r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains
+ r"[a-zA-Z]{2,63}", // root domain
+ r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)" // optional query or url fragments
+ ))
+ .expect("failed to build regex")
+});
+
+fn find_raw_urls(
+ cx: &DocContext<'_>,
+ text: &str,
+ range: Range<usize>,
+ f: &impl Fn(&DocContext<'_>, &str, &str, Range<usize>),
+) {
+ trace!("looking for raw urls in {}", text);
+ // For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
+ for match_ in URL_REGEX.find_iter(text) {
+ let url = match_.as_str();
+ let url_range = match_.range();
+ f(
+ cx,
+ "this URL is not a hyperlink",
+ url,
+ Range { start: range.start + url_range.start, end: range.start + url_range.end },
+ );
+ }
+}
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
new file mode 100644
index 000000000..5aa4f238b
--- /dev/null
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -0,0 +1,170 @@
+//! Validates syntax inside Rust code blocks (\`\`\`rust).
+use rustc_data_structures::sync::{Lock, Lrc};
+use rustc_errors::{
+ emitter::Emitter,
+ translation::{to_fluent_args, Translate},
+ Applicability, Diagnostic, Handler, LazyFallbackBundle,
+};
+use rustc_parse::parse_stream_from_source_str;
+use rustc_session::parse::ParseSess;
+use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
+use rustc_span::source_map::{FilePathMapping, SourceMap};
+use rustc_span::{FileName, InnerSpan, DUMMY_SP};
+
+use crate::clean;
+use crate::core::DocContext;
+use crate::html::markdown::{self, RustCodeBlock};
+use crate::passes::source_span_for_markdown_range;
+
+pub(crate) fn visit_item(cx: &DocContext<'_>, item: &clean::Item) {
+ if let Some(dox) = &item.attrs.collapsed_doc_value() {
+ let sp = item.attr_span(cx.tcx);
+ let extra =
+ crate::html::markdown::ExtraInfo::new_did(cx.tcx, item.item_id.expect_def_id(), sp);
+ for code_block in markdown::rust_code_blocks(dox, &extra) {
+ check_rust_syntax(cx, item, dox, code_block);
+ }
+ }
+}
+
+fn check_rust_syntax(
+ cx: &DocContext<'_>,
+ item: &clean::Item,
+ dox: &str,
+ code_block: RustCodeBlock,
+) {
+ let buffer = Lrc::new(Lock::new(Buffer::default()));
+ let fallback_bundle =
+ rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
+ let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle };
+
+ let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+ let handler = Handler::with_emitter(false, None, Box::new(emitter));
+ let source = dox[code_block.code].to_owned();
+ let sess = ParseSess::with_span_handler(handler, sm);
+
+ let edition = code_block.lang_string.edition.unwrap_or_else(|| cx.tcx.sess.edition());
+ let expn_data =
+ ExpnData::default(ExpnKind::AstPass(AstPass::TestHarness), DUMMY_SP, edition, None, None);
+ let expn_id = cx.tcx.with_stable_hashing_context(|hcx| LocalExpnId::fresh(expn_data, hcx));
+ let span = DUMMY_SP.fresh_expansion(expn_id);
+
+ let is_empty = rustc_driver::catch_fatal_errors(|| {
+ parse_stream_from_source_str(
+ FileName::Custom(String::from("doctest")),
+ source,
+ &sess,
+ Some(span),
+ )
+ .is_empty()
+ })
+ .unwrap_or(false);
+ let buffer = buffer.borrow();
+
+ if !buffer.has_errors && !is_empty {
+ // No errors in a non-empty program.
+ return;
+ }
+
+ let Some(local_id) = item.item_id.as_def_id().and_then(|x| x.as_local())
+ else {
+ // We don't need to check the syntax for other crates so returning
+ // without doing anything should not be a problem.
+ return;
+ };
+
+ let hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id);
+ let empty_block = code_block.lang_string == Default::default() && code_block.is_fenced;
+ let is_ignore = code_block.lang_string.ignore != markdown::Ignore::None;
+
+ // The span and whether it is precise or not.
+ let (sp, precise_span) =
+ match source_span_for_markdown_range(cx.tcx, dox, &code_block.range, &item.attrs) {
+ Some(sp) => (sp, true),
+ None => (item.attr_span(cx.tcx), false),
+ };
+
+ let msg = if buffer.has_errors {
+ "could not parse code block as Rust code"
+ } else {
+ "Rust code block is empty"
+ };
+
+ // Finally build and emit the completed diagnostic.
+ // All points of divergence have been handled earlier so this can be
+ // done the same way whether the span is precise or not.
+ cx.tcx.struct_span_lint_hir(crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, msg, |lint| {
+ let explanation = if is_ignore {
+ "`ignore` code blocks require valid Rust code for syntax highlighting; \
+ mark blocks that do not contain Rust code as text"
+ } else {
+ "mark blocks that do not contain Rust code as text"
+ };
+
+ if precise_span {
+ if is_ignore {
+ // giving an accurate suggestion is hard because `ignore` might not have come first in the list.
+ // just give a `help` instead.
+ lint.span_help(
+ sp.from_inner(InnerSpan::new(0, 3)),
+ &format!("{}: ```text", explanation),
+ );
+ } else if empty_block {
+ lint.span_suggestion(
+ sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(),
+ explanation,
+ "text",
+ Applicability::MachineApplicable,
+ );
+ }
+ } else if empty_block || is_ignore {
+ lint.help(&format!("{}: ```text", explanation));
+ }
+
+ // FIXME(#67563): Provide more context for these errors by displaying the spans inline.
+ for message in buffer.messages.iter() {
+ lint.note(message);
+ }
+
+ lint
+ });
+}
+
+#[derive(Default)]
+struct Buffer {
+ messages: Vec<String>,
+ has_errors: bool,
+}
+
+struct BufferEmitter {
+ buffer: Lrc<Lock<Buffer>>,
+ fallback_bundle: LazyFallbackBundle,
+}
+
+impl Translate for BufferEmitter {
+ fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+ None
+ }
+
+ fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+ &**self.fallback_bundle
+ }
+}
+
+impl Emitter for BufferEmitter {
+ fn emit_diagnostic(&mut self, diag: &Diagnostic) {
+ let mut buffer = self.buffer.borrow_mut();
+
+ let fluent_args = to_fluent_args(diag.args());
+ let translated_main_message = self.translate_message(&diag.message[0].0, &fluent_args);
+
+ buffer.messages.push(format!("error from rustc: {}", translated_main_message));
+ if diag.is_error() {
+ buffer.has_errors = true;
+ }
+ }
+
+ fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+ None
+ }
+}
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs
index a89ed7c7e..070c0aab5 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/lint/html_tags.rs
@@ -1,9 +1,8 @@
//! Detects invalid HTML (like an unclosed `<span>`) in doc comments.
-use super::Pass;
use crate::clean::*;
use crate::core::DocContext;
use crate::html::markdown::main_body_opts;
-use crate::visit::DocVisitor;
+use crate::passes::source_span_for_markdown_range;
use pulldown_cmark::{BrokenLink, Event, LinkType, Parser, Tag};
@@ -11,20 +10,150 @@ use std::iter::Peekable;
use std::ops::Range;
use std::str::CharIndices;
-pub(crate) const CHECK_INVALID_HTML_TAGS: Pass = Pass {
- name: "check-invalid-html-tags",
- run: check_invalid_html_tags,
- description: "detects invalid HTML tags in doc comments",
-};
+pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
+ let tcx = cx.tcx;
+ let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id)
+ // If non-local, no need to check anything.
+ else { return };
+ let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
+ if !dox.is_empty() {
+ let report_diag = |msg: &str, range: &Range<usize>, is_open_tag: bool| {
+ let sp = match source_span_for_markdown_range(tcx, &dox, range, &item.attrs) {
+ Some(sp) => sp,
+ None => item.attr_span(tcx),
+ };
+ tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, msg, |lint| {
+ use rustc_lint_defs::Applicability;
+ // If a tag looks like `<this>`, it might actually be a generic.
+ // We don't try to detect stuff `<like, this>` because that's not valid HTML,
+ // and we don't try to detect stuff `<like this>` because that's not valid Rust.
+ let mut generics_end = range.end;
+ if let Some(Some(mut generics_start)) = (is_open_tag
+ && dox[..generics_end].ends_with('>'))
+ .then(|| extract_path_backwards(&dox, range.start))
+ {
+ while generics_start != 0
+ && generics_end < dox.len()
+ && dox.as_bytes()[generics_start - 1] == b'<'
+ && dox.as_bytes()[generics_end] == b'>'
+ {
+ generics_end += 1;
+ generics_start -= 1;
+ if let Some(new_start) = extract_path_backwards(&dox, generics_start) {
+ generics_start = new_start;
+ }
+ if let Some(new_end) = extract_path_forward(&dox, generics_end) {
+ generics_end = new_end;
+ }
+ }
+ if let Some(new_end) = extract_path_forward(&dox, generics_end) {
+ generics_end = new_end;
+ }
+ let generics_sp = match source_span_for_markdown_range(
+ tcx,
+ &dox,
+ &(generics_start..generics_end),
+ &item.attrs,
+ ) {
+ Some(sp) => sp,
+ None => item.attr_span(tcx),
+ };
+ // Sometimes, we only extract part of a path. For example, consider this:
+ //
+ // <[u32] as IntoIter<u32>>::Item
+ // ^^^^^ unclosed HTML tag `u32`
+ //
+ // We don't have any code for parsing fully-qualified trait paths.
+ // In theory, we could add it, but doing it correctly would require
+ // parsing the entire path grammar, which is problematic because of
+ // overlap between the path grammar and Markdown.
+ //
+ // The example above shows that ambiguity. Is `[u32]` intended to be an
+ // intra-doc link to the u32 primitive, or is it intended to be a slice?
+ //
+ // If the below conditional were removed, we would suggest this, which is
+ // not what the user probably wants.
+ //
+ // <[u32] as `IntoIter<u32>`>::Item
+ //
+ // We know that the user actually wants to wrap the whole thing in a code
+ // block, but the only reason we know that is because `u32` does not, in
+ // fact, implement IntoIter. If the example looks like this:
+ //
+ // <[Vec<i32>] as IntoIter<i32>::Item
+ //
+ // The ideal fix would be significantly different.
+ if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
+ || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
+ {
+ return lint;
+ }
+ // multipart form is chosen here because ``Vec<i32>`` would be confusing.
+ lint.multipart_suggestion(
+ "try marking as source code",
+ vec![
+ (generics_sp.shrink_to_lo(), String::from("`")),
+ (generics_sp.shrink_to_hi(), String::from("`")),
+ ],
+ Applicability::MaybeIncorrect,
+ );
+ }
-struct InvalidHtmlTagsLinter<'a, 'tcx> {
- cx: &'a mut DocContext<'tcx>,
-}
+ lint
+ });
+ };
+
+ let mut tags = Vec::new();
+ let mut is_in_comment = None;
+ let mut in_code_block = false;
+
+ let link_names = item.link_names(&cx.cache);
-pub(crate) fn check_invalid_html_tags(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
- let mut coll = InvalidHtmlTagsLinter { cx };
- coll.visit_crate(&krate);
- krate
+ let mut replacer = |broken_link: BrokenLink<'_>| {
+ if let Some(link) =
+ link_names.iter().find(|link| *link.original_text == *broken_link.reference)
+ {
+ Some((link.href.as_str().into(), link.new_text.as_str().into()))
+ } else if matches!(
+ &broken_link.link_type,
+ LinkType::Reference | LinkType::ReferenceUnknown
+ ) {
+ // If the link is shaped [like][this], suppress any broken HTML in the [this] part.
+ // The `broken_intra_doc_links` will report typos in there anyway.
+ Some((
+ broken_link.reference.to_string().into(),
+ broken_link.reference.to_string().into(),
+ ))
+ } else {
+ None
+ }
+ };
+
+ let p = Parser::new_with_broken_link_callback(&dox, main_body_opts(), Some(&mut replacer))
+ .into_offset_iter();
+
+ for (event, range) in p {
+ match event {
+ Event::Start(Tag::CodeBlock(_)) => in_code_block = true,
+ Event::Html(text) if !in_code_block => {
+ extract_tags(&mut tags, &text, range, &mut is_in_comment, &report_diag)
+ }
+ Event::End(Tag::CodeBlock(_)) => in_code_block = false,
+ _ => {}
+ }
+ }
+
+ for (tag, range) in tags.iter().filter(|(t, _)| {
+ let t = t.to_lowercase();
+ !ALLOWED_UNCLOSED.contains(&t.as_str())
+ }) {
+ report_diag(&format!("unclosed HTML tag `{}`", tag), range, true);
+ }
+
+ if let Some(range) = is_in_comment {
+ report_diag("Unclosed HTML comment", &range, false);
+ }
+ }
}
const ALLOWED_UNCLOSED: &[&str] = &[
@@ -276,155 +405,3 @@ fn extract_tags(
}
}
}
-
-impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
- fn visit_item(&mut self, item: &Item) {
- let tcx = self.cx.tcx;
- let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id)
- // If non-local, no need to check anything.
- else { return };
- let dox = item.attrs.collapsed_doc_value().unwrap_or_default();
- if !dox.is_empty() {
- let report_diag = |msg: &str, range: &Range<usize>, is_open_tag: bool| {
- let sp = match super::source_span_for_markdown_range(tcx, &dox, range, &item.attrs)
- {
- Some(sp) => sp,
- None => item.attr_span(tcx),
- };
- tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, msg, |lint| {
- use rustc_lint_defs::Applicability;
- // If a tag looks like `<this>`, it might actually be a generic.
- // We don't try to detect stuff `<like, this>` because that's not valid HTML,
- // and we don't try to detect stuff `<like this>` because that's not valid Rust.
- let mut generics_end = range.end;
- if let Some(Some(mut generics_start)) = (is_open_tag
- && dox[..generics_end].ends_with('>'))
- .then(|| extract_path_backwards(&dox, range.start))
- {
- while generics_start != 0
- && generics_end < dox.len()
- && dox.as_bytes()[generics_start - 1] == b'<'
- && dox.as_bytes()[generics_end] == b'>'
- {
- generics_end += 1;
- generics_start -= 1;
- if let Some(new_start) = extract_path_backwards(&dox, generics_start) {
- generics_start = new_start;
- }
- if let Some(new_end) = extract_path_forward(&dox, generics_end) {
- generics_end = new_end;
- }
- }
- if let Some(new_end) = extract_path_forward(&dox, generics_end) {
- generics_end = new_end;
- }
- let generics_sp = match super::source_span_for_markdown_range(
- tcx,
- &dox,
- &(generics_start..generics_end),
- &item.attrs,
- ) {
- Some(sp) => sp,
- None => item.attr_span(tcx),
- };
- // Sometimes, we only extract part of a path. For example, consider this:
- //
- // <[u32] as IntoIter<u32>>::Item
- // ^^^^^ unclosed HTML tag `u32`
- //
- // We don't have any code for parsing fully-qualified trait paths.
- // In theory, we could add it, but doing it correctly would require
- // parsing the entire path grammar, which is problematic because of
- // overlap between the path grammar and Markdown.
- //
- // The example above shows that ambiguity. Is `[u32]` intended to be an
- // intra-doc link to the u32 primitive, or is it intended to be a slice?
- //
- // If the below conditional were removed, we would suggest this, which is
- // not what the user probably wants.
- //
- // <[u32] as `IntoIter<u32>`>::Item
- //
- // We know that the user actually wants to wrap the whole thing in a code
- // block, but the only reason we know that is because `u32` does not, in
- // fact, implement IntoIter. If the example looks like this:
- //
- // <[Vec<i32>] as IntoIter<i32>::Item
- //
- // The ideal fix would be significantly different.
- if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
- || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
- {
- return lint;
- }
- // multipart form is chosen here because ``Vec<i32>`` would be confusing.
- lint.multipart_suggestion(
- "try marking as source code",
- vec![
- (generics_sp.shrink_to_lo(), String::from("`")),
- (generics_sp.shrink_to_hi(), String::from("`")),
- ],
- Applicability::MaybeIncorrect,
- );
- }
-
- lint
- });
- };
-
- let mut tags = Vec::new();
- let mut is_in_comment = None;
- let mut in_code_block = false;
-
- let link_names = item.link_names(&self.cx.cache);
-
- let mut replacer = |broken_link: BrokenLink<'_>| {
- if let Some(link) =
- link_names.iter().find(|link| *link.original_text == *broken_link.reference)
- {
- Some((link.href.as_str().into(), link.new_text.as_str().into()))
- } else if matches!(
- &broken_link.link_type,
- LinkType::Reference | LinkType::ReferenceUnknown
- ) {
- // If the link is shaped [like][this], suppress any broken HTML in the [this] part.
- // The `broken_intra_doc_links` will report typos in there anyway.
- Some((
- broken_link.reference.to_string().into(),
- broken_link.reference.to_string().into(),
- ))
- } else {
- None
- }
- };
-
- let p =
- Parser::new_with_broken_link_callback(&dox, main_body_opts(), Some(&mut replacer))
- .into_offset_iter();
-
- for (event, range) in p {
- match event {
- Event::Start(Tag::CodeBlock(_)) => in_code_block = true,
- Event::Html(text) if !in_code_block => {
- extract_tags(&mut tags, &text, range, &mut is_in_comment, &report_diag)
- }
- Event::End(Tag::CodeBlock(_)) => in_code_block = false,
- _ => {}
- }
- }
-
- for (tag, range) in tags.iter().filter(|(t, _)| {
- let t = t.to_lowercase();
- !ALLOWED_UNCLOSED.contains(&t.as_str())
- }) {
- report_diag(&format!("unclosed HTML tag `{}`", tag), range, true);
- }
-
- if let Some(range) = is_in_comment {
- report_diag("Unclosed HTML comment", &range, false);
- }
- }
-
- self.visit_item_recur(item)
- }
-}
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index f81b38ea3..634e70ec9 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -12,9 +12,6 @@ use crate::core::DocContext;
mod stripper;
pub(crate) use stripper::*;
-mod bare_urls;
-pub(crate) use self::bare_urls::CHECK_BARE_URLS;
-
mod strip_hidden;
pub(crate) use self::strip_hidden::STRIP_HIDDEN;
@@ -36,14 +33,11 @@ pub(crate) use self::check_doc_test_visibility::CHECK_DOC_TEST_VISIBILITY;
mod collect_trait_impls;
pub(crate) use self::collect_trait_impls::COLLECT_TRAIT_IMPLS;
-mod check_code_block_syntax;
-pub(crate) use self::check_code_block_syntax::CHECK_CODE_BLOCK_SYNTAX;
-
mod calculate_doc_coverage;
pub(crate) use self::calculate_doc_coverage::CALCULATE_DOC_COVERAGE;
-mod html_tags;
-pub(crate) use self::html_tags::CHECK_INVALID_HTML_TAGS;
+mod lint;
+pub(crate) use self::lint::RUN_LINTS;
/// A single pass over the cleaned documentation.
///
@@ -82,11 +76,9 @@ pub(crate) const PASSES: &[Pass] = &[
STRIP_PRIV_IMPORTS,
PROPAGATE_DOC_CFG,
COLLECT_INTRA_DOC_LINKS,
- CHECK_CODE_BLOCK_SYNTAX,
COLLECT_TRAIT_IMPLS,
CALCULATE_DOC_COVERAGE,
- CHECK_INVALID_HTML_TAGS,
- CHECK_BARE_URLS,
+ RUN_LINTS,
];
/// The list of passes run by default.
@@ -97,10 +89,8 @@ pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[
ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate),
ConditionalPass::new(STRIP_PRIV_IMPORTS, WhenDocumentPrivate),
ConditionalPass::always(COLLECT_INTRA_DOC_LINKS),
- ConditionalPass::always(CHECK_CODE_BLOCK_SYNTAX),
- ConditionalPass::always(CHECK_INVALID_HTML_TAGS),
ConditionalPass::always(PROPAGATE_DOC_CFG),
- ConditionalPass::always(CHECK_BARE_URLS),
+ ConditionalPass::always(RUN_LINTS),
];
/// The list of default passes run when `--doc-coverage` is passed to rustdoc.
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index 9914edf30..e07a788a7 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -27,6 +27,7 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
// strip all impls referencing stripped items
let mut stripper = ImplStripper {
+ tcx: cx.tcx,
retained: &retained,
cache: &cx.cache,
is_json_output,
diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs
index 85be8fa10..3bac5a8e5 100644
--- a/src/librustdoc/passes/strip_priv_imports.rs
+++ b/src/librustdoc/passes/strip_priv_imports.rs
@@ -11,6 +11,6 @@ pub(crate) const STRIP_PRIV_IMPORTS: Pass = Pass {
description: "strips all private import statements (`use`, `extern crate`) from a crate",
};
-pub(crate) fn strip_priv_imports(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate {
- ImportStripper.fold_crate(krate)
+pub(crate) fn strip_priv_imports(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
+ ImportStripper { tcx: cx.tcx }.fold_crate(krate)
}
diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs
index 450f69e15..8fc42462d 100644
--- a/src/librustdoc/passes/strip_private.rs
+++ b/src/librustdoc/passes/strip_private.rs
@@ -26,12 +26,14 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) ->
effective_visibilities: &cx.cache.effective_visibilities,
update_retained: true,
is_json_output,
+ tcx: cx.tcx,
};
- krate = ImportStripper.fold_crate(stripper.fold_crate(krate));
+ krate = ImportStripper { tcx: cx.tcx }.fold_crate(stripper.fold_crate(krate));
}
// strip all impls referencing private items
let mut stripper = ImplStripper {
+ tcx: cx.tcx,
retained: &retained,
cache: &cx.cache,
is_json_output,
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 0089ce63d..995fb5dcc 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -1,19 +1,20 @@
//! A collection of utility functions for the `strip_*` passes.
use rustc_hir::def_id::DefId;
-use rustc_middle::middle::privacy::EffectiveVisibilities;
+use rustc_middle::ty::{TyCtxt, Visibility};
use rustc_span::symbol::sym;
-
use std::mem;
use crate::clean::{self, Item, ItemId, ItemIdSet, NestedAttributesExt};
use crate::fold::{strip_item, DocFolder};
use crate::formats::cache::Cache;
+use crate::visit_lib::RustdocEffectiveVisibilities;
-pub(crate) struct Stripper<'a> {
+pub(crate) struct Stripper<'a, 'tcx> {
pub(crate) retained: &'a mut ItemIdSet,
- pub(crate) effective_visibilities: &'a EffectiveVisibilities<DefId>,
+ pub(crate) effective_visibilities: &'a RustdocEffectiveVisibilities,
pub(crate) update_retained: bool,
pub(crate) is_json_output: bool,
+ pub(crate) tcx: TyCtxt<'tcx>,
}
// We need to handle this differently for the JSON output because some non exported items could
@@ -21,18 +22,19 @@ pub(crate) struct Stripper<'a> {
// are in the public API, which is not enough.
#[inline]
fn is_item_reachable(
+ tcx: TyCtxt<'_>,
is_json_output: bool,
- effective_visibilities: &EffectiveVisibilities<DefId>,
+ effective_visibilities: &RustdocEffectiveVisibilities,
item_id: ItemId,
) -> bool {
if is_json_output {
- effective_visibilities.is_reachable(item_id.expect_def_id())
+ effective_visibilities.is_reachable(tcx, item_id.expect_def_id())
} else {
- effective_visibilities.is_exported(item_id.expect_def_id())
+ effective_visibilities.is_exported(tcx, item_id.expect_def_id())
}
}
-impl<'a> DocFolder for Stripper<'a> {
+impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
match *i.kind {
clean::StrippedItem(..) => {
@@ -66,7 +68,12 @@ impl<'a> DocFolder for Stripper<'a> {
| clean::ForeignTypeItem => {
let item_id = i.item_id;
if item_id.is_local()
- && !is_item_reachable(self.is_json_output, self.effective_visibilities, item_id)
+ && !is_item_reachable(
+ self.tcx,
+ self.is_json_output,
+ self.effective_visibilities,
+ item_id,
+ )
{
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
return None;
@@ -74,13 +81,13 @@ impl<'a> DocFolder for Stripper<'a> {
}
clean::StructFieldItem(..) => {
- if !i.visibility.is_public() {
+ if i.visibility(self.tcx) != Some(Visibility::Public) {
return Some(strip_item(i));
}
}
clean::ModuleItem(..) => {
- if i.item_id.is_local() && !i.visibility.is_public() {
+ if i.item_id.is_local() && i.visibility(self.tcx) != Some(Visibility::Public) {
debug!("Stripper: stripping module {:?}", i.name);
let old = mem::replace(&mut self.update_retained, false);
let ret = strip_item(self.fold_item_recur(i));
@@ -146,14 +153,15 @@ impl<'a> DocFolder for Stripper<'a> {
}
/// This stripper discards all impls which reference stripped items
-pub(crate) struct ImplStripper<'a> {
+pub(crate) struct ImplStripper<'a, 'tcx> {
+ pub(crate) tcx: TyCtxt<'tcx>,
pub(crate) retained: &'a ItemIdSet,
pub(crate) cache: &'a Cache,
pub(crate) is_json_output: bool,
pub(crate) document_private: bool,
}
-impl<'a> ImplStripper<'a> {
+impl<'a> ImplStripper<'a, '_> {
#[inline]
fn should_keep_impl(&self, item: &Item, for_def_id: DefId) -> bool {
if !for_def_id.is_local() || self.retained.contains(&for_def_id.into()) {
@@ -161,7 +169,7 @@ impl<'a> ImplStripper<'a> {
} else if self.is_json_output {
// If the "for" item is exported and the impl block isn't `#[doc(hidden)]`, then we
// need to keep it.
- self.cache.effective_visibilities.is_exported(for_def_id)
+ self.cache.effective_visibilities.is_exported(self.tcx, for_def_id)
&& !item.attrs.lists(sym::doc).has_word(sym::hidden)
} else {
false
@@ -169,7 +177,7 @@ impl<'a> ImplStripper<'a> {
}
}
-impl<'a> DocFolder for ImplStripper<'a> {
+impl<'a> DocFolder for ImplStripper<'a, '_> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
if let clean::ImplItem(ref imp) = *i.kind {
// Impl blocks can be skipped if they are: empty; not a trait impl; and have no
@@ -185,6 +193,7 @@ impl<'a> DocFolder for ImplStripper<'a> {
let item_id = i.item_id;
item_id.is_local()
&& !is_item_reachable(
+ self.tcx,
self.is_json_output,
&self.cache.effective_visibilities,
item_id,
@@ -229,12 +238,16 @@ impl<'a> DocFolder for ImplStripper<'a> {
}
/// This stripper discards all private import statements (`use`, `extern crate`)
-pub(crate) struct ImportStripper;
+pub(crate) struct ImportStripper<'tcx> {
+ pub(crate) tcx: TyCtxt<'tcx>,
+}
-impl DocFolder for ImportStripper {
+impl<'tcx> DocFolder for ImportStripper<'tcx> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
match *i.kind {
- clean::ExternCrateItem { .. } | clean::ImportItem(..) if !i.visibility.is_public() => {
+ clean::ExternCrateItem { .. } | clean::ImportItem(..)
+ if i.visibility(self.tcx) != Some(Visibility::Public) =>
+ {
None
}
_ => Some(self.fold_item_recur(i)),
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index dfa6ba38b..f2ee99cd9 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -110,6 +110,7 @@ pub(crate) struct CallData {
pub(crate) url: String,
pub(crate) display_name: String,
pub(crate) edition: Edition,
+ pub(crate) is_bin: bool,
}
pub(crate) type FnCallLocations = FxHashMap<PathBuf, CallData>;
@@ -122,6 +123,7 @@ struct FindCalls<'a, 'tcx> {
cx: Context<'tcx>,
target_crates: Vec<CrateNum>,
calls: &'a mut AllCallLocations,
+ bin_crate: bool,
}
impl<'a, 'tcx> Visitor<'tcx> for FindCalls<'a, 'tcx>
@@ -245,7 +247,9 @@ where
let mk_call_data = || {
let display_name = file_path.display().to_string();
let edition = call_span.edition();
- CallData { locations: Vec::new(), url, display_name, edition }
+ let is_bin = self.bin_crate;
+
+ CallData { locations: Vec::new(), url, display_name, edition, is_bin }
};
let fn_key = tcx.def_path_hash(*def_id);
@@ -274,6 +278,7 @@ pub(crate) fn run(
cache: formats::cache::Cache,
tcx: TyCtxt<'_>,
options: ScrapeExamplesOptions,
+ bin_crate: bool,
) -> interface::Result<()> {
let inner = move || -> Result<(), String> {
// Generates source files for examples
@@ -300,7 +305,8 @@ pub(crate) fn run(
// Run call-finder on all items
let mut calls = FxHashMap::default();
- let mut finder = FindCalls { calls: &mut calls, tcx, map: tcx.hir(), cx, target_crates };
+ let mut finder =
+ FindCalls { calls: &mut calls, tcx, map: tcx.hir(), cx, target_crates, bin_crate };
tcx.hir().visit_all_item_likes_in_crate(&mut finder);
// The visitor might have found a type error, which we need to
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 06dffce55..22068ebe0 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -7,15 +7,14 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::Node;
use rustc_hir::CRATE_HIR_ID;
-use rustc_middle::middle::privacy::Level;
-use rustc_middle::ty::{TyCtxt, Visibility};
+use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span;
use std::mem;
-use crate::clean::{self, cfg::Cfg, AttributesExt, NestedAttributesExt};
+use crate::clean::{cfg::Cfg, AttributesExt, NestedAttributesExt};
use crate::core;
/// This module is used to store stuff from Rust's AST in a more convenient
@@ -26,8 +25,8 @@ pub(crate) struct Module<'hir> {
pub(crate) where_inner: Span,
pub(crate) mods: Vec<Module<'hir>>,
pub(crate) id: hir::HirId,
- // (item, renamed)
- pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>)>,
+ // (item, renamed, import_id)
+ pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>, Option<hir::HirId>)>,
pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
}
@@ -94,6 +93,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
hir::CRATE_HIR_ID,
self.cx.tcx.hir().root_module(),
self.cx.tcx.crate_name(LOCAL_CRATE),
+ None,
);
// `#[macro_export] macro_rules!` items are reexported at the top level of the
@@ -114,7 +114,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
if self.cx.tcx.has_attr(def_id, sym::macro_export) {
if inserted.insert(def_id) {
let item = self.cx.tcx.hir().expect_item(local_def_id);
- top_level_module.items.push((item, None));
+ top_level_module.items.push((item, None, None));
}
}
}
@@ -156,6 +156,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
id: hir::HirId,
m: &'tcx hir::Mod<'tcx>,
name: Symbol,
+ parent_id: Option<hir::HirId>,
) -> Module<'tcx> {
let mut om = Module::new(name, id, m.spans.inner_span);
let def_id = self.cx.tcx.hir().local_def_id(id).to_def_id();
@@ -167,7 +168,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
continue;
}
- self.visit_item(item, None, &mut om);
+ self.visit_item(item, None, &mut om, parent_id);
}
for &i in m.item_ids {
let item = self.cx.tcx.hir().item(i);
@@ -175,7 +176,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
// Later passes in rustdoc will de-duplicate by name and kind, so if glob-
// imported items appear last, then they'll be the ones that get discarded.
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
- self.visit_item(item, None, &mut om);
+ self.visit_item(item, None, &mut om, parent_id);
}
}
self.inside_public_path = orig_inside_public_path;
@@ -221,23 +222,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
// made reachable by cross-crate inlining which we're checking here.
// (this is done here because we need to know this upfront).
if !res_did.is_local() && !is_no_inline {
- let attrs = clean::inline::load_attrs(self.cx, res_did);
- let self_is_hidden = attrs.lists(sym::doc).has_word(sym::hidden);
- if !self_is_hidden {
- if let Res::Def(kind, did) = res {
- if kind == DefKind::Mod {
- crate::visit_lib::LibEmbargoVisitor::new(self.cx).visit_mod(did)
- } else {
- // All items need to be handled here in case someone wishes to link
- // to them with intra-doc links
- self.cx.cache.effective_visibilities.set_public_at_level(
- did,
- || Visibility::Restricted(CRATE_DEF_ID),
- Level::Direct,
- );
- }
- }
- }
+ crate::visit_lib::lib_embargo_visit_item(self.cx, res_did);
return false;
}
@@ -246,7 +231,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
None => return false,
};
- let is_private = !self.cx.cache.effective_visibilities.is_directly_public(res_did);
+ let is_private =
+ !self.cx.cache.effective_visibilities.is_directly_public(self.cx.tcx, res_did);
let is_hidden = inherits_doc_hidden(self.cx.tcx, res_hir_id);
// Only inline if requested or if the item would otherwise be stripped.
@@ -263,14 +249,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let prev = mem::replace(&mut self.inlining, true);
for &i in m.item_ids {
let i = self.cx.tcx.hir().item(i);
- self.visit_item(i, None, om);
+ self.visit_item(i, None, om, Some(id));
}
self.inlining = prev;
true
}
Node::Item(it) if !glob => {
let prev = mem::replace(&mut self.inlining, true);
- self.visit_item(it, renamed, om);
+ self.visit_item(it, renamed, om, Some(id));
self.inlining = prev;
true
}
@@ -291,6 +277,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
item: &'tcx hir::Item<'_>,
renamed: Option<Symbol>,
om: &mut Module<'tcx>,
+ parent_id: Option<hir::HirId>,
) {
debug!("visiting item {:?}", item);
let name = renamed.unwrap_or(item.ident.name);
@@ -314,39 +301,40 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
hir::ItemKind::GlobalAsm(..) => {}
hir::ItemKind::Use(_, hir::UseKind::ListStem) => {}
hir::ItemKind::Use(path, kind) => {
- let is_glob = kind == hir::UseKind::Glob;
-
- // Struct and variant constructors and proc macro stubs always show up alongside
- // their definitions, we've already processed them so just discard these.
- if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = path.res {
- return;
- }
-
- let attrs = self.cx.tcx.hir().attrs(item.hir_id());
+ for &res in &path.res {
+ // Struct and variant constructors and proc macro stubs always show up alongside
+ // their definitions, we've already processed them so just discard these.
+ if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
+ continue;
+ }
- // If there was a private module in the current path then don't bother inlining
- // anything as it will probably be stripped anyway.
- if is_pub && self.inside_public_path {
- let please_inline = attrs.iter().any(|item| match item.meta_item_list() {
- Some(ref list) if item.has_name(sym::doc) => {
- list.iter().any(|i| i.has_name(sym::inline))
+ let attrs = self.cx.tcx.hir().attrs(item.hir_id());
+
+ // If there was a private module in the current path then don't bother inlining
+ // anything as it will probably be stripped anyway.
+ if is_pub && self.inside_public_path {
+ let please_inline = attrs.iter().any(|item| match item.meta_item_list() {
+ Some(ref list) if item.has_name(sym::doc) => {
+ list.iter().any(|i| i.has_name(sym::inline))
+ }
+ _ => false,
+ });
+ let is_glob = kind == hir::UseKind::Glob;
+ let ident = if is_glob { None } else { Some(name) };
+ if self.maybe_inline_local(
+ item.hir_id(),
+ res,
+ ident,
+ is_glob,
+ om,
+ please_inline,
+ ) {
+ continue;
}
- _ => false,
- });
- let ident = if is_glob { None } else { Some(name) };
- if self.maybe_inline_local(
- item.hir_id(),
- path.res,
- ident,
- is_glob,
- om,
- please_inline,
- ) {
- return;
}
- }
- om.items.push((item, renamed))
+ om.items.push((item, renamed, parent_id))
+ }
}
hir::ItemKind::Macro(ref macro_def, _) => {
// `#[macro_export] macro_rules!` items are handled separately in `visit()`,
@@ -365,11 +353,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let nonexported = !self.cx.tcx.has_attr(def_id, sym::macro_export);
if is_macro_2_0 || nonexported || self.inlining {
- om.items.push((item, renamed));
+ om.items.push((item, renamed, None));
}
}
hir::ItemKind::Mod(ref m) => {
- om.mods.push(self.visit_mod_contents(item.hir_id(), m, name));
+ om.mods.push(self.visit_mod_contents(item.hir_id(), m, name, parent_id));
}
hir::ItemKind::Fn(..)
| hir::ItemKind::ExternCrate(..)
@@ -380,19 +368,19 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
| hir::ItemKind::OpaqueTy(..)
| hir::ItemKind::Static(..)
| hir::ItemKind::Trait(..)
- | hir::ItemKind::TraitAlias(..) => om.items.push((item, renamed)),
+ | hir::ItemKind::TraitAlias(..) => om.items.push((item, renamed, parent_id)),
hir::ItemKind::Const(..) => {
// Underscore constants do not correspond to a nameable item and
// so are never useful in documentation.
if name != kw::Underscore {
- om.items.push((item, renamed));
+ om.items.push((item, renamed, parent_id));
}
}
hir::ItemKind::Impl(impl_) => {
// Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
// them up regardless of where they're located.
if !self.inlining && impl_.of_trait.is_none() {
- om.items.push((item, None));
+ om.items.push((item, None, None));
}
}
}
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 70214e2ad..e490559b0 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -1,86 +1,74 @@
+use crate::core::DocContext;
use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_ID};
-use rustc_middle::middle::privacy::{EffectiveVisibilities, Level};
-use rustc_middle::ty::{TyCtxt, Visibility};
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::DefId;
+use rustc_middle::ty::TyCtxt;
// FIXME: this may not be exhaustive, but is sufficient for rustdocs current uses
+#[derive(Default)]
+pub(crate) struct RustdocEffectiveVisibilities {
+ extern_public: FxHashSet<DefId>,
+}
+
+macro_rules! define_method {
+ ($method:ident) => {
+ pub(crate) fn $method(&self, tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+ match def_id.as_local() {
+ Some(def_id) => tcx.effective_visibilities(()).$method(def_id),
+ None => self.extern_public.contains(&def_id),
+ }
+ }
+ };
+}
+
+impl RustdocEffectiveVisibilities {
+ define_method!(is_directly_public);
+ define_method!(is_exported);
+ define_method!(is_reachable);
+}
+
+pub(crate) fn lib_embargo_visit_item(cx: &mut DocContext<'_>, def_id: DefId) {
+ assert!(!def_id.is_local());
+ LibEmbargoVisitor {
+ tcx: cx.tcx,
+ extern_public: &mut cx.cache.effective_visibilities.extern_public,
+ visited_mods: Default::default(),
+ }
+ .visit_item(def_id)
+}
+
/// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
/// specific rustdoc annotations into account (i.e., `doc(hidden)`)
-pub(crate) struct LibEmbargoVisitor<'a, 'tcx> {
+struct LibEmbargoVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
// Effective visibilities for reachable nodes
- effective_visibilities: &'a mut EffectiveVisibilities<DefId>,
- // Previous level, None means unreachable
- prev_level: Option<Level>,
+ extern_public: &'a mut FxHashSet<DefId>,
// Keeps track of already visited modules, in case a module re-exports its parent
visited_mods: FxHashSet<DefId>,
}
-impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
- pub(crate) fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
- LibEmbargoVisitor {
- tcx: cx.tcx,
- effective_visibilities: &mut cx.cache.effective_visibilities,
- prev_level: Some(Level::Direct),
- visited_mods: FxHashSet::default(),
- }
- }
-
- pub(crate) fn visit_lib(&mut self, cnum: CrateNum) {
- let did = cnum.as_def_id();
- self.update(did, Some(Level::Direct));
- self.visit_mod(did);
- }
-
- // Updates node level and returns the updated level
- fn update(&mut self, did: DefId, level: Option<Level>) -> Option<Level> {
- let is_hidden = self.tcx.is_doc_hidden(did);
-
- let old_level = self.effective_visibilities.public_at_level(did);
- // Visibility levels can only grow
- if level > old_level && !is_hidden {
- self.effective_visibilities.set_public_at_level(
- did,
- || Visibility::Restricted(CRATE_DEF_ID),
- level.unwrap(),
- );
- level
- } else {
- old_level
- }
- }
-
- pub(crate) fn visit_mod(&mut self, def_id: DefId) {
+impl LibEmbargoVisitor<'_, '_> {
+ fn visit_mod(&mut self, def_id: DefId) {
if !self.visited_mods.insert(def_id) {
return;
}
for item in self.tcx.module_children(def_id).iter() {
if let Some(def_id) = item.res.opt_def_id() {
- if self.tcx.def_key(def_id).parent.map_or(false, |d| d == def_id.index)
- || item.vis.is_public()
- {
- self.visit_item(item.res);
+ if item.vis.is_public() {
+ self.visit_item(def_id);
}
}
}
}
- fn visit_item(&mut self, res: Res<!>) {
- let def_id = res.def_id();
- let vis = self.tcx.visibility(def_id);
- let inherited_item_level = if vis.is_public() { self.prev_level } else { None };
-
- let item_level = self.update(def_id, inherited_item_level);
-
- if let Res::Def(DefKind::Mod, _) = res {
- let orig_level = self.prev_level;
-
- self.prev_level = item_level;
- self.visit_mod(def_id);
- self.prev_level = orig_level;
+ fn visit_item(&mut self, def_id: DefId) {
+ if !self.tcx.is_doc_hidden(def_id) {
+ self.extern_public.insert(def_id);
+ if self.tcx.def_kind(def_id) == DefKind::Mod {
+ self.visit_mod(def_id);
+ }
}
}
}
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 4bc91fc40..1ee96b823 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -9,7 +9,7 @@ use std::path::PathBuf;
use serde::{Deserialize, Serialize};
/// rustdoc format-version.
-pub const FORMAT_VERSION: u32 = 22;
+pub const FORMAT_VERSION: u32 = 23;
/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
/// about the language items in the local crate, as well as info about external items to allow
@@ -53,7 +53,7 @@ pub struct ItemSummary {
/// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`).
///
/// Note that items can appear in multiple paths, and the one chosen is implementation
- /// defined. Currenty, this is the full path to where the item was defined. Eg
+ /// defined. Currently, this is the full path to where the item was defined. Eg
/// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`] is
/// `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change.
pub path: Vec<String>,
@@ -210,7 +210,6 @@ pub enum ItemKind {
Constant,
Trait,
TraitAlias,
- Method,
Impl,
Static,
ForeignType,
@@ -243,7 +242,6 @@ pub enum ItemEnum {
Trait(Trait),
TraitAlias(TraitAlias),
- Method(Method),
Impl(Impl),
Typedef(Typedef),
@@ -351,7 +349,7 @@ pub enum Variant {
/// A variant with unnamed fields.
///
/// Unlike most of json, `#[doc(hidden)]` fields will be given as `None`
- /// instead of being ommited, because order matters.
+ /// instead of being omitted, because order matters.
///
/// ```rust
/// enum Demo {
@@ -415,18 +413,12 @@ pub enum Abi {
Other(String),
}
+/// Represents a function (including methods and other associated functions)
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Function {
pub decl: FnDecl,
pub generics: Generics,
pub header: Header,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
-pub struct Method {
- pub decl: FnDecl,
- pub generics: Generics,
- pub header: Header,
pub has_body: bool,
}
@@ -623,6 +615,10 @@ pub struct FunctionPointer {
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct FnDecl {
+ /// List of argument names and their type.
+ ///
+ /// Note that not all names will be valid identifiers, as some of
+ /// them may be patterns.
pub inputs: Vec<(String, Type)>,
pub output: Option<Type>,
pub c_variadic: bool,
diff --git a/src/stage0.json b/src/stage0.json
index db7444839..a83754afa 100644
--- a/src/stage0.json
+++ b/src/stage0.json
@@ -17,292 +17,292 @@
"tool is executed."
],
"compiler": {
- "date": "2022-11-03",
- "version": "1.65.0"
+ "date": "2023-01-10",
+ "version": "1.66.1"
},
"rustfmt": null,
"checksums_sha256": {
- "dist/2022-11-03/cargo-1.65.0-aarch64-apple-darwin.tar.gz": "40858f3078b277165c191b6478c2aba7bf0010162273e28e9964404993eba188",
- "dist/2022-11-03/cargo-1.65.0-aarch64-apple-darwin.tar.xz": "71013b8d491a355d0b88a97c9c47e50817cf1b506fc8507cd644d2225ec76356",
- "dist/2022-11-03/cargo-1.65.0-aarch64-pc-windows-msvc.tar.gz": "5b5b684e028b9a024c137974a4121b355f016d644c635a6d0f4d29814cd1c9d9",
- "dist/2022-11-03/cargo-1.65.0-aarch64-pc-windows-msvc.tar.xz": "b32487855fb9bafc58c423d62b52d283af100ab8e8519ce8a0d406adbfe7ceaf",
- "dist/2022-11-03/cargo-1.65.0-aarch64-unknown-linux-gnu.tar.gz": "406d244def7ea78ed75ca4852498a1b632360626fb5fec69a8442b14ef04aee8",
- "dist/2022-11-03/cargo-1.65.0-aarch64-unknown-linux-gnu.tar.xz": "3fd483c0d58673ab69862824408c8a48612827ddcdeaaca0f8fbe5ca02214a4c",
- "dist/2022-11-03/cargo-1.65.0-aarch64-unknown-linux-musl.tar.gz": "43cb587b766a892d9c474f0a04417533d6c12e085ba07af8e27853d41afb4f91",
- "dist/2022-11-03/cargo-1.65.0-aarch64-unknown-linux-musl.tar.xz": "5e9880995c5a8f247a2d8ee143183f45feee1ec09bad5e147c837518f01591e4",
- "dist/2022-11-03/cargo-1.65.0-arm-unknown-linux-gnueabi.tar.gz": "25c783ec2a61c127215609ae5e45ca11de938cf8e1e163ccdd422be2b245414a",
- "dist/2022-11-03/cargo-1.65.0-arm-unknown-linux-gnueabi.tar.xz": "88b14f59d8dbc64c093100a2748f5392510b480ac4b05a816a85b50030b90db1",
- "dist/2022-11-03/cargo-1.65.0-arm-unknown-linux-gnueabihf.tar.gz": "1793a5773d24d6e4685870a6e47de3f764e74d35f85bdc0d3e888be0efce6a54",
- "dist/2022-11-03/cargo-1.65.0-arm-unknown-linux-gnueabihf.tar.xz": "e3b82e61a5bbf6338555716d8e925cd0a96e4fc0ae262dd04bec009a46aa6051",
- "dist/2022-11-03/cargo-1.65.0-armv7-unknown-linux-gnueabihf.tar.gz": "fcd2a151adebc87fddebb710d7c7606f0aa77245bb45ec05f8b600cd30008687",
- "dist/2022-11-03/cargo-1.65.0-armv7-unknown-linux-gnueabihf.tar.xz": "a27a726733230bff2807109fdd619ccd04d3e96e22ea53d3e24552524619ec2f",
- "dist/2022-11-03/cargo-1.65.0-i686-pc-windows-gnu.tar.gz": "894dc627e3d5a597ca8c6aa5d0ef55f2d9130b14dde19df193b41242e605a31f",
- "dist/2022-11-03/cargo-1.65.0-i686-pc-windows-gnu.tar.xz": "e462df98c630ab06196d27a2a631bbf12da40f8cb0d40028368205e1dcdbe978",
- "dist/2022-11-03/cargo-1.65.0-i686-pc-windows-msvc.tar.gz": "d8d9ec39ba20f8d0ad37a2c0791008631e6ac6efc419bc9543a65785db097c5a",
- "dist/2022-11-03/cargo-1.65.0-i686-pc-windows-msvc.tar.xz": "2994d66f1644a7a0d814cec9d619cca204adeb2af81cb03759f168044d9bf4ee",
- "dist/2022-11-03/cargo-1.65.0-i686-unknown-linux-gnu.tar.gz": "b58b88e7dbfc7b570df1ec0f7be75c318ad8e99ff1e66f4154827b2c81eee3d2",
- "dist/2022-11-03/cargo-1.65.0-i686-unknown-linux-gnu.tar.xz": "64d456a303d6f1edf0bd9807089aa71ef065705b9dd7d115faff5c2d431e78cd",
- "dist/2022-11-03/cargo-1.65.0-mips-unknown-linux-gnu.tar.gz": "602458e1f1669d0a0daf5edd0fb0f9aff24891357e2eda12fcef1b2bb56d95c9",
- "dist/2022-11-03/cargo-1.65.0-mips-unknown-linux-gnu.tar.xz": "f32903493610bb5b2302139bf37120159b848223cdc23da546e6fae7e8e6cbfc",
- "dist/2022-11-03/cargo-1.65.0-mips64-unknown-linux-gnuabi64.tar.gz": "b9a484868b89cc435dc65bc545ec89126d12a9a76a477a13263bcda2f1572f57",
- "dist/2022-11-03/cargo-1.65.0-mips64-unknown-linux-gnuabi64.tar.xz": "453e95cc057583057c2239539425a4e57d80e38ba00288f09d04fddcde2548af",
- "dist/2022-11-03/cargo-1.65.0-mips64el-unknown-linux-gnuabi64.tar.gz": "ca75879b45e7768b6be0d5809e41cc82783f9db4ce7f670966e665ed843a65e2",
- "dist/2022-11-03/cargo-1.65.0-mips64el-unknown-linux-gnuabi64.tar.xz": "594c03b8e6e6a7f3d38cf655591d63c24ed2ab5ce14ace41f1f2c1181c9c09ca",
- "dist/2022-11-03/cargo-1.65.0-mipsel-unknown-linux-gnu.tar.gz": "01ffeeaf5cd1837810580ba2fe7c74354cc25cb7a0a6858e815dfad6aa5e3fd8",
- "dist/2022-11-03/cargo-1.65.0-mipsel-unknown-linux-gnu.tar.xz": "a80ca689ce20508fddb6274e2e5f69a59a5b8e1a1272f840d6b1ca60f83dcccb",
- "dist/2022-11-03/cargo-1.65.0-powerpc-unknown-linux-gnu.tar.gz": "ac9c7bf7e7c38ef6a14e72ddad5abe9592ebbdd9d80c4c5ce59046fd790260a6",
- "dist/2022-11-03/cargo-1.65.0-powerpc-unknown-linux-gnu.tar.xz": "cc309119f4157f3cbdafe065d07bee7de5f262da998854e02b2d8f9f425dce73",
- "dist/2022-11-03/cargo-1.65.0-powerpc64-unknown-linux-gnu.tar.gz": "3aab12cb517b9d27feb0d43fd24834af627a4556bf8760937a77429fe9087592",
- "dist/2022-11-03/cargo-1.65.0-powerpc64-unknown-linux-gnu.tar.xz": "32fac316c0676e395fa3c87ad4222d3c70489278da4c6986ee30406df6e6eb4f",
- "dist/2022-11-03/cargo-1.65.0-powerpc64le-unknown-linux-gnu.tar.gz": "aad8a7e6df87d81e2e0c2913670547dc65672434c23d32811da307ec4b767f59",
- "dist/2022-11-03/cargo-1.65.0-powerpc64le-unknown-linux-gnu.tar.xz": "9393de910df7cd6947e380460a1144ac2373a36c776c7367a81212a51a92d9a7",
- "dist/2022-11-03/cargo-1.65.0-riscv64gc-unknown-linux-gnu.tar.gz": "913289a36696a53e642bd247d7d78920809c5db6300a3181064b62c82a0444b3",
- "dist/2022-11-03/cargo-1.65.0-riscv64gc-unknown-linux-gnu.tar.xz": "fdc9be1d0552179318c588e8eebebfa42fcf5eb65d58b93ba2949d9b5718b429",
- "dist/2022-11-03/cargo-1.65.0-s390x-unknown-linux-gnu.tar.gz": "ca3f9db0bf5bc244bdc225eccb54f9a0b2663ac92e374e33c7c8d6d9339f6b78",
- "dist/2022-11-03/cargo-1.65.0-s390x-unknown-linux-gnu.tar.xz": "bcddebbf39443e62d67e35b3c669677442a551dbfa1f172e2405368cc571e555",
- "dist/2022-11-03/cargo-1.65.0-x86_64-apple-darwin.tar.gz": "40cbbd62013130d5208435dc45d6c91703eb6a469b6d8eacf746eedc6974ccc0",
- "dist/2022-11-03/cargo-1.65.0-x86_64-apple-darwin.tar.xz": "906a656ea12808065da0702082fb08d010f0d51f61148887068ac44613c07ebc",
- "dist/2022-11-03/cargo-1.65.0-x86_64-pc-windows-gnu.tar.gz": "79819a7e5ade380a36cb7bebf8922034802891333bf85c1d0e194b9b70c7ff4a",
- "dist/2022-11-03/cargo-1.65.0-x86_64-pc-windows-gnu.tar.xz": "06f51741e03f9ba458fa774c705f078a5bba36f2f5a990e555c710a4b39a9eae",
- "dist/2022-11-03/cargo-1.65.0-x86_64-pc-windows-msvc.tar.gz": "2932be27a0ebea2d36a30c18b758a7f90582fcb8bc675a225d661e611e57afb9",
- "dist/2022-11-03/cargo-1.65.0-x86_64-pc-windows-msvc.tar.xz": "a0ef427322ac3f41d64f935655942a7dcf7e40bbc7d4f82600087f96d02de4c0",
- "dist/2022-11-03/cargo-1.65.0-x86_64-unknown-freebsd.tar.gz": "a896973695382f4c622b98544f6126c088b21d6a625c129131b113ac36d777a8",
- "dist/2022-11-03/cargo-1.65.0-x86_64-unknown-freebsd.tar.xz": "b12447bec51998ca618710de0f72fdf728c881de76dd28133ead22758be70de1",
- "dist/2022-11-03/cargo-1.65.0-x86_64-unknown-illumos.tar.gz": "a1f391d8d3a819e4c217ab6a12c864cd0af69255ca653566320dbef5eefe0769",
- "dist/2022-11-03/cargo-1.65.0-x86_64-unknown-illumos.tar.xz": "e357c8cc226a1985649c1bec88c1fe9bb0a860d01c530e5692726739fab3dfad",
- "dist/2022-11-03/cargo-1.65.0-x86_64-unknown-linux-gnu.tar.gz": "f7d67cf3b34a7d82fa2b22d42ad2aed20ee8f4be95ab97f88b8bf03a397217c2",
- "dist/2022-11-03/cargo-1.65.0-x86_64-unknown-linux-gnu.tar.xz": "82547aacaf42fc3c2970ec31b96751dfbeba3dffe1a042a3780bd670c29a89bf",
- "dist/2022-11-03/cargo-1.65.0-x86_64-unknown-linux-musl.tar.gz": "43a7154520914663c0d291284621e40cf116ad3b5fea6274ea7cfdd4b9e7368f",
- "dist/2022-11-03/cargo-1.65.0-x86_64-unknown-linux-musl.tar.xz": "7b2b3632205310b867d8d70403aa7ea3a879972033442628fa59483e4ecf0d8b",
- "dist/2022-11-03/cargo-1.65.0-x86_64-unknown-netbsd.tar.gz": "fc41c57eabf4a601bdfd78b8586f0e639404305ca0b61ad62284be4623394de3",
- "dist/2022-11-03/cargo-1.65.0-x86_64-unknown-netbsd.tar.xz": "1567ef1c6ca630fc03125cf4560dcb4d4d2cf1cdcd23ef8b1ad7ec7fa4881693",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-apple-darwin.tar.gz": "68316299635d2577af3b64a2de4839a107f6c33f92e9427d6127526d12ecf07f",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-apple-darwin.tar.xz": "c467c69df0821daebc02be91ac012e4e930ac8e9ef8bdeebf3f04cb5517cc7b0",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-apple-ios-sim.tar.gz": "34061a4772a1054803ea26ccddef78f8d4f654b6c00b328232df7fb4f68c0b20",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-apple-ios-sim.tar.xz": "28c94371a7e0f842bd75af8107e3e6c1e057a2500f1fb81fcc2436700559542f",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-apple-ios.tar.gz": "7707c1fd458a72cedbb62cd0060043eabe6d0f6b66f9d73f2453f502231df85e",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-apple-ios.tar.xz": "d47d58f2ab066002fea4f75184ae9ec1eede3a3636e4948d564c6511d2e85fb2",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-fuchsia.tar.gz": "b4798d4b55b8b8423a1cc870118d2972d057439bbfa2b80f28a83fb2ca242f74",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-fuchsia.tar.xz": "12f2213e0451336a6e9f35b13bf51bdbad445c53cad52cb86577b831d6fa5feb",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-linux-android.tar.gz": "a948302c50dc0960a1eeaf564cead55bb9d1228847e4c396a244e1f9cdc9a14d",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-linux-android.tar.xz": "aa7a9537f10b7551711c0a70d8f632ed6416f442749e508a1fc698a47eb34308",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-pc-windows-msvc.tar.gz": "c14710a87c532cd606955a7c3021a75d4f7a3be2cc05211452df6ae00b9205f5",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-pc-windows-msvc.tar.xz": "1aaa57c35d2a3b52123a02daf85e741b525721bbb2eaa5722388a1ddb9f6fe68",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-unknown-linux-gnu.tar.gz": "86eea00f31fc4cfe320624b38547d1850efb3c890ed00e73b39f725803c4c755",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-unknown-linux-gnu.tar.xz": "735b681c8a6e60925c76d6cc899e78b4cb4562ada24a1f265b2021c1faad78ad",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-unknown-linux-musl.tar.gz": "5136887db2170733bb40b18be597e0ac9474fac030d7344c4517b38b0c98c70a",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-unknown-linux-musl.tar.xz": "9ea488da40c347826cce7e238847c745ee566254bb1d077412673f8243fb1cd2",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-unknown-none-softfloat.tar.gz": "f9c09c55883181e09f5d169e210e8bc15d55c459b4c187e4987969429e076980",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-unknown-none-softfloat.tar.xz": "b52417af1f9ea204cc20c66f486c7233a1e1571243dd38630149b79b7ce2c825",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-unknown-none.tar.gz": "3be333d58f33e5790586b20b369bb1110e3241d14c42282720f80107d6e0df6b",
- "dist/2022-11-03/rust-std-1.65.0-aarch64-unknown-none.tar.xz": "8258b2773dc1688826c126e01b138be10c22a43137ebf091f0a1938fee8272f5",
- "dist/2022-11-03/rust-std-1.65.0-arm-linux-androideabi.tar.gz": "beffe3e8ce63cd9a2f8cf26cdd9dda2c1178d50c8612009e36ef3d40e845ea9c",
- "dist/2022-11-03/rust-std-1.65.0-arm-linux-androideabi.tar.xz": "5379cc9c176bc708bf3d8d01f101514267cd09cc055e9b68d741b40a0302c396",
- "dist/2022-11-03/rust-std-1.65.0-arm-unknown-linux-gnueabi.tar.gz": "0802275835c36a936031a1da78e11c8070e3fa7f699951977bc0463748805d07",
- "dist/2022-11-03/rust-std-1.65.0-arm-unknown-linux-gnueabi.tar.xz": "c8793e77ef43336bc372a7a5b4720d5449e92577c7875471c2bc40ddbfde4811",
- "dist/2022-11-03/rust-std-1.65.0-arm-unknown-linux-gnueabihf.tar.gz": "cbbd549a619cf13c413e1954ed8dca72939e583a34b59076e1fb034e4e04dc24",
- "dist/2022-11-03/rust-std-1.65.0-arm-unknown-linux-gnueabihf.tar.xz": "f7d5eb17dbe46ee9d3c4f9fcffc07b8e3311c747545402c8d3b5c43043f27288",
- "dist/2022-11-03/rust-std-1.65.0-arm-unknown-linux-musleabi.tar.gz": "90ee725d476587abfea627f3e6ebda3073f44fdc1af53d2fc2e71a27f7ad38d1",
- "dist/2022-11-03/rust-std-1.65.0-arm-unknown-linux-musleabi.tar.xz": "453a1443e4753611dc4e6969e50ad8d7984a31d1a457729a860599ed19b1de7a",
- "dist/2022-11-03/rust-std-1.65.0-arm-unknown-linux-musleabihf.tar.gz": "1b170a4206d7de4fdfae965c5d41b29f6d44f117c5ed8c691270d54ad82e98a4",
- "dist/2022-11-03/rust-std-1.65.0-arm-unknown-linux-musleabihf.tar.xz": "32d7f301196d73027fb9a5ae595dbadacdc234307c36b4a175a132e75318e38c",
- "dist/2022-11-03/rust-std-1.65.0-armebv7r-none-eabi.tar.gz": "e7411233c42774111cbecd5e7f833cc552e4e10047ef368835fc6bb6779bd62a",
- "dist/2022-11-03/rust-std-1.65.0-armebv7r-none-eabi.tar.xz": "aa0052fc3904d93ba4f107f49e16849118108390cb1152f17323cdc2bd559b1e",
- "dist/2022-11-03/rust-std-1.65.0-armebv7r-none-eabihf.tar.gz": "c85f7d61c3a9d4930005e5f054b71145aa6da207ad6b3cb10b7f65514adf0f54",
- "dist/2022-11-03/rust-std-1.65.0-armebv7r-none-eabihf.tar.xz": "2d43f8c1a80a9713955915388cf00756388ca0423930839b22bb0687efa173ed",
- "dist/2022-11-03/rust-std-1.65.0-armv5te-unknown-linux-gnueabi.tar.gz": "e4410b54c63eab57e234a5c230744b3bb63704e012d503bb27ea27e47b85afb1",
- "dist/2022-11-03/rust-std-1.65.0-armv5te-unknown-linux-gnueabi.tar.xz": "d079e841be640b4ce26aa821f29bc813243a7c0af7b8aca8ca4acf5c2e5b722f",
- "dist/2022-11-03/rust-std-1.65.0-armv5te-unknown-linux-musleabi.tar.gz": "8897a7c3df9cad8d5686c7c0aa5475f82aa3e94de2f8ff7184fa017e94da96dd",
- "dist/2022-11-03/rust-std-1.65.0-armv5te-unknown-linux-musleabi.tar.xz": "1d11ab1d60070ae30ff87b55dca077f4d532d814a9ab7bc77055b5b429a78c6e",
- "dist/2022-11-03/rust-std-1.65.0-armv7-linux-androideabi.tar.gz": "c7b9649ff1ca1accf8a0f109eccafdb8c5746596b77253bd65c856b616ab02fc",
- "dist/2022-11-03/rust-std-1.65.0-armv7-linux-androideabi.tar.xz": "da55725498ac8af64359e7c2a46f225dbaf647e1254f648b1f150a3a10a0de94",
- "dist/2022-11-03/rust-std-1.65.0-armv7-unknown-linux-gnueabi.tar.gz": "2b2962822322e6c361bb1213f95fb17ac87aefc0e369ac7de67d7d31035092ef",
- "dist/2022-11-03/rust-std-1.65.0-armv7-unknown-linux-gnueabi.tar.xz": "c14268337c69650a2618909d8e691489385d748374d73ab8d6a2f9d6b030d70d",
- "dist/2022-11-03/rust-std-1.65.0-armv7-unknown-linux-gnueabihf.tar.gz": "616714d28c5c4c0273a22cbc18179ba5354d2e3f4dfc300024266c46b4f68127",
- "dist/2022-11-03/rust-std-1.65.0-armv7-unknown-linux-gnueabihf.tar.xz": "fec73401941bffce3b6913d31955f1291119dea119c0051d94f271ae7c959d4c",
- "dist/2022-11-03/rust-std-1.65.0-armv7-unknown-linux-musleabi.tar.gz": "c920e0c288d08be499efeafeb1d52f6c30c6abeca57f09d57190292af21b9645",
- "dist/2022-11-03/rust-std-1.65.0-armv7-unknown-linux-musleabi.tar.xz": "0b5bc219333e3e983fb1e7e86a0c268c4a52ccbd6326a16785be9d9017d97e9f",
- "dist/2022-11-03/rust-std-1.65.0-armv7-unknown-linux-musleabihf.tar.gz": "da790276100bf066127987bb7964325379ef249f887d17fd3e26bc1628700a8f",
- "dist/2022-11-03/rust-std-1.65.0-armv7-unknown-linux-musleabihf.tar.xz": "9368527053c4bab0fd320209b45f0278d0a1e54a37006a56a6e565404ab73fef",
- "dist/2022-11-03/rust-std-1.65.0-armv7a-none-eabi.tar.gz": "f687d4efa0e494feb97ee2103dd2d3149af54d4751c3327d26fea71711ecc464",
- "dist/2022-11-03/rust-std-1.65.0-armv7a-none-eabi.tar.xz": "4a157c9d23367be9a16cb0ea667f80ee85f2aa4ca549fb0a893f40a846927db7",
- "dist/2022-11-03/rust-std-1.65.0-armv7r-none-eabi.tar.gz": "cfa95c5ebe1183f5d2fc1d05676915a35fb0234085c7a7ff20da822d8fb3b03c",
- "dist/2022-11-03/rust-std-1.65.0-armv7r-none-eabi.tar.xz": "b5e9a895d2f59da805453435ed827a957ef131ef465c139456360c5c9ebf86f8",
- "dist/2022-11-03/rust-std-1.65.0-armv7r-none-eabihf.tar.gz": "e18afa534abd57c7cc8827cabd60e87710299817f4bfdd75699e2f200952d6f3",
- "dist/2022-11-03/rust-std-1.65.0-armv7r-none-eabihf.tar.xz": "25ced4ebecd8da057b74c14bfd810d645454959f58677c32d5d0b3942303f13b",
- "dist/2022-11-03/rust-std-1.65.0-asmjs-unknown-emscripten.tar.gz": "10387374e52db6232723a7f71327a130f88980f063b26ffc0a9b450b2fb7d67b",
- "dist/2022-11-03/rust-std-1.65.0-asmjs-unknown-emscripten.tar.xz": "0b28c4673f2e4006732dfdc1085c754e9c94c82a8c3b2afda17981e87c5cfaf9",
- "dist/2022-11-03/rust-std-1.65.0-i586-pc-windows-msvc.tar.gz": "3e5c4634045d67fbe710ba77c78b257b58bc74d51d2fde9c25e018676d190da9",
- "dist/2022-11-03/rust-std-1.65.0-i586-pc-windows-msvc.tar.xz": "d81357c4b1b814f8bde8e3d5fc039fa7e9072c9f15aa75e129e98d37eb9f4675",
- "dist/2022-11-03/rust-std-1.65.0-i586-unknown-linux-gnu.tar.gz": "2813d22ea020ff3ba737762b19d03e4ede5713d4ffd5222c70f798016019963a",
- "dist/2022-11-03/rust-std-1.65.0-i586-unknown-linux-gnu.tar.xz": "533eda439eb5ffec258b8219445742d6d60570040b3ff167291e3d0d985b9d70",
- "dist/2022-11-03/rust-std-1.65.0-i586-unknown-linux-musl.tar.gz": "415c09908b8a38841221e4021d428262e6c394cebc82af32f091bcfbf849e1e2",
- "dist/2022-11-03/rust-std-1.65.0-i586-unknown-linux-musl.tar.xz": "7f5d9ae65827aef1a51676927a4c9533f942021d2fd45fd93b23dfaa738ee205",
- "dist/2022-11-03/rust-std-1.65.0-i686-linux-android.tar.gz": "c6cea8b87db4c2b56e02a0a50e5906f4cf73cffe78cb282cc6f5aaa2e5daa78f",
- "dist/2022-11-03/rust-std-1.65.0-i686-linux-android.tar.xz": "85c9f5f8b165e76876f95f3423adb8260f8c7fe4fc8ca15660ae870cc2d53916",
- "dist/2022-11-03/rust-std-1.65.0-i686-pc-windows-gnu.tar.gz": "9ea4072ebf97349fc0b34e27cb9c2e03d2b508b07d21edaf74a25e60f7d7853d",
- "dist/2022-11-03/rust-std-1.65.0-i686-pc-windows-gnu.tar.xz": "c0f6c117faec7b4d8c4cbe0a252604ff45dcadacb3b75fc6b9e67671d0b878fa",
- "dist/2022-11-03/rust-std-1.65.0-i686-pc-windows-msvc.tar.gz": "139f947a0d85702c61efb294aa0353768dc7b96c014dc5a092979170507f37d9",
- "dist/2022-11-03/rust-std-1.65.0-i686-pc-windows-msvc.tar.xz": "33f36a6b82ed2dd9a120d503d3701807db12d482144813fb6eaa4f5ca03f425e",
- "dist/2022-11-03/rust-std-1.65.0-i686-unknown-freebsd.tar.gz": "e0ae8dad99b48ba9525e07351bdc53ea6ef3a88b268b68be5092df9a84b89cbc",
- "dist/2022-11-03/rust-std-1.65.0-i686-unknown-freebsd.tar.xz": "016666bdc2cb3b3d994385ec7f73e8bf59491d226818757cc8dafc07705ba45a",
- "dist/2022-11-03/rust-std-1.65.0-i686-unknown-linux-gnu.tar.gz": "8f3c90a21494b90e7f7bb16ee8f0b170b4d63389b05ce6c158eeedf5904d51fb",
- "dist/2022-11-03/rust-std-1.65.0-i686-unknown-linux-gnu.tar.xz": "99bd62d593a6ab3205cab7f06b5793a075b9d05d868e927a6948e46269d61e82",
- "dist/2022-11-03/rust-std-1.65.0-i686-unknown-linux-musl.tar.gz": "f29068870b8ce028a13b4593add734c120ca9bd08dfb6826701a9e7fccd5e1ae",
- "dist/2022-11-03/rust-std-1.65.0-i686-unknown-linux-musl.tar.xz": "644a4c57c1392f776c5ebb13f9832778b69464391b3766e6bbd18c3aa11787a6",
- "dist/2022-11-03/rust-std-1.65.0-mips-unknown-linux-gnu.tar.gz": "83cd534c97c44b3cda6eb2b5bc1259906cd7b7c4711950d62816736eca82eff3",
- "dist/2022-11-03/rust-std-1.65.0-mips-unknown-linux-gnu.tar.xz": "50c65a8effc85aa89242ba0a2a2c89bfcc4d0a39dcb42396d10b0036b9a4e90c",
- "dist/2022-11-03/rust-std-1.65.0-mips-unknown-linux-musl.tar.gz": "ea6c59b68367159e64af476035ef8b94b322f2246a453ac1ed475a990dcead55",
- "dist/2022-11-03/rust-std-1.65.0-mips-unknown-linux-musl.tar.xz": "3bc5043f4eb7bb6418708792ee8e777197e562d03843a9adf62ce245ba07289a",
- "dist/2022-11-03/rust-std-1.65.0-mips64-unknown-linux-gnuabi64.tar.gz": "5b163bc93b6fb649668b7dfda6afed48e35d29cb67e05baba59e109b96e77404",
- "dist/2022-11-03/rust-std-1.65.0-mips64-unknown-linux-gnuabi64.tar.xz": "338c702b79dac33e32dde097084dd38852487d2976c5eb66b44ba8fc8319342b",
- "dist/2022-11-03/rust-std-1.65.0-mips64-unknown-linux-muslabi64.tar.gz": "7a6ab5c7cd4c6c5c63a118750867f0c4410c862689cdcc7440937d00639aa9d5",
- "dist/2022-11-03/rust-std-1.65.0-mips64-unknown-linux-muslabi64.tar.xz": "9450745a5e678c9b7e65ecc7d6a016f92d8d22d8091c4a77431b1e58b99a435f",
- "dist/2022-11-03/rust-std-1.65.0-mips64el-unknown-linux-gnuabi64.tar.gz": "1efc00ec863d21be4b1f097dfbc206fceee31a9b2ffcaff5230ba42e29ffdb04",
- "dist/2022-11-03/rust-std-1.65.0-mips64el-unknown-linux-gnuabi64.tar.xz": "a0a0e60a0e850140194250fbbfb962c322d4f474f4ec22d03b7f537034257c09",
- "dist/2022-11-03/rust-std-1.65.0-mips64el-unknown-linux-muslabi64.tar.gz": "91270833ad6cdadf7bb406e175906e8e5c8431caa5fc3cfc10cc40163cb14578",
- "dist/2022-11-03/rust-std-1.65.0-mips64el-unknown-linux-muslabi64.tar.xz": "0862706d22dcfee39b0d2df874dd6065d8c3020c0b8974f6e7b694edd42413ae",
- "dist/2022-11-03/rust-std-1.65.0-mipsel-unknown-linux-gnu.tar.gz": "646398fdd4ee9f5b9a96aee16c615a4f32f77f2bcdc7ee2a4f5f2274cf1d6b92",
- "dist/2022-11-03/rust-std-1.65.0-mipsel-unknown-linux-gnu.tar.xz": "79e078420f7c45fd1cf38b70620ced50d35ddb1621736b65be987c20481fe5bc",
- "dist/2022-11-03/rust-std-1.65.0-mipsel-unknown-linux-musl.tar.gz": "9db41968e4f025fb9c049a6db88fc1b785503ce161e77f2879f795f422d83f7b",
- "dist/2022-11-03/rust-std-1.65.0-mipsel-unknown-linux-musl.tar.xz": "482e9245873338a08f47ea2c29683134b8813deb3e3eafb78b786d34bbecce51",
- "dist/2022-11-03/rust-std-1.65.0-nvptx64-nvidia-cuda.tar.gz": "28e3eecde27c015f854a93f44a4af86efb59f7a0c9800a77b91edeb50d08f571",
- "dist/2022-11-03/rust-std-1.65.0-nvptx64-nvidia-cuda.tar.xz": "1aeb2f90c2b15d835fadf0c3874bea8a1af740b8ba4b802eb6cbee4496f5357e",
- "dist/2022-11-03/rust-std-1.65.0-powerpc-unknown-linux-gnu.tar.gz": "7c1f66581e7024e6e3ecd69db878defd5ea4a88b8b049ffaf62965ce9d652b15",
- "dist/2022-11-03/rust-std-1.65.0-powerpc-unknown-linux-gnu.tar.xz": "672b9ea8018dcdf7d5f79f5298bacc34e7600a082727b4f1a20c14251752aaa2",
- "dist/2022-11-03/rust-std-1.65.0-powerpc64-unknown-linux-gnu.tar.gz": "f3a25b84be74da0455f6e85c9c1d189ce1cd660e965c6bc7d1018c8fdd31e597",
- "dist/2022-11-03/rust-std-1.65.0-powerpc64-unknown-linux-gnu.tar.xz": "8a26e08908156ae5a05c64c2732435ef4efb994a2ac6d0b2e9c93c0dae19d089",
- "dist/2022-11-03/rust-std-1.65.0-powerpc64le-unknown-linux-gnu.tar.gz": "b66b5d04ad9627003b6658399e22ebf758cf6c6ce4b38ae0829cc3817402d776",
- "dist/2022-11-03/rust-std-1.65.0-powerpc64le-unknown-linux-gnu.tar.xz": "ce18b44300f7d5d94856cef5b270ba010061fafa411beb9782207e26cbab88a6",
- "dist/2022-11-03/rust-std-1.65.0-riscv32i-unknown-none-elf.tar.gz": "cd0eeecc284385a66f6c217467cde74ce450b02b6ac3418989ed452e1d9fa56e",
- "dist/2022-11-03/rust-std-1.65.0-riscv32i-unknown-none-elf.tar.xz": "19cdc94ab99fd668cfd0697ddaf38989ab6aa8b6a317291fee87911c4879c09b",
- "dist/2022-11-03/rust-std-1.65.0-riscv32imac-unknown-none-elf.tar.gz": "a7dd667b06ad75fd6027b2cf34921c57d3419b1e63ee687085af6955a0d79d9a",
- "dist/2022-11-03/rust-std-1.65.0-riscv32imac-unknown-none-elf.tar.xz": "5d61b0ab7bc4f065279e131aac33d64d2c2f5c5f6ad356f45278340bdb3ad223",
- "dist/2022-11-03/rust-std-1.65.0-riscv32imc-unknown-none-elf.tar.gz": "9ee81f4c10602eab12d4ab0048e2a3aea8a557bf0cd4e5274a344c2f9ba2ec27",
- "dist/2022-11-03/rust-std-1.65.0-riscv32imc-unknown-none-elf.tar.xz": "b73be7b808403390cd81c53e46d117be3202c4e97c69dfc7a7e4e34fbe3c0b47",
- "dist/2022-11-03/rust-std-1.65.0-riscv64gc-unknown-linux-gnu.tar.gz": "ee47cf94cd4fd130a233518236f49b742f7f29bb66e2256be23ba71a292430e2",
- "dist/2022-11-03/rust-std-1.65.0-riscv64gc-unknown-linux-gnu.tar.xz": "fa99f123ce14f1cda245857b50fd4709adee960e7d36ce663b87c13aee18b64b",
- "dist/2022-11-03/rust-std-1.65.0-riscv64gc-unknown-none-elf.tar.gz": "55459a12f4f2a3cdc7c050febd26365fb5326db62243b406349eb87783d177b3",
- "dist/2022-11-03/rust-std-1.65.0-riscv64gc-unknown-none-elf.tar.xz": "8f1bfe6264930035324d4c497bcd1af70bf6c302e470cc96b9103c6c57930264",
- "dist/2022-11-03/rust-std-1.65.0-riscv64imac-unknown-none-elf.tar.gz": "fdd2b1bbee188a1fd74f700096b486fc659c9d29c5f7f906aa2958d4dc95ec91",
- "dist/2022-11-03/rust-std-1.65.0-riscv64imac-unknown-none-elf.tar.xz": "04f970b1b643049dba001459075609368203add0b00de797fbca53384c8895d9",
- "dist/2022-11-03/rust-std-1.65.0-s390x-unknown-linux-gnu.tar.gz": "f3ea601929249df63d207883a3777f0def4e84f4e7c1cfe12e3f7872e3f20996",
- "dist/2022-11-03/rust-std-1.65.0-s390x-unknown-linux-gnu.tar.xz": "a3f6740be345364f4599ae837d2401e0f31e5d33a4f958852d12a384ee581a83",
- "dist/2022-11-03/rust-std-1.65.0-sparc64-unknown-linux-gnu.tar.gz": "f58ed6eba451802d5ba37ce1455266317863fdfa04096e0ca8f2cb25488083bd",
- "dist/2022-11-03/rust-std-1.65.0-sparc64-unknown-linux-gnu.tar.xz": "fc2a8816665f464d3085dcd379c44b9de0ee1f1084fae0a4c32c57754b27992b",
- "dist/2022-11-03/rust-std-1.65.0-sparcv9-sun-solaris.tar.gz": "021fb2b640e88717b32356d738a1385cf41c860fdec5830045d026cdf11261de",
- "dist/2022-11-03/rust-std-1.65.0-sparcv9-sun-solaris.tar.xz": "7941668a20b44d293485a0c8369f46a1cb6f29fa976fb1644097897723447960",
- "dist/2022-11-03/rust-std-1.65.0-thumbv6m-none-eabi.tar.gz": "f8de6b8de74bfdb20921be1f61df7b018e29b4f94829d951004ddb82b9062086",
- "dist/2022-11-03/rust-std-1.65.0-thumbv6m-none-eabi.tar.xz": "f9b28bdb16e33343e4dbc66921a295f42371273f147c30d76552cf7c97fc15a0",
- "dist/2022-11-03/rust-std-1.65.0-thumbv7em-none-eabi.tar.gz": "b1e9b2f38f8197236efa70ec75de87dd5503c466c8a9bdd14cd54144ab26ec74",
- "dist/2022-11-03/rust-std-1.65.0-thumbv7em-none-eabi.tar.xz": "862f08bbfc281b6f8417630f59670dadd22d49e4fb98f0dd153d2b81e2e39c5c",
- "dist/2022-11-03/rust-std-1.65.0-thumbv7em-none-eabihf.tar.gz": "4afecbf8043a574388c82a28522317dcbc332f585364572fae0dc41bf19f2aee",
- "dist/2022-11-03/rust-std-1.65.0-thumbv7em-none-eabihf.tar.xz": "609f8625e4397903173cd330774c2116d096a1d7a1539afa479a15b9e7961406",
- "dist/2022-11-03/rust-std-1.65.0-thumbv7m-none-eabi.tar.gz": "543a6365bff2f8038c41b144f02cf353c0421241235a9a431b379f53a758c95f",
- "dist/2022-11-03/rust-std-1.65.0-thumbv7m-none-eabi.tar.xz": "878de0ce07f95c8e2837350af17b0d75a1e759d150917a95aa966284f36d104b",
- "dist/2022-11-03/rust-std-1.65.0-thumbv7neon-linux-androideabi.tar.gz": "c1b5a05d36bdbbe3bbbfb1de2566969e3a82c61182fd74691362f8187e3d5622",
- "dist/2022-11-03/rust-std-1.65.0-thumbv7neon-linux-androideabi.tar.xz": "20b23a5b2ec299506b402921841afa5a948a67769749a59646d100f43ca4c206",
- "dist/2022-11-03/rust-std-1.65.0-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "1102d8d4f3cea919ffa97655120f312dc4ec52c86918966f87c0145a055b4a5a",
- "dist/2022-11-03/rust-std-1.65.0-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "0996cdb1f05ae6df6b26f3c2798bd72727952a73a5fa2a8e988ac992e71fa584",
- "dist/2022-11-03/rust-std-1.65.0-thumbv8m.base-none-eabi.tar.gz": "266ce748b7d7bd241547ce1a9b9c27971580e0706dbee58550d2207fb3d97f91",
- "dist/2022-11-03/rust-std-1.65.0-thumbv8m.base-none-eabi.tar.xz": "d1fb5e2a653d6d98d6608ceb2ecb16f4379b791c2c81c03f4bcf4c23d70cab3c",
- "dist/2022-11-03/rust-std-1.65.0-thumbv8m.main-none-eabi.tar.gz": "7222393cc74402a855ba16496620d1ec92a4c3154a44660f3ad0333a4e40b872",
- "dist/2022-11-03/rust-std-1.65.0-thumbv8m.main-none-eabi.tar.xz": "f6b16ca290d003fd45d2bbea740a5b9803aafc8baa76dedc29074e6eebd07289",
- "dist/2022-11-03/rust-std-1.65.0-thumbv8m.main-none-eabihf.tar.gz": "17f534931cbc4298a4c2df6677d220989e3dcd3a50edd40f8d1e9113118f198a",
- "dist/2022-11-03/rust-std-1.65.0-thumbv8m.main-none-eabihf.tar.xz": "1b22f23d4ee80a8c586a84acd988a550dc2b137ce8c624d48c2b44cfd93f1675",
- "dist/2022-11-03/rust-std-1.65.0-wasm32-unknown-emscripten.tar.gz": "d776bc36af79f99582fdd7b559e6f692b7f617b7f83a47f369fa433f0f2b49fa",
- "dist/2022-11-03/rust-std-1.65.0-wasm32-unknown-emscripten.tar.xz": "f9aa938f2c664f885d3eafad45519ba759ebe3631d62d953a2670174bb90517c",
- "dist/2022-11-03/rust-std-1.65.0-wasm32-unknown-unknown.tar.gz": "177a35ce65f969127bbd58ef08e24471afb2c638a811104c493699a23f5e0006",
- "dist/2022-11-03/rust-std-1.65.0-wasm32-unknown-unknown.tar.xz": "e5190436f2a0c7fa6f2b03bfbfd9c2b44a0de499533b6491f0ec05f08e9cbb6b",
- "dist/2022-11-03/rust-std-1.65.0-wasm32-wasi.tar.gz": "5972f8bacfda0ed5e02b0b9a76ca3f6ed8f5f3d4c11d9ff42bafc8833c744b5d",
- "dist/2022-11-03/rust-std-1.65.0-wasm32-wasi.tar.xz": "cfb55d6d29200a14cd2764a83d513cc85e45a79ed82f2916a7c6f06d10fc1d31",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-apple-darwin.tar.gz": "6b832ef5e94dc9d21c00b5c3cdbf5e4f4223a6215d6fa025ba064b7a24a4963a",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-apple-darwin.tar.xz": "8afef6fee075b7994b5f9b14b13738db27d9841af65f19fb9edccf299b013102",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-apple-ios.tar.gz": "9e5d88ea498ebdf50e1bbded7c3a107a820e668fb6c693c8d0d99244dba125b6",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-apple-ios.tar.xz": "2ba1cb490b834877a6caf77e5db19058492d7e943403b09a4efb1b89a0930cf3",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-fortanix-unknown-sgx.tar.gz": "cdef3244fbbbb2f291c462f53cd4ef6aeeda3d1b7ccb8d77b1d4040947855026",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-fortanix-unknown-sgx.tar.xz": "abdfbe1d32f3935cd5cf5235e88ca0275638977c0586aee2fd5a3a694ca9c0a9",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-fuchsia.tar.gz": "08faecdacef02a81b63d7d2a40fd18a10e7d6954f6461f95c95296936447fc26",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-fuchsia.tar.xz": "4ec2e0c20daf9f474f4cb660dee4707d892f1053c9099cb823b02bb9930d61e1",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-linux-android.tar.gz": "a093924e7fff13cde2c3a46903dc52f4e69e2ad1f79f477dc8e51ff053e87828",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-linux-android.tar.xz": "bd72b31cdab3c65434af6aed84a080cffc388acd4afc0e87d1223e358eff7acf",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-pc-solaris.tar.gz": "611f718e776fc021dcf1c6d7b66de15cb717049dc05d5f040717b4eec54eaa1b",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-pc-solaris.tar.xz": "e89de2a096a90308b78e4e8ee8d51f0b17db0319191bbae8823ee2c805b75ef1",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-pc-windows-gnu.tar.gz": "5ab4b95694511e4cd9af7c5ee3698f0d7c8a2be55e3fc8a7d866bcca1d560625",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-pc-windows-gnu.tar.xz": "05d44a506ec32cfda19a6959f1ad89d994f2705eea3b86f0c00cb9d2ec4423b3",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-pc-windows-msvc.tar.gz": "e07c5bd1b18068bf8e739a7b59875a2911d45315ad8b5e9e6348101f97fdb269",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-pc-windows-msvc.tar.xz": "8b2398872f69d15fcc57777472c31b58f7dc4b55c33f382870fc221995351a0c",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-sun-solaris.tar.gz": "5d7ec4e6f07d78bffad42289b4e8798f48b276c6c436159c4d4117c34c4d4cf0",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-sun-solaris.tar.xz": "4eacb700c3791a8f5d1424a4cdc8e3b35c4fcdee57b97c855cadca6821a7afbd",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-freebsd.tar.gz": "eab943166d86021dad01e65a2f304fcc2914d48e34bcba9f710f362401770e0a",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-freebsd.tar.xz": "bd2242d140bb99bf03d480c56ad85c5ab034d41e29599bee0609191e1181c96f",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-illumos.tar.gz": "153f7d78721ba0e273f9d556ebe4d35ec44522dce0f136e9fa269408345b9e06",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-illumos.tar.xz": "ef652ce8b7183068be581ebb8c91dcefac8ec0f84edbf86f7998261e503edafb",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-linux-gnu.tar.gz": "8c194b0e3814efecb87fc4779767ef17d25399fbd476dbfc92f9a7f88b98f784",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-linux-gnu.tar.xz": "2b588cd2d49688c0c33b7466614123e8fe4c910f4d802fc0ff0662b1772816a9",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-linux-gnux32.tar.gz": "e077e02a56c379950df3c3dda1b18b4fa78d33eb25667f206540dcca3eff0d55",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-linux-gnux32.tar.xz": "7c630f206556916021a7e43dfcfd8392fe1b1e3c7ec94ffc8ef1be87b0ce0631",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-linux-musl.tar.gz": "fbf8b5a2c388710cc7f4cc045d93cf05ebdd2d497936f54f995ccb44d346d85b",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-linux-musl.tar.xz": "55abeb1b55aeebc46a4af2f304271361397df58d12f7eb23fb262bc3132c6056",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-netbsd.tar.gz": "d0405e239dff6b7d840a5a6e45f60c7f661fd428d5a310b25e44de4e7fcb8eec",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-netbsd.tar.xz": "f173d07ccbbe65fc0878c16a7435f17a9db04476f0949e4625a79fa37911e436",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-none.tar.gz": "0942c94117d599cb85e028fc6f9aba057c1d1e8456a6d71c47f64c6d991e6ccd",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-none.tar.xz": "1d3ebe239659688ec787cc87819f8c4a6b77e0361f086111a5c36eb0ad730ca8",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-redox.tar.gz": "b8cc647867823ea52e4f6e647cf5fa7c6370447a324be8a70b56004f179301aa",
- "dist/2022-11-03/rust-std-1.65.0-x86_64-unknown-redox.tar.xz": "23fd34f7ec55ba1e581e692764314c7c342eb87da00562dcba51808a89cb8a92",
- "dist/2022-11-03/rustc-1.65.0-aarch64-apple-darwin.tar.gz": "bbcf34977e41b9f966746a559aa2af6fa7efd7f695338851b37f722f7a1104fb",
- "dist/2022-11-03/rustc-1.65.0-aarch64-apple-darwin.tar.xz": "3368c57e5d2b396486eee5c38d184ddf13f248fbd0291c20764cd26a4e6fb5f1",
- "dist/2022-11-03/rustc-1.65.0-aarch64-pc-windows-msvc.tar.gz": "1c0be4fe80c052e0df315ca97006d5c9c4fdc4c172f3c3c9e6bad3747731578e",
- "dist/2022-11-03/rustc-1.65.0-aarch64-pc-windows-msvc.tar.xz": "d5008e3675ba9b57d05e4b9785b64b88d4166dc45b3fada6744e236024bfc18a",
- "dist/2022-11-03/rustc-1.65.0-aarch64-unknown-linux-gnu.tar.gz": "5ada1a7c9496017e3eed5d8ada62699c8d513f7664d8e02d5d9f02d26974cedc",
- "dist/2022-11-03/rustc-1.65.0-aarch64-unknown-linux-gnu.tar.xz": "67c3d3545fd898c1383071c0f6296453565e0da10903c50652d7bf679b53e8a2",
- "dist/2022-11-03/rustc-1.65.0-aarch64-unknown-linux-musl.tar.gz": "f3e2d2890291fedfea3829c7ffe937603cc43464463fde25187a054ab46755df",
- "dist/2022-11-03/rustc-1.65.0-aarch64-unknown-linux-musl.tar.xz": "51676b3c7023bf57084497b02c6fbfa1604309f52b207d1afe59cf7d20c5fa54",
- "dist/2022-11-03/rustc-1.65.0-arm-unknown-linux-gnueabi.tar.gz": "05a72c333b1ef236fbbb1dc7245b38af1818f0de4e7148f4f7d03b4019cc9c5e",
- "dist/2022-11-03/rustc-1.65.0-arm-unknown-linux-gnueabi.tar.xz": "d6157c4f1b33ca22035c4a796449a187cf8ea54ce50baafc0b035cc0728e8d16",
- "dist/2022-11-03/rustc-1.65.0-arm-unknown-linux-gnueabihf.tar.gz": "2fa0fc7b34eaede3a9a9b85386fc217dc5f455e0a5252bcad10bbc2027b14ef9",
- "dist/2022-11-03/rustc-1.65.0-arm-unknown-linux-gnueabihf.tar.xz": "a217abf1b6db15feb869702b9e3a6462640ba9e87fef9f3bd7c551d237fa2956",
- "dist/2022-11-03/rustc-1.65.0-armv7-unknown-linux-gnueabihf.tar.gz": "34698308b23db42d36e2a651d1d122d0078eb0b1b6ad8d0fdf7dde8358f1486c",
- "dist/2022-11-03/rustc-1.65.0-armv7-unknown-linux-gnueabihf.tar.xz": "883a82b25c5929ba1dbc532394b213a29a914d6dc6bfcf4f28da955c722a760c",
- "dist/2022-11-03/rustc-1.65.0-i686-pc-windows-gnu.tar.gz": "2c6655ed0b87b123a632c861c7b0748d593f82c886013346884d5372d3c504e7",
- "dist/2022-11-03/rustc-1.65.0-i686-pc-windows-gnu.tar.xz": "2ee9b0e2880b5e6817816ba891aa481c0e0c6625683126cc296b2b8dc73177cf",
- "dist/2022-11-03/rustc-1.65.0-i686-pc-windows-msvc.tar.gz": "8ee53ccb1e99945be3c04e36154f467493170c663c47b1c5c8e68e9283875826",
- "dist/2022-11-03/rustc-1.65.0-i686-pc-windows-msvc.tar.xz": "11c01faea62d1077b6e059958991c6496e27a6db1a0b8fd48fb0d2168981d8a5",
- "dist/2022-11-03/rustc-1.65.0-i686-unknown-linux-gnu.tar.gz": "88b9ac8670c55077be42cb9168e0f17d922c0b0eba3044ffa3e63729f02b363a",
- "dist/2022-11-03/rustc-1.65.0-i686-unknown-linux-gnu.tar.xz": "5345c5ffa8aa334419f3c4ca8669c9ea7545abd81097856bbf599271d48b24a8",
- "dist/2022-11-03/rustc-1.65.0-mips-unknown-linux-gnu.tar.gz": "8f63f3cf93718ea10b7f462f5b31cf16b56178c1a120ea17d8bcf7485a1b2e74",
- "dist/2022-11-03/rustc-1.65.0-mips-unknown-linux-gnu.tar.xz": "6ac4ffc60c6942be108e881717fe1288cad15db8a735966899ad8155fb39e17e",
- "dist/2022-11-03/rustc-1.65.0-mips64-unknown-linux-gnuabi64.tar.gz": "8318f09fbe8e07ba5e01b19522fce3c2dea319e4edaeb7616004533510bbc930",
- "dist/2022-11-03/rustc-1.65.0-mips64-unknown-linux-gnuabi64.tar.xz": "414a54a5dabd280c1d59925b3c2781d7850eb0e958701c7e51765478e69e9f06",
- "dist/2022-11-03/rustc-1.65.0-mips64el-unknown-linux-gnuabi64.tar.gz": "dbabfcec57e0d8e1699111914affd0ae9618eb069c1c278c65dcc8febfdd6ef4",
- "dist/2022-11-03/rustc-1.65.0-mips64el-unknown-linux-gnuabi64.tar.xz": "550ca4d5aaeeedcf9e9242060c4ce11eff88fe57860ef11921c7d034fd07a203",
- "dist/2022-11-03/rustc-1.65.0-mipsel-unknown-linux-gnu.tar.gz": "ef52a7a666f0e76afe8ff61dba430bf64fed424e4b3e32cea11676a0889bad10",
- "dist/2022-11-03/rustc-1.65.0-mipsel-unknown-linux-gnu.tar.xz": "77ffd6f14aaa13c54a5f470116e3a4866d44ed0fac2546c325bc4e4bfe66083a",
- "dist/2022-11-03/rustc-1.65.0-powerpc-unknown-linux-gnu.tar.gz": "224e34c6add5e19bd7eb522048c0bedf259612328b21a2c6f01fe8a3fb7a68a5",
- "dist/2022-11-03/rustc-1.65.0-powerpc-unknown-linux-gnu.tar.xz": "78c5334e77ef84be2ebce14c5adc4d4e20410d975f6349020cdcffd01ff2a590",
- "dist/2022-11-03/rustc-1.65.0-powerpc64-unknown-linux-gnu.tar.gz": "aaca27aabaeded4e3e4243d372c3bbb213f5781185e8bb2416a5090d434c6ce7",
- "dist/2022-11-03/rustc-1.65.0-powerpc64-unknown-linux-gnu.tar.xz": "e890651263099a66d85a021d455f1851507b58c5282680d1b1bb2f778d6cad1d",
- "dist/2022-11-03/rustc-1.65.0-powerpc64le-unknown-linux-gnu.tar.gz": "17222364ca34b31bf2a596b1117114ddd08cd1f0d16309c21c1d712dadd63141",
- "dist/2022-11-03/rustc-1.65.0-powerpc64le-unknown-linux-gnu.tar.xz": "a6ce7aadd10a3fd84fe4717a59378421a65b101b61f27eed8b09336b8daf62cf",
- "dist/2022-11-03/rustc-1.65.0-riscv64gc-unknown-linux-gnu.tar.gz": "06f7b5761a290424f08bc66e258b9b4e47e45346873ed0ec0688fb223e232155",
- "dist/2022-11-03/rustc-1.65.0-riscv64gc-unknown-linux-gnu.tar.xz": "60102ba6b659a1e070626d3f1098fd16427464631923c64a458f4e281901679d",
- "dist/2022-11-03/rustc-1.65.0-s390x-unknown-linux-gnu.tar.gz": "1a9c7f8e18f3c5136c83d4b941cc567ac7d576b52a82e42c1bafbbf47d493b61",
- "dist/2022-11-03/rustc-1.65.0-s390x-unknown-linux-gnu.tar.xz": "dc3666eeba9754f67876df7249961c79b21fc576f6e49185ca23d01d82d1356d",
- "dist/2022-11-03/rustc-1.65.0-x86_64-apple-darwin.tar.gz": "be525d2eb2a55f7f5a9f5b3cffe5c1d7b511b4adf9cf5d5855b861138152f1fa",
- "dist/2022-11-03/rustc-1.65.0-x86_64-apple-darwin.tar.xz": "4ee585ecd3f195eb2ee380a9a8550d24852a578c38f07138aef354b0a6b10b77",
- "dist/2022-11-03/rustc-1.65.0-x86_64-pc-windows-gnu.tar.gz": "3abfe8be05104781fb71b6d9f81afd46998733d1f672dd901b27263325f03e5c",
- "dist/2022-11-03/rustc-1.65.0-x86_64-pc-windows-gnu.tar.xz": "197bb667b78f5bcee3713a28b94f3beed30d8fc8b9ab00d5e70b1a75944a2c70",
- "dist/2022-11-03/rustc-1.65.0-x86_64-pc-windows-msvc.tar.gz": "894fe660f3508e9dfac49ed27880aff0dc07196bda1bf15c7c7cc530dbe5599b",
- "dist/2022-11-03/rustc-1.65.0-x86_64-pc-windows-msvc.tar.xz": "0eae7a12177781bedfeb042a21a971e57c1542e5a5a4da751edaf69f95ae7fbf",
- "dist/2022-11-03/rustc-1.65.0-x86_64-unknown-freebsd.tar.gz": "e6104c86d66a19527c48e4e533c28e1b7b74cd2c4e3dfc3eba139c4b152ea121",
- "dist/2022-11-03/rustc-1.65.0-x86_64-unknown-freebsd.tar.xz": "9dcde013879317c17a2e1e0e584f3ac1b6edda2419a51d32fac22201354a25e7",
- "dist/2022-11-03/rustc-1.65.0-x86_64-unknown-illumos.tar.gz": "25154fb657c111809698912f437fe94fabfcf3c367bd10d227755c9a9f6f9109",
- "dist/2022-11-03/rustc-1.65.0-x86_64-unknown-illumos.tar.xz": "922ecf55b2848099369d8b2f6bcfd2979cee307aabd5eab392955b813f7a53ad",
- "dist/2022-11-03/rustc-1.65.0-x86_64-unknown-linux-gnu.tar.gz": "6a30ffca17a244ad6bfb1d257572155f4e2b08d3ca2d852c2fc7420e264c6baa",
- "dist/2022-11-03/rustc-1.65.0-x86_64-unknown-linux-gnu.tar.xz": "62b89786e195fc5a8a262f83118d6689832b24228c9d303cba8ac14dc1e9adc8",
- "dist/2022-11-03/rustc-1.65.0-x86_64-unknown-linux-musl.tar.gz": "afcb7bcec9b128d641224ca476dc5f9e5ab74b6ff82235b95dd305e882e46def",
- "dist/2022-11-03/rustc-1.65.0-x86_64-unknown-linux-musl.tar.xz": "06960685fcf39f24993525cb804649343b8f3c953ad740163edee16d9c9645bd",
- "dist/2022-11-03/rustc-1.65.0-x86_64-unknown-netbsd.tar.gz": "5af04405b78b7a4062e163b7926014fda0a7ef851d75ed50bcaf3f472c277028",
- "dist/2022-11-03/rustc-1.65.0-x86_64-unknown-netbsd.tar.xz": "d6b913b77954146a2aca87ea15758df6bc9481512692423f0b1c0c39c14d5095"
+ "dist/2023-01-10/cargo-1.66.1-aarch64-apple-darwin.tar.gz": "01e83be8ce32e3af5155efde7f3e14b0864c1a73b2e73f03401bd14b67018ad7",
+ "dist/2023-01-10/cargo-1.66.1-aarch64-apple-darwin.tar.xz": "ba2c250f383d71cc0e770b43ba8d71b8fa370509a57bee783c87991e1ce94ab0",
+ "dist/2023-01-10/cargo-1.66.1-aarch64-pc-windows-msvc.tar.gz": "48914e6e598e375d846ce7160694b72ab7cd2e6fd128249d72484f46e773dc86",
+ "dist/2023-01-10/cargo-1.66.1-aarch64-pc-windows-msvc.tar.xz": "b40cba0db58ae52bf9d888465a38c3ba6ed201fab9454d9894407cc44c284692",
+ "dist/2023-01-10/cargo-1.66.1-aarch64-unknown-linux-gnu.tar.gz": "96a44a8ca403f66573d5a8a56610456ac8c0a075f32a6680f8ec4cfff27aa244",
+ "dist/2023-01-10/cargo-1.66.1-aarch64-unknown-linux-gnu.tar.xz": "61736a6ec61a4eaa9a7b3f219d9f8166ae97c1acd54b5e904c15fb8caff06250",
+ "dist/2023-01-10/cargo-1.66.1-aarch64-unknown-linux-musl.tar.gz": "4314ee9856edea883ac23f5d80edb766ee5ec40da2a0c9fdfbd3db1d51e2d916",
+ "dist/2023-01-10/cargo-1.66.1-aarch64-unknown-linux-musl.tar.xz": "8dc391ab64312906ac44adc6fee0c14a5e7f94dda6a5073093879727fdeae109",
+ "dist/2023-01-10/cargo-1.66.1-arm-unknown-linux-gnueabi.tar.gz": "267ef161d2248a4f37d168ec59b5e07168ed54f0d3c70f65315b85f4103adda7",
+ "dist/2023-01-10/cargo-1.66.1-arm-unknown-linux-gnueabi.tar.xz": "3eb1c2186fa28f43539cfc85ef885cc12602d8907fdaa1e9ddc9cc22b988ebd0",
+ "dist/2023-01-10/cargo-1.66.1-arm-unknown-linux-gnueabihf.tar.gz": "8f96fe00ed1d795888530570b12d82feec2d1d01a764ce8815218c46970e436c",
+ "dist/2023-01-10/cargo-1.66.1-arm-unknown-linux-gnueabihf.tar.xz": "e398f9fa14d1b9af1a299536a1646fe1299996095891842b7311bc8f45d4d44d",
+ "dist/2023-01-10/cargo-1.66.1-armv7-unknown-linux-gnueabihf.tar.gz": "4c8eb18c404e1d675822b8e6571b0965be91d33adbe682a171da6f5e3bf4de34",
+ "dist/2023-01-10/cargo-1.66.1-armv7-unknown-linux-gnueabihf.tar.xz": "633e4d9aef40c7f47e99673c4b15171632ef30d0ef478406bd495523d4c8fbf1",
+ "dist/2023-01-10/cargo-1.66.1-i686-pc-windows-gnu.tar.gz": "9d1dd67a0a6dade0a5c14b40254e893757053ed28de8c62551c3354e7626467c",
+ "dist/2023-01-10/cargo-1.66.1-i686-pc-windows-gnu.tar.xz": "cde75b73e08c365b6735fe784fc460f9e68f52d7dd886d6033a21d6de93f4f77",
+ "dist/2023-01-10/cargo-1.66.1-i686-pc-windows-msvc.tar.gz": "e07de7c2642b2f5e2baf4cca103577018ce2e0048924c6f3c19a9b2193cd1a2f",
+ "dist/2023-01-10/cargo-1.66.1-i686-pc-windows-msvc.tar.xz": "e490aaf460a263045ba815d186c0d3f22426fd985c3c13a40b5556ee7c498ff7",
+ "dist/2023-01-10/cargo-1.66.1-i686-unknown-linux-gnu.tar.gz": "432d9fcd0748fabe71ae69a6ccb4ec7a4659bb388e0160c55abbe9af83c77193",
+ "dist/2023-01-10/cargo-1.66.1-i686-unknown-linux-gnu.tar.xz": "fb0c1aa922c4e41fead9d35090769309cb45648d6f77ccbe8d2ba125a75cc2af",
+ "dist/2023-01-10/cargo-1.66.1-mips-unknown-linux-gnu.tar.gz": "45525bd524ad690e3322eaf3a093b2ee97f792dc18757dbbaf479d5b09248d2f",
+ "dist/2023-01-10/cargo-1.66.1-mips-unknown-linux-gnu.tar.xz": "0f03d6d35b6044dc81a4d5eb9bd42c9d1e8c0e85363f960ff921ebe46294ae45",
+ "dist/2023-01-10/cargo-1.66.1-mips64-unknown-linux-gnuabi64.tar.gz": "57a7b5469a35ac56f7a10a83349a7252b5c9403a44ef9828e0747eab35402bd1",
+ "dist/2023-01-10/cargo-1.66.1-mips64-unknown-linux-gnuabi64.tar.xz": "0a91e5adb189d3bed38527306b9f1ec42bc99ff127538fc5fe7e98e8ae8e2952",
+ "dist/2023-01-10/cargo-1.66.1-mips64el-unknown-linux-gnuabi64.tar.gz": "e72d16a68eeb16998124f5c7e6c56e48ec2561cde738c28091f6a930b98f1095",
+ "dist/2023-01-10/cargo-1.66.1-mips64el-unknown-linux-gnuabi64.tar.xz": "7d31ea88b8380fe4d2ea51d18e1b66aad6f0dd84d3d3679d6a24f613b9f45a34",
+ "dist/2023-01-10/cargo-1.66.1-mipsel-unknown-linux-gnu.tar.gz": "8e8b93d31021e2a007cf24973a48d2c7c90283ca2fdbae9e9e1ad926b99197b1",
+ "dist/2023-01-10/cargo-1.66.1-mipsel-unknown-linux-gnu.tar.xz": "74d757a456d2fbb418c253db203c0bb3f71d797e4ab3e2804b6c594a18e0f199",
+ "dist/2023-01-10/cargo-1.66.1-powerpc-unknown-linux-gnu.tar.gz": "144f0e2ff9f9cdcb9343239291a5c208a3304de63200fad666657c5946e1e617",
+ "dist/2023-01-10/cargo-1.66.1-powerpc-unknown-linux-gnu.tar.xz": "f771fa4294c8e0d5d0e58129fe9d4e0913566dd43523b6f0af19a08004004df8",
+ "dist/2023-01-10/cargo-1.66.1-powerpc64-unknown-linux-gnu.tar.gz": "469b2f79648f09c435be7134bcb3bba8bac6cfee7a2fd6b87b8a87e5cdea9545",
+ "dist/2023-01-10/cargo-1.66.1-powerpc64-unknown-linux-gnu.tar.xz": "9a933d39e6b028e73db9cc0959af84128824e0b11554e3a0171cad7635a343c7",
+ "dist/2023-01-10/cargo-1.66.1-powerpc64le-unknown-linux-gnu.tar.gz": "abbe380f8126f0d8c16285783cc969f7d3ae4e99010d00a1261678e25c3e6ffb",
+ "dist/2023-01-10/cargo-1.66.1-powerpc64le-unknown-linux-gnu.tar.xz": "29fa2e003f4bf3e37a3fb506d5b7ab19eb6412b5966d865e082b354637d5d84a",
+ "dist/2023-01-10/cargo-1.66.1-riscv64gc-unknown-linux-gnu.tar.gz": "8baf1432ca5f75e5f873de5a976ce0f46f460e5f2d31d4ded49130a92362a339",
+ "dist/2023-01-10/cargo-1.66.1-riscv64gc-unknown-linux-gnu.tar.xz": "f362cf575fde92f988d5b1fe19fd463a1905d8d2a3844168034df49b1dffb10b",
+ "dist/2023-01-10/cargo-1.66.1-s390x-unknown-linux-gnu.tar.gz": "4981b2b7530b769d498f986efd75a9868db5533e6720826887983ad4bb986ab3",
+ "dist/2023-01-10/cargo-1.66.1-s390x-unknown-linux-gnu.tar.xz": "f69ea091fa1ee4871a46cb9fa1da5b81fa2980687f3bedbc4677a4a82f8da0c0",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-apple-darwin.tar.gz": "125d0ec5b5a159f4f3757b4ae9eaa338afb7d38b4e290794b8157ed6ca8ac16f",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-apple-darwin.tar.xz": "fda976867618d86764bc2f2b5b02fc63803995acd545a5446369d5a059682aa9",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-pc-windows-gnu.tar.gz": "e686537c6d3d79164b7c415b762cc866e3da973f463a962e3025cc75387bb68d",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-pc-windows-gnu.tar.xz": "0de6c045ddfb3a15ef548f8099297a1ed1e03e3171f99e403b247eb5a56b6d4c",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-pc-windows-msvc.tar.gz": "2cce09f42737775a9ad27275634c398ec475c56610c3a49f4885ff1850b192fc",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-pc-windows-msvc.tar.xz": "efd875360249511fa2382a5d0757e2e1937265e4574c40f7acfe4368fa79d60d",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-unknown-freebsd.tar.gz": "5cea374d6396b038532f30995459e7184779485da74b726f58219ac592edd002",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-unknown-freebsd.tar.xz": "aa40e3a68e1f02b8052adb17d9a4a8e664cbbda09c2e408327f0bf9057641ad9",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-unknown-illumos.tar.gz": "c4313ef482200f413e96dff7880082e6fd926cac9594db395b7ce9f3b009eaef",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-unknown-illumos.tar.xz": "2d077552a4c8319113e329e27431fcfcf4bc349287c303c263881ad62d9d547c",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-unknown-linux-gnu.tar.gz": "7752e7c5cd12204fe852bcb2a67d7fa9ab037f26dd34ccc3b25253b4c223df19",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-unknown-linux-gnu.tar.xz": "a636f83eb2327a66f484b9592ab305c6642df16fc80d0d1cb727e766a60da904",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-unknown-linux-musl.tar.gz": "3778e1460a418ff1c18f70ea83ea89b94c58b1b2e10e3d38e4692d49096c774a",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-unknown-linux-musl.tar.xz": "6b91979328294e8a5f74c7134846eff593b0b0c9ea6aa3b58d4572e4a3d2e902",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-unknown-netbsd.tar.gz": "4a2e394f117bb413e6d24fce30c5534a9a10a4a69ae5e4298423785366de5c62",
+ "dist/2023-01-10/cargo-1.66.1-x86_64-unknown-netbsd.tar.xz": "874562e3d2400c21f856d1a16e4e0ff702a07f875447408b1842735b4609b9d0",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-apple-darwin.tar.gz": "cc327dfbceac467ac7afef199ac218820b50dc62031370eea25e49ff5c290f63",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-apple-darwin.tar.xz": "f91f5266200e199b66687014c3eadcb6379ac6f34b89c7e22a0fec1d9f2217ec",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-apple-ios-sim.tar.gz": "e25fa5f3976d19afcb7d0c3eded315ae2a2efaf8b5e05d79f96ed9d1b852bcb9",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-apple-ios-sim.tar.xz": "11e14858709f6836106a827496784eb462c86cdb0b4a613823baa70b3cc880ba",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-apple-ios.tar.gz": "cf93dc6e3c2ccde4af55a5f5701c812465bf3291f0c68bc6c9f1f156efa8d0b1",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-apple-ios.tar.xz": "ea17287c959c315682b971d33bcba29f5f5c91ca649cef8c078064b9ea51c31d",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-fuchsia.tar.gz": "3ee045537a6a59de17c257ac6f691f9d57a7b1dcf83dd7f17ec9098106fc0a8d",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-fuchsia.tar.xz": "350df24820887b29eef02d9aea5197a27919957a70b8e47b57e63fe1a07216c0",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-linux-android.tar.gz": "384183741608544f8d51dcf99a8cb87689aae30ae1fcf7e50650efc729c557fe",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-linux-android.tar.xz": "585ab55f6f68fac070fb262bef6cdfa1906db23e630c2f4a303aa6539e282cfd",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-pc-windows-msvc.tar.gz": "fe9ba6fcc9ea6ca4b6d86bf5bf3abc824b157afb8a5d0cf12b289a7ac733f767",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-pc-windows-msvc.tar.xz": "b2dde83310056bd842ee41194537746b04a6589fd2f1e58b742a8f40addd5c62",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-unknown-linux-gnu.tar.gz": "0ab8e60caf3c63f687d02f16cb577da86ed292481fda29da9e9acd53140f9b31",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-unknown-linux-gnu.tar.xz": "9d96ba6a5a255339cd04af079d906753d56c85503c727279c227d24bd4987e24",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-unknown-linux-musl.tar.gz": "5fe9813f157add9291cb7bff633bdaea567f232a882b39c8383029b51de11d97",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-unknown-linux-musl.tar.xz": "520ac446f20490685cc4d73192cfbb4c9b9e55c884aa4ae2b098e3a54d891de8",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-unknown-none-softfloat.tar.gz": "6c9a7400bdc524f88f0dbec3f728bfb10dc8b2d08151483597b7fb377117f25a",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-unknown-none-softfloat.tar.xz": "5ce6dd92923b4815cbd66cc0a9557e5d2bd72dd2b08776b18e685563e1d17a67",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-unknown-none.tar.gz": "9c246bd606f708bd4c289921b97f4d22effc58c8a9c7fba8b382ac55908323fe",
+ "dist/2023-01-10/rust-std-1.66.1-aarch64-unknown-none.tar.xz": "084d7237bb4ab010d02ad51b9215b1d092279eb0e9f5af102b23e5c2b85e98a2",
+ "dist/2023-01-10/rust-std-1.66.1-arm-linux-androideabi.tar.gz": "9027b677f909f49819ac5e241df491ed58facbee0f265e09258ff98e37d5f123",
+ "dist/2023-01-10/rust-std-1.66.1-arm-linux-androideabi.tar.xz": "0a5afab5afe069823b495a641e422133cb64d7123467b88573c4e334a0be111b",
+ "dist/2023-01-10/rust-std-1.66.1-arm-unknown-linux-gnueabi.tar.gz": "35cc58bc6c9390f99bb1ae49b6273576f08c99609f0aa33c3b7ad0d4bc9ede3f",
+ "dist/2023-01-10/rust-std-1.66.1-arm-unknown-linux-gnueabi.tar.xz": "42afd189ef64988f64976f767a734734bccd7c71e578780e902148c98226fa29",
+ "dist/2023-01-10/rust-std-1.66.1-arm-unknown-linux-gnueabihf.tar.gz": "db178fab229f61a21368718330dcd749171439abf60bf14a2ac415e96e624226",
+ "dist/2023-01-10/rust-std-1.66.1-arm-unknown-linux-gnueabihf.tar.xz": "506126773af9c3dacc506776a0b2e12fe6fa0c95eaf4f4ebb5cdbd335feb83fa",
+ "dist/2023-01-10/rust-std-1.66.1-arm-unknown-linux-musleabi.tar.gz": "667650f0ea68808e2610d3f96a214de707dfbefca90541b15ddeb43f413dbeff",
+ "dist/2023-01-10/rust-std-1.66.1-arm-unknown-linux-musleabi.tar.xz": "5282fc97111a7eafbead3463ed7bc0f3065332f21aec6a39a740157fe42f943a",
+ "dist/2023-01-10/rust-std-1.66.1-arm-unknown-linux-musleabihf.tar.gz": "87bb0bb0a68f3e91fcce2700639600ab27de62410a1fa27ffcd7e62f16fd202b",
+ "dist/2023-01-10/rust-std-1.66.1-arm-unknown-linux-musleabihf.tar.xz": "3d21b478fbf07bd27902bdd189e6988341f0c2c0108b538f926cea3031bc8ea6",
+ "dist/2023-01-10/rust-std-1.66.1-armebv7r-none-eabi.tar.gz": "0a00ceb2e2ff80e9b46e0fb8ed0d6f6d22f4691568aff0b79bf3daf6c22e5588",
+ "dist/2023-01-10/rust-std-1.66.1-armebv7r-none-eabi.tar.xz": "da5f198a69c1197939ff852b9fb5daabc0133ccd1fd4da0d62bc7f739887fb74",
+ "dist/2023-01-10/rust-std-1.66.1-armebv7r-none-eabihf.tar.gz": "c13a692e482bc793b5acccaa4266c265807072dafa7ee8d5d7e0b67113d4a65a",
+ "dist/2023-01-10/rust-std-1.66.1-armebv7r-none-eabihf.tar.xz": "69021741e6cca8c601fae01936a1d772ec0e500628939d2c7a9b072edb6c53a5",
+ "dist/2023-01-10/rust-std-1.66.1-armv5te-unknown-linux-gnueabi.tar.gz": "2267f1149fe323ceaced52c638a8c6d82c8485724757903804b839f3e4d8b08f",
+ "dist/2023-01-10/rust-std-1.66.1-armv5te-unknown-linux-gnueabi.tar.xz": "0ebf0178bbe9c5572d1db89e190dee23aef0e2f667995abedbd66e33d0bd73ab",
+ "dist/2023-01-10/rust-std-1.66.1-armv5te-unknown-linux-musleabi.tar.gz": "7c8a14b71589f26a3a8aa3a4ad1bd46d50df9538b0ec603e22f4687f78d8b6dc",
+ "dist/2023-01-10/rust-std-1.66.1-armv5te-unknown-linux-musleabi.tar.xz": "938e7442c21ea0895c44ec78fa718ea1d3abe32ed0425ed328c905e188af250e",
+ "dist/2023-01-10/rust-std-1.66.1-armv7-linux-androideabi.tar.gz": "205e335273f3b84d2bb3f173eeb3ad6faf44a413369e19458a8677b9cafa573e",
+ "dist/2023-01-10/rust-std-1.66.1-armv7-linux-androideabi.tar.xz": "487c063a502df7b033108a69701ae38759c1bdda2f092d8ffc116f1c3acd1242",
+ "dist/2023-01-10/rust-std-1.66.1-armv7-unknown-linux-gnueabi.tar.gz": "cca938c45c83cd3f4e3585e33d925358b7d0ffa91f407fcb5fdb2a1f94c85cd0",
+ "dist/2023-01-10/rust-std-1.66.1-armv7-unknown-linux-gnueabi.tar.xz": "d75c6dc3c00d662b0d3f6ce7fde0f76057542edfbc97a20b29247842c8a711d2",
+ "dist/2023-01-10/rust-std-1.66.1-armv7-unknown-linux-gnueabihf.tar.gz": "c4150af5f8366cb4a9e1fe4bd982ee84bb66789c3b5085c55f6f7ba8012a8feb",
+ "dist/2023-01-10/rust-std-1.66.1-armv7-unknown-linux-gnueabihf.tar.xz": "bdc491f4c05669e7a3382b6bfdaeaa20e2cfa5ef553305df0e0d73729a45e6e4",
+ "dist/2023-01-10/rust-std-1.66.1-armv7-unknown-linux-musleabi.tar.gz": "17fd23b934c878506f644fe59d7942c9cffafcdf4f55ec66f048ecfc38b6a944",
+ "dist/2023-01-10/rust-std-1.66.1-armv7-unknown-linux-musleabi.tar.xz": "d720bd1e493f53797f90d83dbe6d52ecbe1ff3cae282f4b2e18c37fe92c9adf6",
+ "dist/2023-01-10/rust-std-1.66.1-armv7-unknown-linux-musleabihf.tar.gz": "bd43b68a4384acd7a5b862e2260c3a1eff8897e4e7fca1a7032d20e8e7c1c701",
+ "dist/2023-01-10/rust-std-1.66.1-armv7-unknown-linux-musleabihf.tar.xz": "830285e5388081c68fac9dc955aa824a4d919b0e24eadc6e0b95b30103d79db9",
+ "dist/2023-01-10/rust-std-1.66.1-armv7a-none-eabi.tar.gz": "e88859a1d51e4435da5970556982db760b54bd29cd0f75554079bf329b9f8357",
+ "dist/2023-01-10/rust-std-1.66.1-armv7a-none-eabi.tar.xz": "abccb60f9941fda1947b28a9a7d94624ac4da9f438e50dd5cd16cfa4961f6989",
+ "dist/2023-01-10/rust-std-1.66.1-armv7r-none-eabi.tar.gz": "4f68ab0141eba263f4ab3dfa1a552e10a44eb73dbc20b365b7ec4ddfffef198f",
+ "dist/2023-01-10/rust-std-1.66.1-armv7r-none-eabi.tar.xz": "49e6c4559ec5b7543487f7af1334adbc8aebb7aaeeeaceeed2a570761c4b2aac",
+ "dist/2023-01-10/rust-std-1.66.1-armv7r-none-eabihf.tar.gz": "f986754a5c53c864e0de7b5cf6576d270462f1b24b5a77776a117b09e06933cc",
+ "dist/2023-01-10/rust-std-1.66.1-armv7r-none-eabihf.tar.xz": "b27a9fb40faccc39cedaa54cc6db262ba50fa7872c8ea58ecb9868241e0aeda6",
+ "dist/2023-01-10/rust-std-1.66.1-asmjs-unknown-emscripten.tar.gz": "927ecdaa0d4f7aa178ff05394b051d3c96e3baf44b9a5c39807ce58f205606d1",
+ "dist/2023-01-10/rust-std-1.66.1-asmjs-unknown-emscripten.tar.xz": "ebb81db61752d13cd94ec9636ba0d0b98423417d0301257a7928606648b216c0",
+ "dist/2023-01-10/rust-std-1.66.1-i586-pc-windows-msvc.tar.gz": "4f83008d54c5ca0eb52b8331617d601fe4617ea8a706e78d4a9386bca3dd1a4d",
+ "dist/2023-01-10/rust-std-1.66.1-i586-pc-windows-msvc.tar.xz": "e72b3db1fb4b75c9b2e2a0f97391482d9eb58a15aeb8780562de6e6e247c955a",
+ "dist/2023-01-10/rust-std-1.66.1-i586-unknown-linux-gnu.tar.gz": "f772d6462c3476abfed840d6a6bc9c31f0fdf9c3c5bd1967f5c023dd701ceda3",
+ "dist/2023-01-10/rust-std-1.66.1-i586-unknown-linux-gnu.tar.xz": "90eb8e2490283930e682b79842d664d4867414563353d53dafc47eccf44aea17",
+ "dist/2023-01-10/rust-std-1.66.1-i586-unknown-linux-musl.tar.gz": "e17a44278972b7f8da9ceb0191c799a779acb12e77e2ca3f5d9f0d317360c105",
+ "dist/2023-01-10/rust-std-1.66.1-i586-unknown-linux-musl.tar.xz": "c4bab2d63223d0c6e63806082e30d8c38b37eefc10ee2e7380971e3012c00bca",
+ "dist/2023-01-10/rust-std-1.66.1-i686-linux-android.tar.gz": "20737f65beb6116eff080fe1043bee459af965c07646ea2b2091edec1bf1e103",
+ "dist/2023-01-10/rust-std-1.66.1-i686-linux-android.tar.xz": "380d97f317134f587d82ee4816f04ebf8ced879aacf54b49ebf17d65c2423bff",
+ "dist/2023-01-10/rust-std-1.66.1-i686-pc-windows-gnu.tar.gz": "e32aa1c799dccb24260050f5a853daa4be168fdc30610d6c6d2842e0784d735e",
+ "dist/2023-01-10/rust-std-1.66.1-i686-pc-windows-gnu.tar.xz": "507d9a4f12c125e45c6db95b6ae3f2e79efcacb64516eec53f222805afdef4b2",
+ "dist/2023-01-10/rust-std-1.66.1-i686-pc-windows-msvc.tar.gz": "e44703f977595651748190d13bcbf6e42ae8f52bfc7a5904d1a9b26f21ec1152",
+ "dist/2023-01-10/rust-std-1.66.1-i686-pc-windows-msvc.tar.xz": "bf844b7855a7753012c4ac8ce6fd76b30f0c9046edc5c3409576b3b58eb134c0",
+ "dist/2023-01-10/rust-std-1.66.1-i686-unknown-freebsd.tar.gz": "d1f1d27bea45472d8cddad0d6f4b2635ff8b581d742928c0ab817b2d55913bbd",
+ "dist/2023-01-10/rust-std-1.66.1-i686-unknown-freebsd.tar.xz": "2913ac7ac6ceb90b292f3a822739791c6e70498972e649d458e2cfe174e4a406",
+ "dist/2023-01-10/rust-std-1.66.1-i686-unknown-linux-gnu.tar.gz": "e8a937cb56aa2f644a537f403b4e92978cdb17a2e4d8b737f4a9743bb17724b4",
+ "dist/2023-01-10/rust-std-1.66.1-i686-unknown-linux-gnu.tar.xz": "b32cbbb9002f8a20b302823a2ff122a91f077b5e1a7bc1340de690ded86bf10b",
+ "dist/2023-01-10/rust-std-1.66.1-i686-unknown-linux-musl.tar.gz": "314106777fa561f9dfb1ecf18f24e1d960f8fe51ab1705d5c5140de9199c37cc",
+ "dist/2023-01-10/rust-std-1.66.1-i686-unknown-linux-musl.tar.xz": "52013329eb6697d94f5dce01dd509b4b93b473c18a3a2c05d0230b9dfeab14d1",
+ "dist/2023-01-10/rust-std-1.66.1-mips-unknown-linux-gnu.tar.gz": "d61188ea93c117fb7534bd49c46f2f0116bc880f8e49a591688cbc2d4eb594d6",
+ "dist/2023-01-10/rust-std-1.66.1-mips-unknown-linux-gnu.tar.xz": "e6029b4cec5d6c06c34a0dbec614fa252fdc8cf31013d6e561112cf90f742568",
+ "dist/2023-01-10/rust-std-1.66.1-mips-unknown-linux-musl.tar.gz": "3d1e3b8e57695149aa3f050213619923430ccd63e6db7b37df152939267e0362",
+ "dist/2023-01-10/rust-std-1.66.1-mips-unknown-linux-musl.tar.xz": "23f917eccaca59d4c911eb96d8ffefe86834dbcdf902c9ab6dad8558c31c4575",
+ "dist/2023-01-10/rust-std-1.66.1-mips64-unknown-linux-gnuabi64.tar.gz": "d42f546133e0ba8ea79b35e115fa56a845cc6e191a2d8d865de93d0026edf09c",
+ "dist/2023-01-10/rust-std-1.66.1-mips64-unknown-linux-gnuabi64.tar.xz": "70d1406e0981d5d31c1d3f85c848bba0476e0ff6203e7706f66b4d2212f01b66",
+ "dist/2023-01-10/rust-std-1.66.1-mips64-unknown-linux-muslabi64.tar.gz": "4b7b4d5cdb9b817605aa73be641f12af8c816bf896e958488ae4e1b69b917394",
+ "dist/2023-01-10/rust-std-1.66.1-mips64-unknown-linux-muslabi64.tar.xz": "0fd221d4b4205ce548e83f0e7416c8332eb12b64d5a43c0b3ed61e9f7d6edf13",
+ "dist/2023-01-10/rust-std-1.66.1-mips64el-unknown-linux-gnuabi64.tar.gz": "246da3c3f3939aafafd63b9c5e2536f5e3e25a9cb38842586fb9679d1d01e085",
+ "dist/2023-01-10/rust-std-1.66.1-mips64el-unknown-linux-gnuabi64.tar.xz": "132d6d5750a877972ebc6f23e831f2ef3077465b2ab24ca645d32ea83c496fe3",
+ "dist/2023-01-10/rust-std-1.66.1-mips64el-unknown-linux-muslabi64.tar.gz": "41e4780f044136651e418a68744a9a12597ad6d02a83b6f4837f74480e513266",
+ "dist/2023-01-10/rust-std-1.66.1-mips64el-unknown-linux-muslabi64.tar.xz": "533f370368ac8b6192e1450289c64544ebf9cacc38c3a52ef6c0ecded7ee6fa5",
+ "dist/2023-01-10/rust-std-1.66.1-mipsel-unknown-linux-gnu.tar.gz": "cdc9a4caa8356e49c7f5d0806bf8f8cef693eb03e42d875388abc0bbed9b8099",
+ "dist/2023-01-10/rust-std-1.66.1-mipsel-unknown-linux-gnu.tar.xz": "8bfa3d6079c6df049978fe61b1ccaf992aecd006e23df2439ecfc883bd8bc31b",
+ "dist/2023-01-10/rust-std-1.66.1-mipsel-unknown-linux-musl.tar.gz": "da0f5ebe95ccc70926937705b0601632985aa3415414becbf2cb9740917f958f",
+ "dist/2023-01-10/rust-std-1.66.1-mipsel-unknown-linux-musl.tar.xz": "d7028820888d0decde047a6e77b866e690532aa09522c9a23a3fbf8780a72257",
+ "dist/2023-01-10/rust-std-1.66.1-nvptx64-nvidia-cuda.tar.gz": "d0739019f1f61081ad7fdf39069d85b91babc78de296f3166dad842e4ae1af6f",
+ "dist/2023-01-10/rust-std-1.66.1-nvptx64-nvidia-cuda.tar.xz": "1d9e2b6c9054fd4c55613226b16e3bd08d46561149cff44472a5cc55535d1904",
+ "dist/2023-01-10/rust-std-1.66.1-powerpc-unknown-linux-gnu.tar.gz": "c70872a80ca38b2daa83132da5ea979e443c8d973d4692fbaee8b9134926c8c1",
+ "dist/2023-01-10/rust-std-1.66.1-powerpc-unknown-linux-gnu.tar.xz": "417b12a9bf090d694514937cd8c321ed625f155248f63c0de8207b17fa4b35b1",
+ "dist/2023-01-10/rust-std-1.66.1-powerpc64-unknown-linux-gnu.tar.gz": "ae31dba580edc17394a2a0563d7cf02d3185e2a63a3dca34ab78e05ea5b362b1",
+ "dist/2023-01-10/rust-std-1.66.1-powerpc64-unknown-linux-gnu.tar.xz": "7074c4ea9fcc683ceb0adcca6ba07544a1d91f0e5d2a4cf14c81eb14316ebf35",
+ "dist/2023-01-10/rust-std-1.66.1-powerpc64le-unknown-linux-gnu.tar.gz": "42f7a99384bcbf36fa71328b1a5cc759fb34affff38bc2d7a4531f1ec39b253d",
+ "dist/2023-01-10/rust-std-1.66.1-powerpc64le-unknown-linux-gnu.tar.xz": "4c64a09be872b5832b50d681fbe29691b6a5d3e23ee5535020fa22b8b453c770",
+ "dist/2023-01-10/rust-std-1.66.1-riscv32i-unknown-none-elf.tar.gz": "f3afffaa0767de5db0a94880b21653683ccba24370edcb04e81ceb44da5b09f8",
+ "dist/2023-01-10/rust-std-1.66.1-riscv32i-unknown-none-elf.tar.xz": "c0573a3cac2d313647875bcf306a6278abfc362a599741f389c4c7aabcd696b0",
+ "dist/2023-01-10/rust-std-1.66.1-riscv32imac-unknown-none-elf.tar.gz": "01059c9074dae22c3b6a4be530e3ab36f5c5571b0b321f134f12d2948fc05435",
+ "dist/2023-01-10/rust-std-1.66.1-riscv32imac-unknown-none-elf.tar.xz": "93afbfda3d09d7a738f55735929a00a5d7a820f183829f159967905f221d918e",
+ "dist/2023-01-10/rust-std-1.66.1-riscv32imc-unknown-none-elf.tar.gz": "c747d5ca12a4e6bed863035eb6efec82089643aa80260be21f5b5f7f92bb3df9",
+ "dist/2023-01-10/rust-std-1.66.1-riscv32imc-unknown-none-elf.tar.xz": "9769564e50f59ed5e72ca59b8f3548ea3033ffd4f12d29b4c8cba2696f08991e",
+ "dist/2023-01-10/rust-std-1.66.1-riscv64gc-unknown-linux-gnu.tar.gz": "48ecc5b05c297f93af106be6ccf04cae5d478e5e53cddfd34ec19b860a591948",
+ "dist/2023-01-10/rust-std-1.66.1-riscv64gc-unknown-linux-gnu.tar.xz": "776eff6f451845e88224714ee6da7819e34f01b7625bf927394c2b91e5c8243c",
+ "dist/2023-01-10/rust-std-1.66.1-riscv64gc-unknown-none-elf.tar.gz": "5d812ba583f1a31d0970100348b48b1999104e1392d0687125bb7fffdee450c5",
+ "dist/2023-01-10/rust-std-1.66.1-riscv64gc-unknown-none-elf.tar.xz": "9b439a4ddbb906c7d4609177ce699c4289380337ae6237dee07a1890cf072de2",
+ "dist/2023-01-10/rust-std-1.66.1-riscv64imac-unknown-none-elf.tar.gz": "9190f43a3a8cde5701e83efe9ac6f050411c3a3a048d99d48a546cc4ea34724f",
+ "dist/2023-01-10/rust-std-1.66.1-riscv64imac-unknown-none-elf.tar.xz": "0baf46ad3d53646ebcdbf5e15f31c09d4ac121ef6a3629de62eaaa4da9947a57",
+ "dist/2023-01-10/rust-std-1.66.1-s390x-unknown-linux-gnu.tar.gz": "59cc06b5feae16ae0da3b5725f6e72e72f3c5c02bed7b492ba8f10ddf0716602",
+ "dist/2023-01-10/rust-std-1.66.1-s390x-unknown-linux-gnu.tar.xz": "51d1567e1d28e43c2165886f5a4955dcdaa41aa5ddcec5fb08200491fd1f6062",
+ "dist/2023-01-10/rust-std-1.66.1-sparc64-unknown-linux-gnu.tar.gz": "d3f563173576e9f118b734b88cb44b84c27766ab5a1e4308b9a425ebfb1d8cb4",
+ "dist/2023-01-10/rust-std-1.66.1-sparc64-unknown-linux-gnu.tar.xz": "3aee03fa61c28bb242023efb09a22e38a76b075cc72bcad9894560be8b28a927",
+ "dist/2023-01-10/rust-std-1.66.1-sparcv9-sun-solaris.tar.gz": "fb3fd76e7cf7ca3875141dbf87a8ee5463bd3c7b684a93d6c2edd11f19606a13",
+ "dist/2023-01-10/rust-std-1.66.1-sparcv9-sun-solaris.tar.xz": "d923d7cf82c1588356f680279e1a5f55d7d45a57eee5bf0ec518ccb28081373d",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv6m-none-eabi.tar.gz": "2864dbd6ded36045a9477c27c355f0defaf7f29f5907653d720da92623d2668d",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv6m-none-eabi.tar.xz": "2ccfab7ac0347ffe5017bdcb7d19f68bf15e9bca6518851a4b13745efec22034",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv7em-none-eabi.tar.gz": "962ab95eff101c3d172012d6a0d63a37e73f1f4590e4aaa0c33fc1cde5558b77",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv7em-none-eabi.tar.xz": "b0f60062f1ac1152911f85fe9f7a420c441482768bc622766958aaa4f1f9ee2b",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv7em-none-eabihf.tar.gz": "e9ae06e2cdd86b5cd1c3502c26b11d72fc759390ae24d3d1fc9b4bec6dde0705",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv7em-none-eabihf.tar.xz": "08854bf8a7ae73b86524a43cd104aa94f2dbd953fd7deb9181469548758b9fdf",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv7m-none-eabi.tar.gz": "a9d56c0dc6353091af549f86861b2e27f62b143770e2335587cac0c12c91cf69",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv7m-none-eabi.tar.xz": "d297adde1880fe59765e41bddb2ecb1119b60f88cabd52bb0f304f7bcacbb969",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv7neon-linux-androideabi.tar.gz": "61a94e403b860d13a309f6e7e35c26e17fa8b54c034027799466e4bb2a3b4628",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv7neon-linux-androideabi.tar.xz": "52e63c72726ec46ec30bb8c00b078835202227de192fe001b03a1289522aa804",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "45ecf852dd4c0969434eea9f8b1680a7d0af0e3ca80dc134c2c87577dc6b99d9",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "0645bfefc8ac6a9e4e866cc18074c1f74f38e0d0e317c455a1a6858999ab85fc",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv8m.base-none-eabi.tar.gz": "c5fde3c4d5b7ef1f3e15c23621abc271f0ebc0f394f20c62f942062bc4f034ab",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv8m.base-none-eabi.tar.xz": "2befcc055c38a98b3e686a141a00f1c63341921eff33d22d1f33adc6a20ba084",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv8m.main-none-eabi.tar.gz": "db9adca292c7eaf41702b32f4f15e6e46f506311d1d75d699b1aa5ca48ad1d45",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv8m.main-none-eabi.tar.xz": "18ff148801552fd947ca80ff004ce470dc835596b13e8905a7f1f9b8af981a39",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv8m.main-none-eabihf.tar.gz": "95ac22cb1bc3fa740d677ddab229d93be7517783456c9694f6c6e0e95aa266ed",
+ "dist/2023-01-10/rust-std-1.66.1-thumbv8m.main-none-eabihf.tar.xz": "2b2f27158a2fcb3eac05f462fd01415a22fa95a26dae19629d6ffc3d1abafb29",
+ "dist/2023-01-10/rust-std-1.66.1-wasm32-unknown-emscripten.tar.gz": "4e5c994ff495d7d6551aa46f21c9747e459d8b014a24cfada3f81d57d9f6521f",
+ "dist/2023-01-10/rust-std-1.66.1-wasm32-unknown-emscripten.tar.xz": "7d4b9a14b0d77036c9f9687d4c5dc4e1049445a8e33cba735f35da0c7a73c59b",
+ "dist/2023-01-10/rust-std-1.66.1-wasm32-unknown-unknown.tar.gz": "c1fcba65c7521fd4affb8a56df4d8435d0cbc8d9e2fc19a07a41daa05517d385",
+ "dist/2023-01-10/rust-std-1.66.1-wasm32-unknown-unknown.tar.xz": "295ad2b64f7a8bf0ab39328390ba88592f71a4b3c70c37ae857c3171a9a68c2a",
+ "dist/2023-01-10/rust-std-1.66.1-wasm32-wasi.tar.gz": "175f8081136cc4ab2f1244437112d2018b29c8d5d221d474223f547e9f6002d3",
+ "dist/2023-01-10/rust-std-1.66.1-wasm32-wasi.tar.xz": "13d38d9bcf995ee4c1717ccf813ffb98c676dac8c0de1d8f17b095848037e328",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-apple-darwin.tar.gz": "dff38a6930052a5bbcb189e879376ca75fe3ea229fe241fa636f362b2ce56298",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-apple-darwin.tar.xz": "4ed9ba4487a65039304d69329910e653805a56e1251cb29692ba159b5465d988",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-apple-ios.tar.gz": "a27575be686bfecfca72c800e77ab364cf74d65ac8bb847fcfc488a9a5342db7",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-apple-ios.tar.xz": "1f92bbd09a27be8e563f171a2246e5bd504b3178925f64ea3532575d8333005c",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-fortanix-unknown-sgx.tar.gz": "bab7fe360b4d2cae595e0b14cb1aef43c1feb5408b806dfba1057e98988855d3",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-fortanix-unknown-sgx.tar.xz": "007a7047eb4b6e4946558157348abba00928a5a6599ec55979cd4b146b69fc21",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-fuchsia.tar.gz": "5231f3353545cb7784da1ed1ba66516c0662078434dffcc6b6efdbf3ee2217f0",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-fuchsia.tar.xz": "a44651d77c151da1ba5a6fe954b46c01e296e94c8f22b3374520289cc2af61de",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-linux-android.tar.gz": "806d3893aff9b66fd7b4bdfad4ef92c6d03b9d34e7f264daa2e678741eb1b2b1",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-linux-android.tar.xz": "5de970c6b2fee00a78c521616d0169a6395bcc5b6363817dd682585a37fcbe79",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-pc-solaris.tar.gz": "cae2409be16bc84f07dcad15e4aede3f6262414af46a840963a1b1ddce1e4263",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-pc-solaris.tar.xz": "a53e3ce8648376f564e3120a6abfe329d047b464b9573f9f4c22763675634deb",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-pc-windows-gnu.tar.gz": "ce5bb091b9fc0cd58d01ca2f467b06f1a7a3b7b200bbd92b3474db8265df9947",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-pc-windows-gnu.tar.xz": "d18451bc7f9d7d3ebebce45375ab5ab806c3cf6c2565cb0081af5b0829272ab2",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-pc-windows-msvc.tar.gz": "01e2c4d7ead0909655a4f7ddd2e40afa16ee8356e28c0bf04ed935523e16224a",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-pc-windows-msvc.tar.xz": "dc59294536edf99e1b12115614b7f14279efc14b4f691047412d4c9ad3b88bca",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-sun-solaris.tar.gz": "6476119d70a735a79bec7ddfe4de4df0e0762d8c5d676ddb48c0410c3988d6bf",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-sun-solaris.tar.xz": "a9b074effd294320086d7118c6ed547f5db1515cc3a37b1cb0a665f8a685f6a0",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-freebsd.tar.gz": "e716ff3944cd42aad89d8763580006536180ab2d66ada52d1a54c65c1eaed5ae",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-freebsd.tar.xz": "1ac18e011113e26f6a17568c91d80f424ad86b069f5fa7710f2d87ca93ea3698",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-illumos.tar.gz": "b2640f80f541539ca9406b66bfc03ce7fb18b7089528d72a973b916f35c6b4ec",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-illumos.tar.xz": "000896e51a50434ab2bc8ea38b91597812c8ba5a5d0945bab94d6e00d7d38bd4",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-linux-gnu.tar.gz": "b225606cd0cf02b1f5fc77420647a28b35f22d67e565dcdbe29f0c919245565f",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-linux-gnu.tar.xz": "c5e2c9b160bd8d99514f13cfbc0e42a722fd9ca14e6aaca4b9b77731a7a48377",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-linux-gnux32.tar.gz": "97c676f76ef86ab3710d4bd7e76ca4d4e1a1c65f4206a560021e493a60652332",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-linux-gnux32.tar.xz": "878868c5e16d08c65d458c53969332d4b5765872330f0764c9355f915ecd567e",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-linux-musl.tar.gz": "eb9cda159efb9fa3f9b1e6c1e74d9bc2ef0ebd65e38824dd4e69f8c4495bf7c2",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-linux-musl.tar.xz": "a9710727ba28955deb7fbec799faed19486c9af3c7e3088ec6659a257515ffca",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-netbsd.tar.gz": "bf52a2f1d78ac7ab2355cd29d0a6dd8502cd2846c74a2b145b6ff3392fc10694",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-netbsd.tar.xz": "3533b02694652cb3f561785c9c0f0727c325c972d9df0a52603d55c80590c6db",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-none.tar.gz": "4d4030dd81a4683fbeb4b791d0788f9eb7b12b7cf032c84761609f85a5c4b891",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-none.tar.xz": "6532d834cae6d7e910ed6b41fd2a1d94687aa13afe5e11989622d6d41e0d9b93",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-redox.tar.gz": "55c1b1238918c7d61b525351afb5a575e61f8858db8f450cd7eb2202e960e68a",
+ "dist/2023-01-10/rust-std-1.66.1-x86_64-unknown-redox.tar.xz": "0a1dd8fae4585b259b603580ccdfa4eaadd826a596f137431f7b981e9e81314a",
+ "dist/2023-01-10/rustc-1.66.1-aarch64-apple-darwin.tar.gz": "ee3f7ab14cd8842abd31f21c575ef779afd2b32f584390b47886f30002cad646",
+ "dist/2023-01-10/rustc-1.66.1-aarch64-apple-darwin.tar.xz": "db6dfaa552633212ff07f3b9c7345314a896c150df7ab83e31d51b6117f38aee",
+ "dist/2023-01-10/rustc-1.66.1-aarch64-pc-windows-msvc.tar.gz": "0a3c61f0b3f71241aaf60b4a4d702a9cf0c281c67d79938624b3df7d73a36815",
+ "dist/2023-01-10/rustc-1.66.1-aarch64-pc-windows-msvc.tar.xz": "c5a4e13532df845b81d29b5471d7af6f1e4037ea18285d3a291cb38e5e9b1cc4",
+ "dist/2023-01-10/rustc-1.66.1-aarch64-unknown-linux-gnu.tar.gz": "d268a5c65154613349d0f4d35456f0f6a62da1b94490bf63930405d077a3a1df",
+ "dist/2023-01-10/rustc-1.66.1-aarch64-unknown-linux-gnu.tar.xz": "b4d842594ba11a84712c2d1bbf7f7945cfcc2485c72861a23b488fefba5c6a45",
+ "dist/2023-01-10/rustc-1.66.1-aarch64-unknown-linux-musl.tar.gz": "545fdf7f981d3d1928c9075f6645a75425196c569605b6a4f58737323ee95e35",
+ "dist/2023-01-10/rustc-1.66.1-aarch64-unknown-linux-musl.tar.xz": "f002ee293348f6e9199d2ee4aa225a3d31d28d062c0b471848d2e679555df30e",
+ "dist/2023-01-10/rustc-1.66.1-arm-unknown-linux-gnueabi.tar.gz": "09235884c8b7779fff62e15efef97b2f894970df7fc3159ed526822bb9720f46",
+ "dist/2023-01-10/rustc-1.66.1-arm-unknown-linux-gnueabi.tar.xz": "6941f802e07d43af7f0f5e02c4357d989848658e59ce5e6dc6b69e16ca80b1c9",
+ "dist/2023-01-10/rustc-1.66.1-arm-unknown-linux-gnueabihf.tar.gz": "3d5afab28d52fc4d5e2d27c937a45b3ff287833d104ee264d3dc010306fdaf18",
+ "dist/2023-01-10/rustc-1.66.1-arm-unknown-linux-gnueabihf.tar.xz": "ea8111d77e69635dbd1c7e0fd6ff82ee094a8f6b7aa2c8a4a97b1b8156a266c4",
+ "dist/2023-01-10/rustc-1.66.1-armv7-unknown-linux-gnueabihf.tar.gz": "37b5574893a636f8ac6a506b8b7fcda0fae23996ed86d9bc8bc330ac95e96abf",
+ "dist/2023-01-10/rustc-1.66.1-armv7-unknown-linux-gnueabihf.tar.xz": "d6da5f660c1b7f43d22f23aac31208c884e174463ffbc8c62760fc971defe031",
+ "dist/2023-01-10/rustc-1.66.1-i686-pc-windows-gnu.tar.gz": "e2e05e010cd8ac7b8fb034c521fd074cd60490809ca03954afd0393a25e57c9e",
+ "dist/2023-01-10/rustc-1.66.1-i686-pc-windows-gnu.tar.xz": "73a88acba26d8b381c8a2c4afdd734af88729addaaf4011fb38a6347f2775b0d",
+ "dist/2023-01-10/rustc-1.66.1-i686-pc-windows-msvc.tar.gz": "7b2148a13a7b156a3758dc5c2704621cc9c4017a9697b412ec8df00fe099c0d3",
+ "dist/2023-01-10/rustc-1.66.1-i686-pc-windows-msvc.tar.xz": "45ebedb47b8d7acbfef37a734c321b86d1e9f2344295ee10705771d6ebb005a1",
+ "dist/2023-01-10/rustc-1.66.1-i686-unknown-linux-gnu.tar.gz": "61647bf6cf5d0210c069e05f0b9ebad41f44f3c15b44a3a4543e14e64fff75b9",
+ "dist/2023-01-10/rustc-1.66.1-i686-unknown-linux-gnu.tar.xz": "e2ab464f43d6319ddb9796cbfacd444dc40f3d0e7503d672c23ecbe0daf11e1c",
+ "dist/2023-01-10/rustc-1.66.1-mips-unknown-linux-gnu.tar.gz": "b07133f2a27a8fdb0fd78eb8c40d671dffe2154714d07fa673b52beef438b257",
+ "dist/2023-01-10/rustc-1.66.1-mips-unknown-linux-gnu.tar.xz": "64ad92525ae1f018e08c055d7892e0fc613437bde8cf614b1c2a8986488290e7",
+ "dist/2023-01-10/rustc-1.66.1-mips64-unknown-linux-gnuabi64.tar.gz": "5428ceca3575c45fdab97c7d605b2dcb6c75bdd60f33a66ea187824c490b67eb",
+ "dist/2023-01-10/rustc-1.66.1-mips64-unknown-linux-gnuabi64.tar.xz": "c7f4cdbc41c5ecffc818a068000828e62bbbb911bd3626a2a44e22b6c5691bf9",
+ "dist/2023-01-10/rustc-1.66.1-mips64el-unknown-linux-gnuabi64.tar.gz": "79cbffb9650674cca72b9975485b40aba77181258d7e4e453b3453eaf979d8d6",
+ "dist/2023-01-10/rustc-1.66.1-mips64el-unknown-linux-gnuabi64.tar.xz": "d7b41cca2df9dd7241794b32312879d00eeaae74dfae5966d0eb3ea73532aeaa",
+ "dist/2023-01-10/rustc-1.66.1-mipsel-unknown-linux-gnu.tar.gz": "7f8dd076bb05f6eec6bd1c53ed28f8f81670438b3494bf2e89a1bb70d4129e12",
+ "dist/2023-01-10/rustc-1.66.1-mipsel-unknown-linux-gnu.tar.xz": "f2674d60ce52c49048e9823af57aae24bb6722e8998783819ec884222caeccf3",
+ "dist/2023-01-10/rustc-1.66.1-powerpc-unknown-linux-gnu.tar.gz": "ad825c820a4cd4ed1a981bed9e1994d02b1c67e58539abcd02f41ede86c6724a",
+ "dist/2023-01-10/rustc-1.66.1-powerpc-unknown-linux-gnu.tar.xz": "ff16d02c100086175b9fbcfff4d3705fb4f5b58a6506ec7667dc86c56b8bb3c7",
+ "dist/2023-01-10/rustc-1.66.1-powerpc64-unknown-linux-gnu.tar.gz": "7b77993bc0a308676fdc2f5ced01497380acceabd0eb93ea313041f6a6a6a72e",
+ "dist/2023-01-10/rustc-1.66.1-powerpc64-unknown-linux-gnu.tar.xz": "f5bff79d517e2f721839462881331bdc1b8323a434f4ebe0529f93213adb2a24",
+ "dist/2023-01-10/rustc-1.66.1-powerpc64le-unknown-linux-gnu.tar.gz": "95d8313e5035247af9e3a1605571fb6e4cb941ca2f8cba6d0aebcfb74dca1f20",
+ "dist/2023-01-10/rustc-1.66.1-powerpc64le-unknown-linux-gnu.tar.xz": "3b4322b519b0f7fbcf88511b2061be1499921517d810d7696be58a16467d4589",
+ "dist/2023-01-10/rustc-1.66.1-riscv64gc-unknown-linux-gnu.tar.gz": "0f30541631c2a172be27a8eae75ab683e029f762837120aed0e135b142cccdea",
+ "dist/2023-01-10/rustc-1.66.1-riscv64gc-unknown-linux-gnu.tar.xz": "84bea70d3acb6af04ae4c0f49f904bba4e2644b92c5996aacbafd7610dd0e147",
+ "dist/2023-01-10/rustc-1.66.1-s390x-unknown-linux-gnu.tar.gz": "6fae28f0b21dab788d24f6bca4f3e4f0551d5dfe4ab37f90066b6072c73df524",
+ "dist/2023-01-10/rustc-1.66.1-s390x-unknown-linux-gnu.tar.xz": "25a047db8ec0627bb7054eafe6edca6ce4c473b30d6766b30cbff1c536d0673b",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-apple-darwin.tar.gz": "1cc7b8373ec086816ed53ea0e467fbbb1b38cb39dde50a695f8ff103992dd59f",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-apple-darwin.tar.xz": "ed17239ee1d37d5cd3e0883378d9f6c6935d783464466fef2658c14deac229ce",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-pc-windows-gnu.tar.gz": "a8b3b9c368664c03544ae06dfb3400ad2418fedfff5b94d968bdf9584d548c65",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-pc-windows-gnu.tar.xz": "0bbd030dc3256e5ac187411ae2a74eb59a03a38f08db07f4d077ee0c3147855c",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-pc-windows-msvc.tar.gz": "ca5028ece5f72dfee15fda992901867a5fc37de2fc822afa9974619ab61ec0d6",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-pc-windows-msvc.tar.xz": "9d9b701d33849290d3e695cadef0d5c39ef157e3f22100411f44db0c098afb2d",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-unknown-freebsd.tar.gz": "c74a5535f77a5c731f5a47f93aced4e0e68a5ab195ef99ce6e7f84d4e90d7aab",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-unknown-freebsd.tar.xz": "e5e925f315ea39f8605a15d39d3b096fd3ebef01b266a28dd945222e576ba49e",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-unknown-illumos.tar.gz": "24e369cfda367a9813cee996d1da5d2779b05ab6a6e1402df8437284330422ba",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-unknown-illumos.tar.xz": "91c77bbf1be084d79f0d1e0732365fd2e81ca175c3785786c435ab4635eee74a",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-unknown-linux-gnu.tar.gz": "a3aa1c42ca384fa3a0cb6817d00affb47c747c28a92072d2353bd103c9973a03",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-unknown-linux-gnu.tar.xz": "242855e2626860aede6957dc56481cc02acf8cad12fa5bbbcbd93f9c51f0b3ad",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-unknown-linux-musl.tar.gz": "4fc5a7374dcbe53f5ffe7b14c47191054926e9ee4988076f58e3c0b0effc3878",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-unknown-linux-musl.tar.xz": "0f476542c8a6caa9082b4f8a23cff70c58b96fec4f732904310aaa86c90cec9a",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-unknown-netbsd.tar.gz": "8fe64b9a8372c337aa95d486652d3ea40c27894219aca810b8cbb8865701ab17",
+ "dist/2023-01-10/rustc-1.66.1-x86_64-unknown-netbsd.tar.xz": "ef23b47622d92ed1a33e3f1315ae62e392bd80d4ac87639daf26ca958c7941fa"
}
}
diff --git a/src/test/assembly/asm/aarch64-el2vmsa.rs b/src/test/assembly/asm/aarch64-el2vmsa.rs
new file mode 100644
index 000000000..1908ffb8f
--- /dev/null
+++ b/src/test/assembly/asm/aarch64-el2vmsa.rs
@@ -0,0 +1,37 @@
+// assembly-output: emit-asm
+// compile-flags: --target aarch64-unknown-linux-gnu
+// needs-llvm-components: aarch64
+
+#![feature(no_core, lang_items, rustc_attrs)]
+#![crate_type = "rlib"]
+#![no_core]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+ () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+// CHECK-LABEL: ttbr0_el2:
+#[no_mangle]
+pub fn ttbr0_el2() {
+ // CHECK: //APP
+ // CHECK-NEXT: msr TTBR0_EL2, x0
+ // CHECK-NEXT: //NO_APP
+ unsafe {
+ asm!("msr ttbr0_el2, x0");
+ }
+}
+
+// CHECK-LABEL: vttbr_el2:
+#[no_mangle]
+pub fn vttbr_el2() {
+ // CHECK: //APP
+ // CHECK-NEXT: msr VTTBR_EL2, x0
+ // CHECK-NEXT: //NO_APP
+ unsafe {
+ asm!("msr vttbr_el2, x0");
+ }
+}
diff --git a/src/test/assembly/is_aligned.rs b/src/test/assembly/is_aligned.rs
new file mode 100644
index 000000000..04b5de834
--- /dev/null
+++ b/src/test/assembly/is_aligned.rs
@@ -0,0 +1,58 @@
+// assembly-output: emit-asm
+// min-llvm-version: 14.0
+// only-x86_64
+// revisions: opt-speed opt-size
+// [opt-speed] compile-flags: -Copt-level=1
+// [opt-size] compile-flags: -Copt-level=s
+#![crate_type="rlib"]
+
+#![feature(core_intrinsics)]
+#![feature(pointer_is_aligned)]
+
+// CHECK-LABEL: is_aligned_to_unchecked
+// CHECK: decq
+// CHECK-NEXT: testq
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub unsafe fn is_aligned_to_unchecked(ptr: *const u8, align: usize) -> bool {
+ unsafe {
+ std::intrinsics::assume(align.is_power_of_two())
+ }
+ ptr.is_aligned_to(align)
+}
+
+// CHECK-LABEL: is_aligned_1
+// CHECK: movb $1
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_1(ptr: *const u8) -> bool {
+ ptr.is_aligned()
+}
+
+// CHECK-LABEL: is_aligned_2
+// CHECK: testb $1
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_2(ptr: *const u16) -> bool {
+ ptr.is_aligned()
+}
+
+// CHECK-LABEL: is_aligned_4
+// CHECK: testb $3
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_4(ptr: *const u32) -> bool {
+ ptr.is_aligned()
+}
+
+// CHECK-LABEL: is_aligned_8
+// CHECK: testb $7
+// CHECK-NEXT: sete
+// CHECK: retq
+#[no_mangle]
+pub fn is_aligned_8(ptr: *const u64) -> bool {
+ ptr.is_aligned()
+}
diff --git a/src/test/assembly/sparc-struct-abi.rs b/src/test/assembly/sparc-struct-abi.rs
index 6a898b297..6309dd420 100644
--- a/src/test/assembly/sparc-struct-abi.rs
+++ b/src/test/assembly/sparc-struct-abi.rs
@@ -44,12 +44,16 @@ pub unsafe extern "C" fn callee(arg: Franta) {
tst_use(arg.b);
tst_use(arg.c);
tst_use(arg.d);
+ tail_call_avoidance_fn();
}
extern "C" {
fn opaque_callee(arg: Franta, intarg: i32);
fn tst_use(arg: f32);
fn clobber();
+ // This exists so that post-https://reviews.llvm.org/D138741 LLVM doesn't
+ // tail-call away some of our assertions.
+ fn tail_call_avoidance_fn();
}
#[no_mangle]
@@ -62,4 +66,5 @@ pub unsafe extern "C" fn caller() {
// CHECK: call opaque_callee
// CHECK: mov 3, %o2
opaque_callee(Franta { a: 1.0, b: 2.0, c: 3.0, d: 4.0 }, 3);
+ tail_call_avoidance_fn();
}
diff --git a/src/test/assembly/strict_provenance.rs b/src/test/assembly/strict_provenance.rs
new file mode 100644
index 000000000..01f1957d5
--- /dev/null
+++ b/src/test/assembly/strict_provenance.rs
@@ -0,0 +1,37 @@
+// assembly-output: emit-asm
+// compile-flags: -Copt-level=1
+// only-x86_64
+// min-llvm-version: 15.0
+#![crate_type = "rlib"]
+
+// CHECK-LABEL: old_style
+// CHECK: movq %{{.*}}, %rax
+// CHECK: orq $1, %rax
+// CHECK: retq
+#[no_mangle]
+pub fn old_style(a: *mut u8) -> *mut u8 {
+ (a as usize | 1) as *mut u8
+}
+
+// CHECK-LABEL: cheri_compat
+// CHECK: movq %{{.*}}, %rax
+// CHECK: orq $1, %rax
+// CHECK: retq
+#[no_mangle]
+pub fn cheri_compat(a: *mut u8) -> *mut u8 {
+ let old = a as usize;
+ let new = old | 1;
+ let diff = new.wrapping_sub(old);
+ a.wrapping_add(diff)
+}
+
+// CHECK-LABEL: definitely_not_a_null_pointer
+// CHECK: movq %{{.*}}, %rax
+// CHECK: orq $1, %rax
+// CHECK: retq
+#[no_mangle]
+pub fn definitely_not_a_null_pointer(a: *mut u8) -> *mut u8 {
+ let old = a as usize;
+ let new = old | 1;
+ a.wrapping_sub(old).wrapping_add(new)
+}
diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs
index b4fda5f8c..9061d7432 100644
--- a/src/test/codegen/abi-efiapi.rs
+++ b/src/test/codegen/abi-efiapi.rs
@@ -27,7 +27,7 @@ trait Copy { }
//x86_64: define win64cc void @has_efiapi
//i686: define void @has_efiapi
//aarch64: define dso_local void @has_efiapi
-//arm: define dso_local void @has_efiapi
+//arm: define dso_local arm_aapcscc void @has_efiapi
//riscv: define dso_local void @has_efiapi
#[no_mangle]
pub extern "efiapi" fn has_efiapi() {}
diff --git a/src/test/codegen/async-fn-debug-awaitee-field.rs b/src/test/codegen/async-fn-debug-awaitee-field.rs
index 909cd0062..bc2686158 100644
--- a/src/test/codegen/async-fn-debug-awaitee-field.rs
+++ b/src/test/codegen/async-fn-debug-awaitee-field.rs
@@ -11,12 +11,14 @@ async fn async_fn_test() {
foo().await;
}
-// NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}",
+// NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[GEN_SCOPE:![0-9]*]],
// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
+// NONMSVC: [[GEN_SCOPE:!.*]] = !DINamespace(name: "async_fn_test",
// CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
-// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<async_fn_debug_awaitee_field::foo::{async_fn_env#0}>",
-// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
+// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[AWAITEE_SCOPE:![0-9]*]],
+// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0>",
+// NONMSVC: [[AWAITEE_SCOPE]] = !DINamespace(name: "foo",
fn main() {
let _fn = async_fn_test();
diff --git a/src/test/codegen/auxiliary/extern_decl.rs b/src/test/codegen/auxiliary/extern_decl.rs
new file mode 100644
index 000000000..edc483518
--- /dev/null
+++ b/src/test/codegen/auxiliary/extern_decl.rs
@@ -0,0 +1,11 @@
+// Auxiliary crate that exports a function and static. Both always
+// evaluate to `71`. We force mutability on the static to prevent
+// it from being inlined as constant.
+
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub fn extern_fn() -> u8 { unsafe { extern_static } }
+
+#[no_mangle]
+pub static mut extern_static: u8 = 71;
diff --git a/src/test/codegen/auxiliary/static_dllimport_aux.rs b/src/test/codegen/auxiliary/static_dllimport_aux.rs
new file mode 100644
index 000000000..afb0dc42f
--- /dev/null
+++ b/src/test/codegen/auxiliary/static_dllimport_aux.rs
@@ -0,0 +1,13 @@
+use std::sync::atomic::{AtomicPtr, Ordering};
+
+#[inline(always)]
+pub fn memrchr() {
+ fn detect() {}
+
+ static CROSS_CRATE_STATIC_ITEM: AtomicPtr<()> = AtomicPtr::new(detect as *mut ());
+
+ unsafe {
+ let fun = CROSS_CRATE_STATIC_ITEM.load(Ordering::SeqCst);
+ std::mem::transmute::<*mut (), fn()>(fun)()
+ }
+}
diff --git a/src/test/codegen/avr/avr-func-addrspace.rs b/src/test/codegen/avr/avr-func-addrspace.rs
index a038dfe76..cbbcfad3e 100644
--- a/src/test/codegen/avr/avr-func-addrspace.rs
+++ b/src/test/codegen/avr/avr-func-addrspace.rs
@@ -19,6 +19,8 @@ pub trait Sized { }
pub trait Copy { }
#[lang = "receiver"]
pub trait Receiver { }
+#[lang = "tuple_trait"]
+pub trait Tuple { }
pub struct Result<T, E> { _a: T, _b: E }
@@ -29,7 +31,7 @@ impl Copy for &usize {}
pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {}
#[lang = "fn_once"]
-pub trait FnOnce<Args> {
+pub trait FnOnce<Args: Tuple> {
#[lang = "fn_once_output"]
type Output;
@@ -37,24 +39,16 @@ pub trait FnOnce<Args> {
}
#[lang = "fn_mut"]
-pub trait FnMut<Args> : FnOnce<Args> {
+pub trait FnMut<Args: Tuple> : FnOnce<Args> {
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}
#[lang = "fn"]
-pub trait Fn<Args>: FnOnce<Args> {
+pub trait Fn<Args: Tuple>: FnOnce<Args> {
/// Performs the call operation.
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}
-impl<'a, A, R> FnOnce<A> for &'a fn(A) -> R {
- type Output = R;
-
- extern "rust-call" fn call_once(self, args: A) -> R {
- (*self)(args)
- }
-}
-
pub static mut STORAGE_FOO: fn(&usize, &mut u32) -> Result<(), ()> = arbitrary_black_box;
pub static mut STORAGE_BAR: u32 = 12;
diff --git a/src/test/codegen/dllimports/main.rs b/src/test/codegen/dllimports/main.rs
index bb3134e81..ab599992f 100644
--- a/src/test/codegen/dllimports/main.rs
+++ b/src/test/codegen/dllimports/main.rs
@@ -1,17 +1,6 @@
// This test is for *-windows-msvc only.
-// ignore-android
-// ignore-dragonfly
-// ignore-emscripten
-// ignore-freebsd
+// only-windows
// ignore-gnu
-// ignore-haiku
-// ignore-ios
-// ignore-linux
-// ignore-macos
-// ignore-netbsd
-// ignore-openbsd
-// ignore-solaris
-// ignore-sgx no dynamic linking
// aux-build:dummy.rs
// aux-build:wrapper.rs
diff --git a/src/test/codegen/enum-bounds-check-derived-idx.rs b/src/test/codegen/enum-bounds-check-derived-idx.rs
index fe02aeb5f..aa66c2ed0 100644
--- a/src/test/codegen/enum-bounds-check-derived-idx.rs
+++ b/src/test/codegen/enum-bounds-check-derived-idx.rs
@@ -12,15 +12,13 @@ pub enum Bar {
// CHECK-LABEL: @lookup_inc
#[no_mangle]
pub fn lookup_inc(buf: &[u8; 5], f: Bar) -> u8 {
- // FIXME: panic check can be removed by adding the assumes back after https://github.com/rust-lang/rust/pull/98332
- // CHECK: panic_bounds_check
+ // CHECK-NOT: panic_bounds_check
buf[f as usize + 1]
}
// CHECK-LABEL: @lookup_dec
#[no_mangle]
pub fn lookup_dec(buf: &[u8; 5], f: Bar) -> u8 {
- // FIXME: panic check can be removed by adding the assumes back after https://github.com/rust-lang/rust/pull/98332
- // CHECK: panic_bounds_check
+ // CHECK-NOT: panic_bounds_check
buf[f as usize - 1]
}
diff --git a/src/test/codegen/enum-bounds-check-issue-13926.rs b/src/test/codegen/enum-bounds-check-issue-13926.rs
index 1aec41d54..b26945bc5 100644
--- a/src/test/codegen/enum-bounds-check-issue-13926.rs
+++ b/src/test/codegen/enum-bounds-check-issue-13926.rs
@@ -13,7 +13,6 @@ pub enum Exception {
// CHECK-LABEL: @access
#[no_mangle]
pub fn access(array: &[usize; 12], exc: Exception) -> usize {
- // FIXME: panic check can be removed by adding the assumes back after https://github.com/rust-lang/rust/pull/98332
- // CHECK: panic_bounds_check
+ // CHECK-NOT: panic_bounds_check
array[(exc as u8 - 4) as usize]
}
diff --git a/src/test/codegen/enum-bounds-check.rs b/src/test/codegen/enum-bounds-check.rs
index f85c6817d..17322d591 100644
--- a/src/test/codegen/enum-bounds-check.rs
+++ b/src/test/codegen/enum-bounds-check.rs
@@ -21,7 +21,6 @@ pub enum Bar {
// CHECK-LABEL: @lookup_unmodified
#[no_mangle]
pub fn lookup_unmodified(buf: &[u8; 5], f: Bar) -> u8 {
- // FIXME: panic check can be removed by adding the assumes back after https://github.com/rust-lang/rust/pull/98332
- // CHECK: panic_bounds_check
+ // CHECK-NOT: panic_bounds_check
buf[f as usize]
}
diff --git a/src/test/codegen/enum-match.rs b/src/test/codegen/enum-match.rs
new file mode 100644
index 000000000..44f1b408d
--- /dev/null
+++ b/src/test/codegen/enum-match.rs
@@ -0,0 +1,109 @@
+// compile-flags: -Copt-level=1
+// only-x86_64
+
+#![crate_type = "lib"]
+
+// Check each of the 3 cases for `codegen_get_discr`.
+
+// Case 0: One tagged variant.
+pub enum Enum0 {
+ A(bool),
+ B,
+}
+
+// CHECK: define i8 @match0{{.*}}
+// CHECK-NEXT: start:
+// CHECK-NEXT: %1 = icmp eq i8 %0, 2
+// CHECK-NEXT: %2 = and i8 %0, 1
+// CHECK-NEXT: %.0 = select i1 %1, i8 13, i8 %2
+#[no_mangle]
+pub fn match0(e: Enum0) -> u8 {
+ use Enum0::*;
+ match e {
+ A(b) => b as u8,
+ B => 13,
+ }
+}
+
+// Case 1: Niche values are on a boundary for `range`.
+pub enum Enum1 {
+ A(bool),
+ B,
+ C,
+}
+
+// CHECK: define i8 @match1{{.*}}
+// CHECK-NEXT: start:
+// CHECK-NEXT: %1 = {{.*}}call i8 @llvm.usub.sat.i8(i8 %0, i8 1)
+// CHECK-NEXT: switch i8 %1, label {{.*}} [
+#[no_mangle]
+pub fn match1(e: Enum1) -> u8 {
+ use Enum1::*;
+ match e {
+ A(b) => b as u8,
+ B => 13,
+ C => 100,
+ }
+}
+
+// Case 2: Special cases don't apply.
+pub enum X {
+ _2=2, _3, _4, _5, _6, _7, _8, _9, _10, _11,
+ _12, _13, _14, _15, _16, _17, _18, _19, _20,
+ _21, _22, _23, _24, _25, _26, _27, _28, _29,
+ _30, _31, _32, _33, _34, _35, _36, _37, _38,
+ _39, _40, _41, _42, _43, _44, _45, _46, _47,
+ _48, _49, _50, _51, _52, _53, _54, _55, _56,
+ _57, _58, _59, _60, _61, _62, _63, _64, _65,
+ _66, _67, _68, _69, _70, _71, _72, _73, _74,
+ _75, _76, _77, _78, _79, _80, _81, _82, _83,
+ _84, _85, _86, _87, _88, _89, _90, _91, _92,
+ _93, _94, _95, _96, _97, _98, _99, _100, _101,
+ _102, _103, _104, _105, _106, _107, _108, _109,
+ _110, _111, _112, _113, _114, _115, _116, _117,
+ _118, _119, _120, _121, _122, _123, _124, _125,
+ _126, _127, _128, _129, _130, _131, _132, _133,
+ _134, _135, _136, _137, _138, _139, _140, _141,
+ _142, _143, _144, _145, _146, _147, _148, _149,
+ _150, _151, _152, _153, _154, _155, _156, _157,
+ _158, _159, _160, _161, _162, _163, _164, _165,
+ _166, _167, _168, _169, _170, _171, _172, _173,
+ _174, _175, _176, _177, _178, _179, _180, _181,
+ _182, _183, _184, _185, _186, _187, _188, _189,
+ _190, _191, _192, _193, _194, _195, _196, _197,
+ _198, _199, _200, _201, _202, _203, _204, _205,
+ _206, _207, _208, _209, _210, _211, _212, _213,
+ _214, _215, _216, _217, _218, _219, _220, _221,
+ _222, _223, _224, _225, _226, _227, _228, _229,
+ _230, _231, _232, _233, _234, _235, _236, _237,
+ _238, _239, _240, _241, _242, _243, _244, _245,
+ _246, _247, _248, _249, _250, _251, _252, _253,
+}
+
+pub enum Enum2 {
+ A(X),
+ B,
+ C,
+ D,
+ E,
+}
+
+// CHECK: define i8 @match2{{.*}}
+// CHECK-NEXT: start:
+// CHECK-NEXT: %1 = add i8 %0, 2
+// CHECK-NEXT: %2 = zext i8 %1 to i64
+// CHECK-NEXT: %3 = icmp ult i8 %1, 4
+// CHECK-NEXT: %4 = add nuw nsw i64 %2, 1
+// CHECK-NEXT: %_2 = select i1 %3, i64 %4, i64 0
+// CHECK-NEXT: switch i64 %_2, label {{.*}} [
+#[no_mangle]
+pub fn match2(e: Enum2) -> u8 {
+ use Enum2::*;
+ match e {
+ A(b) => b as u8,
+ B => 13,
+ C => 100,
+ D => 200,
+ E => 250,
+ }
+}
diff --git a/src/test/codegen/ffi-const.rs b/src/test/codegen/ffi-const.rs
index d9cfa5429..937205034 100644
--- a/src/test/codegen/ffi-const.rs
+++ b/src/test/codegen/ffi-const.rs
@@ -7,6 +7,7 @@ pub fn bar() { unsafe { foo() } }
extern "C" {
// CHECK-LABEL: declare{{.*}}void @foo()
// CHECK-SAME: [[ATTRS:#[0-9]+]]
- // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readnone{{.*}} }
+ // The attribute changed from `readnone` to `memory(none)` with LLVM 16.0.
+ // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readnone|memory\(none\)}}{{.*}} }
#[ffi_const] pub fn foo();
}
diff --git a/src/test/codegen/ffi-pure.rs b/src/test/codegen/ffi-pure.rs
index 5bdb2ee91..2ed735813 100644
--- a/src/test/codegen/ffi-pure.rs
+++ b/src/test/codegen/ffi-pure.rs
@@ -7,6 +7,7 @@ pub fn bar() { unsafe { foo() } }
extern "C" {
// CHECK-LABEL: declare{{.*}}void @foo()
// CHECK-SAME: [[ATTRS:#[0-9]+]]
- // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}readonly{{.*}} }
+ // The attribute changed from `readonly` to `memory(read)` with LLVM 16.0.
+ // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readonly|memory\(read\)}}{{.*}} }
#[ffi_pure] pub fn foo();
}
diff --git a/src/test/codegen/issue-103285-ptr-addr-overflow-check.rs b/src/test/codegen/issue-103285-ptr-addr-overflow-check.rs
new file mode 100644
index 000000000..a3499babe
--- /dev/null
+++ b/src/test/codegen/issue-103285-ptr-addr-overflow-check.rs
@@ -0,0 +1,16 @@
+// compile-flags: -O -C debug-assertions=yes
+
+#![crate_type = "lib"]
+#![feature(strict_provenance)]
+
+#[no_mangle]
+pub fn test(src: *const u8, dst: *const u8) -> usize {
+ // CHECK-LABEL: @test(
+ // CHECK-NOT: panic
+ let src_usize = src.addr();
+ let dst_usize = dst.addr();
+ if src_usize > dst_usize {
+ return src_usize - dst_usize;
+ }
+ return 0;
+}
diff --git a/src/test/codegen/issue-37945.rs b/src/test/codegen/issue-37945.rs
index 12fa1e9e5..fe54375bb 100644
--- a/src/test/codegen/issue-37945.rs
+++ b/src/test/codegen/issue-37945.rs
@@ -15,7 +15,7 @@ use std::slice::Iter;
pub fn is_empty_1(xs: Iter<f32>) -> bool {
// CHECK-LABEL: @is_empty_1(
// CHECK-NEXT: start:
-// CHECK-NEXT: [[A:%.*]] = icmp ne {{i32\*|ptr}} %xs.1, null
+// CHECK-NEXT: [[A:%.*]] = icmp ne {{i32\*|ptr}} {{%xs.0|%xs.1}}, null
// CHECK-NEXT: tail call void @llvm.assume(i1 [[A]])
// The order between %xs.0 and %xs.1 on the next line doesn't matter
// and different LLVM versions produce different order.
@@ -28,7 +28,7 @@ pub fn is_empty_1(xs: Iter<f32>) -> bool {
pub fn is_empty_2(xs: Iter<f32>) -> bool {
// CHECK-LABEL: @is_empty_2
// CHECK-NEXT: start:
-// CHECK-NEXT: [[C:%.*]] = icmp ne {{i32\*|ptr}} %xs.1, null
+// CHECK-NEXT: [[C:%.*]] = icmp ne {{i32\*|ptr}} {{%xs.0|%xs.1}}, null
// CHECK-NEXT: tail call void @llvm.assume(i1 [[C]])
// The order between %xs.0 and %xs.1 on the next line doesn't matter
// and different LLVM versions produce different order.
diff --git a/src/test/codegen/issue-81408-dllimport-thinlto-windows.rs b/src/test/codegen/issue-81408-dllimport-thinlto-windows.rs
new file mode 100644
index 000000000..0b6ab4f7e
--- /dev/null
+++ b/src/test/codegen/issue-81408-dllimport-thinlto-windows.rs
@@ -0,0 +1,15 @@
+// compile-flags: -O -C lto=thin -C prefer-dynamic=no
+// only-windows
+// aux-build:static_dllimport_aux.rs
+
+// Test that on Windows, when performing ThinLTO, we do not mark cross-crate static items with
+// dllimport because lld does not fix the symbol names for us.
+
+extern crate static_dllimport_aux;
+
+// CHECK-LABEL: @{{.+}}CROSS_CRATE_STATIC_ITEM{{.+}} =
+// CHECK-SAME: external local_unnamed_addr global %"{{.+}}AtomicPtr
+
+pub fn main() {
+ static_dllimport_aux::memrchr();
+}
diff --git a/src/test/codegen/iter-repeat-n-trivial-drop.rs b/src/test/codegen/iter-repeat-n-trivial-drop.rs
new file mode 100644
index 000000000..20e1d9b4d
--- /dev/null
+++ b/src/test/codegen/iter-repeat-n-trivial-drop.rs
@@ -0,0 +1,56 @@
+// compile-flags: -O
+// only-x86_64
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+#![feature(iter_repeat_n)]
+
+#[derive(Clone)]
+pub struct NotCopy(u16);
+
+impl Drop for NotCopy {
+ fn drop(&mut self) {}
+}
+
+// For a type where `Drop::drop` doesn't do anything observable and a clone is the
+// same as a move, make sure that the extra case for the last item disappears.
+
+#[no_mangle]
+// CHECK-LABEL: @iter_repeat_n_next
+pub fn iter_repeat_n_next(it: &mut std::iter::RepeatN<NotCopy>) -> Option<NotCopy> {
+ // CHECK-NEXT: start:
+ // CHECK-NOT: br
+ // CHECK: %[[COUNT:.+]] = load i64
+ // CHECK-NEXT: %[[COUNT_ZERO:.+]] = icmp eq i64 %[[COUNT]], 0
+ // CHECK-NEXT: br i1 %[[COUNT_ZERO]], label %[[EMPTY:.+]], label %[[NOT_EMPTY:.+]]
+
+ // CHECK: [[NOT_EMPTY]]:
+ // CHECK-NEXT: %[[DEC:.+]] = add i64 %[[COUNT]], -1
+ // CHECK-NEXT: store i64 %[[DEC]]
+ // CHECK-NOT: br
+ // CHECK: %[[VAL:.+]] = load i16
+ // CHECK-NEXT: br label %[[EMPTY]]
+
+ // CHECK: [[EMPTY]]:
+ // CHECK-NOT: br
+ // CHECK: phi i16 [ undef, %start ], [ %[[VAL]], %[[NOT_EMPTY]] ]
+ // CHECK-NOT: br
+ // CHECK: ret
+
+ it.next()
+}
+
+// And as a result, using the iterator can optimize without special cases for
+// the last iteration, like `memset`ing all the items in one call.
+
+#[no_mangle]
+// CHECK-LABEL: @vec_extend_via_iter_repeat_n
+pub fn vec_extend_via_iter_repeat_n() -> Vec<u8> {
+ // CHECK: %[[ADDR:.+]] = tail call dereferenceable_or_null(1234) ptr @__rust_alloc(i64 1234, i64 1)
+ // CHECK: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(1234) %[[ADDR]], i8 42, i64 1234,
+
+ let n = 1234_usize;
+ let mut v = Vec::with_capacity(n);
+ v.extend(std::iter::repeat_n(42_u8, n));
+ v
+}
diff --git a/src/test/codegen/match-optimized.rs b/src/test/codegen/match-optimized.rs
new file mode 100644
index 000000000..36402cc73
--- /dev/null
+++ b/src/test/codegen/match-optimized.rs
@@ -0,0 +1,60 @@
+// compile-flags: -C no-prepopulate-passes -O
+
+#![crate_type = "lib"]
+
+pub enum E {
+ A,
+ B,
+ C,
+}
+
+// CHECK-LABEL: @exhaustive_match
+#[no_mangle]
+pub fn exhaustive_match(e: E) -> u8 {
+// CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [
+// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]]
+// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]]
+// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[C:[a-zA-Z0-9_]+]]
+// CHECK-NEXT: ]
+// CHECK: [[OTHERWISE]]:
+// CHECK-NEXT: unreachable
+//
+// CHECK: [[A]]:
+// CHECK-NEXT: store i8 0, {{i8\*|ptr}} %1, align 1
+// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
+// CHECK: [[B]]:
+// CHECK-NEXT: store i8 1, {{i8\*|ptr}} %1, align 1
+// CHECK-NEXT: br label %[[EXIT]]
+// CHECK: [[C]]:
+// CHECK-NEXT: store i8 2, {{i8\*|ptr}} %1, align 1
+// CHECK-NEXT: br label %[[EXIT]]
+ match e {
+ E::A => 0,
+ E::B => 1,
+ E::C => 2,
+ }
+}
+
+#[repr(u16)]
+pub enum E2 {
+ A = 13,
+ B = 42,
+}
+
+// For optimized code we produce a switch with an unreachable target as the `otherwise` so LLVM
+// knows the possible values. Compare with `src/test/codegen/match-unoptimized.rs`.
+
+// CHECK-LABEL: @exhaustive_match_2
+#[no_mangle]
+pub fn exhaustive_match_2(e: E2) -> u8 {
+ // CHECK: switch i16 %{{.+}}, label %[[UNREACH:.+]] [
+ // CHECK-NEXT: i16 13,
+ // CHECK-NEXT: i16 42,
+ // CHECK-NEXT: ]
+ // CHECK: [[UNREACH]]:
+ // CHECK-NEXT: unreachable
+ match e {
+ E2::A => 0,
+ E2::B => 1,
+ }
+}
diff --git a/src/test/codegen/match-unoptimized.rs b/src/test/codegen/match-unoptimized.rs
new file mode 100644
index 000000000..be40b29e3
--- /dev/null
+++ b/src/test/codegen/match-unoptimized.rs
@@ -0,0 +1,23 @@
+// compile-flags: -C no-prepopulate-passes -Copt-level=0
+
+#![crate_type = "lib"]
+
+#[repr(u16)]
+pub enum E2 {
+ A = 13,
+ B = 42,
+}
+
+// For unoptimized code we produce a `br` instead of a `switch`. Compare with
+// `src/test/codegen/match-optimized.rs`
+
+// CHECK-LABEL: @exhaustive_match_2
+#[no_mangle]
+pub fn exhaustive_match_2(e: E2) -> u8 {
+ // CHECK: %[[CMP:.+]] = icmp eq i16 %{{.+}}, 13
+ // CHECK-NEXT: br i1 %[[CMP:.+]],
+ match e {
+ E2::A => 0,
+ E2::B => 1,
+ }
+}
diff --git a/src/test/codegen/match.rs b/src/test/codegen/match.rs
deleted file mode 100644
index b203641fd..000000000
--- a/src/test/codegen/match.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-// compile-flags: -C no-prepopulate-passes
-
-#![crate_type = "lib"]
-
-pub enum E {
- A,
- B,
-}
-
-// CHECK-LABEL: @exhaustive_match
-#[no_mangle]
-pub fn exhaustive_match(e: E) -> u8 {
-// CHECK: switch{{.*}}, label %[[OTHERWISE:[a-zA-Z0-9_]+]] [
-// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[A:[a-zA-Z0-9_]+]]
-// CHECK-NEXT: i[[TY:[0-9]+]] [[DISCR:[0-9]+]], label %[[B:[a-zA-Z0-9_]+]]
-// CHECK-NEXT: ]
-// CHECK: [[OTHERWISE]]:
-// CHECK-NEXT: unreachable
-// CHECK: [[A]]:
-// CHECK-NEXT: store i8 0, {{i8\*|ptr}} %1, align 1
-// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
-// CHECK: [[B]]:
-// CHECK-NEXT: store i8 1, {{i8\*|ptr}} %1, align 1
-// CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]]
- match e {
- E::A => 0,
- E::B => 1,
- }
-}
diff --git a/src/test/codegen/mem-replace-direct-memcpy.rs b/src/test/codegen/mem-replace-direct-memcpy.rs
index 4318e926e..e8bbf0e1b 100644
--- a/src/test/codegen/mem-replace-direct-memcpy.rs
+++ b/src/test/codegen/mem-replace-direct-memcpy.rs
@@ -18,7 +18,7 @@ pub fn replace_byte(dst: &mut u8, src: u8) -> u8 {
// CHECK-NOT: call void @llvm.memcpy
// CHECK: ; core::mem::replace
// CHECK-NOT: call void @llvm.memcpy
-// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %dest, i{{.*}} 1, i1 false)
+// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{.*}} 1, i1 false)
// CHECK-NOT: call void @llvm.memcpy
-// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %dest, {{i8\*|ptr}} align 1 %src{{.*}}, i{{.*}} 1, i1 false)
+// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{.*}} 1, i1 false)
// CHECK-NOT: call void @llvm.memcpy
diff --git a/src/test/codegen/naked-nocoverage.rs b/src/test/codegen/naked-nocoverage.rs
new file mode 100644
index 000000000..91a6260bf
--- /dev/null
+++ b/src/test/codegen/naked-nocoverage.rs
@@ -0,0 +1,19 @@
+// Checks that naked functions are not instrumented by -Cinstrument-coverage.
+// Regression test for issue #105170.
+//
+// needs-asm-support
+// needs-profiler-support
+// compile-flags: -Cinstrument-coverage
+#![crate_type = "lib"]
+#![feature(naked_functions)]
+use std::arch::asm;
+
+#[naked]
+#[no_mangle]
+pub unsafe extern "C" fn f() {
+ // CHECK: define void @f()
+ // CHECK-NEXT: start:
+ // CHECK-NEXT: call void asm
+ // CHECK-NEXT: unreachable
+ asm!("", options(noreturn));
+}
diff --git a/src/test/codegen/option-nonzero-eq.rs b/src/test/codegen/option-nonzero-eq.rs
new file mode 100644
index 000000000..598dcc19b
--- /dev/null
+++ b/src/test/codegen/option-nonzero-eq.rs
@@ -0,0 +1,34 @@
+// compile-flags: -O -Zmerge-functions=disabled
+
+#![crate_type = "lib"]
+
+extern crate core;
+use core::num::{NonZeroU32, NonZeroI64};
+use core::ptr::NonNull;
+
+// CHECK-lABEL: @non_zero_eq
+#[no_mangle]
+pub fn non_zero_eq(l: Option<NonZeroU32>, r: Option<NonZeroU32>) -> bool {
+ // CHECK: start:
+ // CHECK-NEXT: icmp eq i32
+ // CHECK-NEXT: ret i1
+ l == r
+}
+
+// CHECK-lABEL: @non_zero_signed_eq
+#[no_mangle]
+pub fn non_zero_signed_eq(l: Option<NonZeroI64>, r: Option<NonZeroI64>) -> bool {
+ // CHECK: start:
+ // CHECK-NEXT: icmp eq i64
+ // CHECK-NEXT: ret i1
+ l == r
+}
+
+// CHECK-lABEL: @non_null_eq
+#[no_mangle]
+pub fn non_null_eq(l: Option<NonNull<u8>>, r: Option<NonNull<u8>>) -> bool {
+ // CHECK: start:
+ // CHECK-NEXT: icmp eq {{(i8\*|ptr)}}
+ // CHECK-NEXT: ret i1
+ l == r
+}
diff --git a/src/test/codegen/panic-abort-windows.rs b/src/test/codegen/panic-abort-windows.rs
index 9ee4bfc47..2ee29762d 100644
--- a/src/test/codegen/panic-abort-windows.rs
+++ b/src/test/codegen/panic-abort-windows.rs
@@ -1,16 +1,5 @@
-// This test is for *-windows-msvc only.
-// ignore-android
-// ignore-dragonfly
-// ignore-emscripten
-// ignore-freebsd
-// ignore-haiku
-// ignore-ios
-// ignore-linux
-// ignore-macos
-// ignore-netbsd
-// ignore-openbsd
-// ignore-solaris
-// ignore-sgx
+// This test is for *-windows only.
+// only-windows
// compile-flags: -C no-prepopulate-passes -C panic=abort -O
diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs
index 7aebd3ec7..87c8fe135 100644
--- a/src/test/codegen/repeat-trusted-len.rs
+++ b/src/test/codegen/repeat-trusted-len.rs
@@ -11,3 +11,10 @@ pub fn repeat_take_collect() -> Vec<u8> {
// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{[0-9]+}}, i8 42, i{{[0-9]+}} 100000, i1 false)
iter::repeat(42).take(100000).collect()
}
+
+// CHECK-LABEL: @repeat_with_take_collect
+#[no_mangle]
+pub fn repeat_with_take_collect() -> Vec<u8> {
+// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{[0-9]+}}, i8 13, i{{[0-9]+}} 12345, i1 false)
+ iter::repeat_with(|| 13).take(12345).collect()
+}
diff --git a/src/test/codegen/slice-iter-len-eq-zero.rs b/src/test/codegen/slice-iter-len-eq-zero.rs
index 112402825..894b0ec3d 100644
--- a/src/test/codegen/slice-iter-len-eq-zero.rs
+++ b/src/test/codegen/slice-iter-len-eq-zero.rs
@@ -9,7 +9,7 @@ type Demo = [u8; 3];
#[no_mangle]
pub fn slice_iter_len_eq_zero(y: std::slice::Iter<'_, Demo>) -> bool {
// CHECK-NOT: sub
- // CHECK: %2 = icmp eq {{i8\*|ptr}} %1, %0
+ // CHECK: %2 = icmp eq {{i8\*|ptr}} {{%1|%0}}, {{%1|%0}}
// CHECK: ret i1 %2
y.len() == 0
}
diff --git a/src/test/codegen/static-relocation-model-msvc.rs b/src/test/codegen/static-relocation-model-msvc.rs
new file mode 100644
index 000000000..b2afc7deb
--- /dev/null
+++ b/src/test/codegen/static-relocation-model-msvc.rs
@@ -0,0 +1,26 @@
+// Verify linkage of external symbols in the static relocation model on MSVC.
+//
+// compile-flags: -O -C relocation-model=static
+// aux-build: extern_decl.rs
+// only-x86_64-pc-windows-msvc
+
+#![crate_type = "rlib"]
+
+extern crate extern_decl;
+
+// The `extern_decl` definitions are imported from a statically linked rust
+// crate, thus they are expected to be marked `dso_local` without `dllimport`.
+//
+// The `access_extern()` symbol is from this compilation unit, thus we expect
+// it to be marked `dso_local` as well, given the static relocation model.
+//
+// CHECK: @extern_static = external dso_local local_unnamed_addr global i8
+// CHECK: define dso_local i8 @access_extern() {{.*}}
+// CHECK: declare dso_local i8 @extern_fn() {{.*}}
+
+#[no_mangle]
+pub fn access_extern() -> u8 {
+ unsafe {
+ extern_decl::extern_fn() + extern_decl::extern_static
+ }
+}
diff --git a/src/test/codegen/unchecked_shifts.rs b/src/test/codegen/unchecked_shifts.rs
new file mode 100644
index 000000000..60d0cb09a
--- /dev/null
+++ b/src/test/codegen/unchecked_shifts.rs
@@ -0,0 +1,66 @@
+// compile-flags: -O
+// min-llvm-version: 15.0 (LLVM 13 in CI does this differently from submodule LLVM)
+// ignore-debug (because unchecked is checked in debug)
+
+#![crate_type = "lib"]
+#![feature(unchecked_math)]
+
+// CHECK-LABEL: @unchecked_shl_unsigned_same
+#[no_mangle]
+pub unsafe fn unchecked_shl_unsigned_same(a: u32, b: u32) -> u32 {
+ // CHECK-NOT: and i32
+ // CHECK: shl i32 %a, %b
+ // CHECK-NOT: and i32
+ a.unchecked_shl(b)
+}
+
+// CHECK-LABEL: @unchecked_shl_unsigned_smaller
+#[no_mangle]
+pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 {
+ // This uses -DAG to avoid failing on irrelevant reorderings,
+ // like emitting the truncation earlier.
+
+ // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 65536
+ // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
+ // CHECK-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16
+ // CHECK-DAG: shl i16 %a, %[[TRUNC]]
+ a.unchecked_shl(b)
+}
+
+// CHECK-LABEL: @unchecked_shl_unsigned_bigger
+#[no_mangle]
+pub unsafe fn unchecked_shl_unsigned_bigger(a: u64, b: u32) -> u64 {
+ // CHECK: %[[EXT:.+]] = zext i32 %b to i64
+ // CHECK: shl i64 %a, %[[EXT]]
+ a.unchecked_shl(b)
+}
+
+// CHECK-LABEL: @unchecked_shr_signed_same
+#[no_mangle]
+pub unsafe fn unchecked_shr_signed_same(a: i32, b: u32) -> i32 {
+ // CHECK-NOT: and i32
+ // CHECK: ashr i32 %a, %b
+ // CHECK-NOT: and i32
+ a.unchecked_shr(b)
+}
+
+// CHECK-LABEL: @unchecked_shr_signed_smaller
+#[no_mangle]
+pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 {
+ // This uses -DAG to avoid failing on irrelevant reorderings,
+ // like emitting the truncation earlier.
+
+ // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 32768
+ // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]])
+ // CHECK-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16
+ // CHECK-DAG: ashr i16 %a, %[[TRUNC]]
+ a.unchecked_shr(b)
+}
+
+// CHECK-LABEL: @unchecked_shr_signed_bigger
+#[no_mangle]
+pub unsafe fn unchecked_shr_signed_bigger(a: i64, b: u32) -> i64 {
+ // CHECK: %[[EXT:.+]] = zext i32 %b to i64
+ // CHECK: ashr i64 %a, %[[EXT]]
+ a.unchecked_shr(b)
+}
diff --git a/src/test/debuginfo/basic-types.rs b/src/test/debuginfo/basic-types.rs
index 07d33be2a..9e82f0714 100644
--- a/src/test/debuginfo/basic-types.rs
+++ b/src/test/debuginfo/basic-types.rs
@@ -47,7 +47,6 @@
// gdbg-check:$15 = {data_ptr = [...] "Hello, World!", length = 13}
// gdbr-check:$15 = "Hello, World!"
-
// === LLDB TESTS ==================================================================================
// lldb-command:run
@@ -96,7 +95,6 @@
// lldbg-check:[...]$12 = 3.5
// lldbr-check:(f64) f64 = 3.5
-
// === CDB TESTS ===================================================================================
// cdb-command:g
@@ -131,7 +129,7 @@
// cdb-command:.enable_unicode 1
// FIXME(#88840): The latest version of the Windows SDK broke the visualizer for str.
// cdb-command:dx s
-// cdb-check:s : [...] [Type: str]
+// cdb-check:s : [...] [Type: ref$<str$>]
#![allow(unused_variables)]
#![feature(omit_gdb_pretty_printer_section)]
@@ -156,4 +154,6 @@ fn main() {
_zzz(); // #break
}
-fn _zzz() {()}
+fn _zzz() {
+ ()
+}
diff --git a/src/test/debuginfo/function-names.rs b/src/test/debuginfo/function-names.rs
index 60fb06d40..2227de3b3 100644
--- a/src/test/debuginfo/function-names.rs
+++ b/src/test/debuginfo/function-names.rs
@@ -76,9 +76,9 @@
// Const generic parameter
// cdb-command:x a!function_names::const_generic_fn*
// cdb-check:[...] a!function_names::const_generic_fn_bool<false> (void)
-// cdb-check:[...] a!function_names::const_generic_fn_non_int<CONST$6348c650c7b26618> (void)
// cdb-check:[...] a!function_names::const_generic_fn_unsigned_int<14> (void)
// cdb-check:[...] a!function_names::const_generic_fn_signed_int<-7> (void)
+// cdb-check:[...] a!function_names::const_generic_fn_non_int<CONST$6348c650c7b26618> (void)
#![allow(unused_variables)]
#![feature(omit_gdb_pretty_printer_section)]
diff --git a/src/test/debuginfo/lexical-scope-in-if-let.rs b/src/test/debuginfo/lexical-scope-in-if-let.rs
index cdc37ce48..8fee459bd 100644
--- a/src/test/debuginfo/lexical-scope-in-if-let.rs
+++ b/src/test/debuginfo/lexical-scope-in-if-let.rs
@@ -58,19 +58,19 @@
// cdb-command: g
// cdb-command: dv
-// cdb-check:[...]y = true
-// cdb-check:[...]b = 0n456
// cdb-check:[...]a = 0n123
// cdb-check:[...]x = 0n42
+// cdb-check:[...]b = 0n456
+// cdb-check:[...]y = true
// cdb-command: g
// cdb-command: dv
// cdb-check:[...]z = 0n10
// cdb-check:[...]c = 0n789
-// cdb-check:[...]y = true
-// cdb-check:[...]b = 0n456
// cdb-check:[...]a = 0n123
// cdb-check:[...]x = 0n42
+// cdb-check:[...]b = 0n456
+// cdb-check:[...]y = true
fn main() {
let a = id(123);
diff --git a/src/test/debuginfo/msvc-pretty-enums.rs b/src/test/debuginfo/msvc-pretty-enums.rs
index 7f1be6f27..d66e4c660 100644
--- a/src/test/debuginfo/msvc-pretty-enums.rs
+++ b/src/test/debuginfo/msvc-pretty-enums.rs
@@ -116,13 +116,13 @@
// cdb-check: niche_w_fields_3_niche5,d : F [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields3>]
// cdb-command: dx -r3 niche_w_fields_std_result_ok,d
-// cdb-check: niche_w_fields_std_result_ok,d : Ok [Type: enum2$<core::result::Result<alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>,u64> >]
-// cdb-check: [+0x[...]] __0 [Type: alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>]
+// cdb-check: niche_w_fields_std_result_ok,d : Ok [Type: enum2$<core::result::Result<alloc::boxed::Box<slice2$<u8>,alloc::alloc::Global>,u64> >]
+// cdb-check: [+0x[...]] __0 [Type: alloc::boxed::Box<slice2$<u8>,alloc::alloc::Global>]
// cdb-check: [+0x[...]] data_ptr : [...]
// cdb-check: [+0x[...]] length : 3 [...]
// cdb-command: dx -r3 niche_w_fields_std_result_err,d
-// cdb-check: niche_w_fields_std_result_err,d : Err [Type: enum2$<core::result::Result<alloc::boxed::Box<slice$<u8>,alloc::alloc::Global>,u64> >]
+// cdb-check: niche_w_fields_std_result_err,d : Err [Type: enum2$<core::result::Result<alloc::boxed::Box<slice2$<u8>,alloc::alloc::Global>,u64> >]
// cdb-check: [+0x[...]] __0 : 789 [Type: unsigned __int64]
// cdb-command: dx -r2 arbitrary_discr1,d
diff --git a/src/test/debuginfo/msvc-scalarpair-params.rs b/src/test/debuginfo/msvc-scalarpair-params.rs
index 9630952cb..ae67f6981 100644
--- a/src/test/debuginfo/msvc-scalarpair-params.rs
+++ b/src/test/debuginfo/msvc-scalarpair-params.rs
@@ -38,14 +38,14 @@
// cdb-command: g
// cdb-command: dx s
-// cdb-check:s : "this is a static str" [Type: str]
+// cdb-check:s : "this is a static str" [Type: ref$<str$>]
// cdb-check: [len] : 0x14 [Type: unsigned [...]]
// cdb-check: [chars]
// cdb-command: g
// cdb-command: dx s
-// cdb-check:s : { len=0x5 } [Type: slice$<u8>]
+// cdb-check:s : { len=0x5 } [Type: ref$<slice2$<u8> >]
// cdb-check: [len] : 0x5 [Type: unsigned [...]]
// cdb-check: [0] : 0x1 [Type: unsigned char]
// cdb-check: [1] : 0x2 [Type: unsigned char]
diff --git a/src/test/debuginfo/mutex.rs b/src/test/debuginfo/mutex.rs
index 314ba40b0..61ec6a812 100644
--- a/src/test/debuginfo/mutex.rs
+++ b/src/test/debuginfo/mutex.rs
@@ -10,7 +10,7 @@
//
// cdb-command:dx m,d
// cdb-check:m,d [Type: std::sync::mutex::Mutex<i32>]
-// cdb-check: [...] inner [Type: std::sys_common::mutex::MovableMutex]
+// cdb-check: [...] inner [Type: std::sys::windows::locks::mutex::Mutex]
// cdb-check: [...] poison [Type: std::sync::poison::Flag]
// cdb-check: [...] data : 0 [Type: core::cell::UnsafeCell<i32>]
diff --git a/src/test/debuginfo/pretty-std.rs b/src/test/debuginfo/pretty-std.rs
index a51b37205..7bb2810c2 100644
--- a/src/test/debuginfo/pretty-std.rs
+++ b/src/test/debuginfo/pretty-std.rs
@@ -69,7 +69,7 @@
// cdb-command: g
// cdb-command: dx slice,d
-// cdb-check:slice,d : { len=4 } [Type: slice$<i32>]
+// cdb-check:slice,d : { len=4 } [Type: ref$<slice2$<i32> >]
// cdb-check: [len] : 4 [Type: [...]]
// cdb-check: [0] : 0 [Type: int]
// cdb-check: [1] : 1 [Type: int]
@@ -86,7 +86,7 @@
// cdb-check: [3] : 7 [Type: unsigned __int64]
// cdb-command: dx str_slice
-// cdb-check:str_slice : "IAMA string slice!" [Type: str]
+// cdb-check:str_slice : "IAMA string slice!" [Type: ref$<str$>]
// cdb-command: dx string
// cdb-check:string : "IAMA string!" [Type: [...]::String]
@@ -138,7 +138,7 @@
// cdb-command: dx vecdeque
// cdb-check:vecdeque : { len=0x2 } [Type: alloc::collections::vec_deque::VecDeque<i32,alloc::alloc::Global>]
// cdb-check: [<Raw View>] [Type: alloc::collections::vec_deque::VecDeque<i32,alloc::alloc::Global>]
-// cdb-check: [len] : 0x2
+// cdb-check: [len] : 0x2 [Type: unsigned [...]]
// cdb-check: [capacity] : 0x8 [Type: unsigned [...]]
// cdb-check: [0x0] : 90 [Type: int]
// cdb-check: [0x1] : 20 [Type: int]
@@ -175,7 +175,7 @@ fn main() {
linkedlist.push_front(128);
// VecDeque
- let mut vecdeque = VecDeque::new();
+ let mut vecdeque = VecDeque::with_capacity(8);
vecdeque.push_back(20);
vecdeque.push_front(90);
diff --git a/src/test/debuginfo/rc_arc.rs b/src/test/debuginfo/rc_arc.rs
index c05c565d9..5d5492d72 100644
--- a/src/test/debuginfo/rc_arc.rs
+++ b/src/test/debuginfo/rc_arc.rs
@@ -57,7 +57,7 @@
// cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell<usize>]
// cdb-command:dx slice_rc,d
-// cdb-check:slice_rc,d : { len=3 } [Type: alloc::rc::Rc<slice$<u32> >]
+// cdb-check:slice_rc,d : { len=3 } [Type: alloc::rc::Rc<slice2$<u32> >]
// cdb-check: [Length] : 3 [Type: [...]]
// cdb-check: [Reference count] : 41 [Type: core::cell::Cell<usize>]
// cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell<usize>]
@@ -66,7 +66,7 @@
// cdb-check: [2] : 3 [Type: u32]
// cdb-command:dx slice_rc_weak,d
-// cdb-check:slice_rc_weak,d : { len=3 } [Type: alloc::rc::Weak<slice$<u32> >]
+// cdb-check:slice_rc_weak,d : { len=3 } [Type: alloc::rc::Weak<slice2$<u32> >]
// cdb-check: [Length] : 3 [Type: [...]]
// cdb-check: [Reference count] : 41 [Type: core::cell::Cell<usize>]
// cdb-check: [Weak reference count] : 2 [Type: core::cell::Cell<usize>]
@@ -85,7 +85,7 @@
// cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize]
// cdb-command:dx slice_arc,d
-// cdb-check:slice_arc,d : { len=3 } [Type: alloc::sync::Arc<slice$<u32> >]
+// cdb-check:slice_arc,d : { len=3 } [Type: alloc::sync::Arc<slice2$<u32> >]
// cdb-check: [Length] : 3 [Type: [...]]
// cdb-check: [Reference count] : 61 [Type: core::sync::atomic::AtomicUsize]
// cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize]
@@ -94,7 +94,7 @@
// cdb-check: [2] : 6 [Type: u32]
// cdb-command:dx slice_arc_weak,d
-// cdb-check:slice_arc_weak,d : { len=3 } [Type: alloc::sync::Weak<slice$<u32> >]
+// cdb-check:slice_arc_weak,d : { len=3 } [Type: alloc::sync::Weak<slice2$<u32> >]
// cdb-check: [Length] : 3 [Type: [...]]
// cdb-check: [Reference count] : 61 [Type: core::sync::atomic::AtomicUsize]
// cdb-check: [Weak reference count] : 2 [Type: core::sync::atomic::AtomicUsize]
diff --git a/src/test/debuginfo/result-types.rs b/src/test/debuginfo/result-types.rs
index cdac47a78..f1944fa38 100644
--- a/src/test/debuginfo/result-types.rs
+++ b/src/test/debuginfo/result-types.rs
@@ -7,12 +7,12 @@
// cdb-command: g
// cdb-command: dx x,d
-// cdb-check:x,d : Ok [Type: enum2$<core::result::Result<i32,str> >]
+// cdb-check:x,d : Ok [Type: enum2$<core::result::Result<i32,ref$<str$> > >]
// cdb-check: [...] __0 : -3 [Type: int]
// cdb-command: dx y
-// cdb-check:y : Err [Type: enum2$<core::result::Result<i32,str> >]
-// cdb-check: [...] __0 : "Some error message" [Type: str]
+// cdb-check:y : Err [Type: enum2$<core::result::Result<i32,ref$<str$> > >]
+// cdb-check: [...] __0 : "Some error message" [Type: ref$<str$>]
fn main() {
let x: Result<i32, &str> = Ok(-3);
diff --git a/src/test/debuginfo/rwlock-read.rs b/src/test/debuginfo/rwlock-read.rs
index ed9aae16b..bc42f92f0 100644
--- a/src/test/debuginfo/rwlock-read.rs
+++ b/src/test/debuginfo/rwlock-read.rs
@@ -16,7 +16,7 @@
// cdb-command:dx r
// cdb-check:r [Type: std::sync::rwlock::RwLockReadGuard<i32>]
// cdb-check: [...] data : NonNull([...]: 0) [Type: core::ptr::non_null::NonNull<i32>]
-// cdb-check: [...] inner_lock : [...] [Type: std::sys_common::rwlock::MovableRwLock *]
+// cdb-check: [...] inner_lock : [...] [Type: std::sys::windows::locks::rwlock::RwLock *]
#[allow(unused_variables)]
diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs
index 9cc99d776..d7b79a845 100644
--- a/src/test/debuginfo/type-names.rs
+++ b/src/test/debuginfo/type-names.rs
@@ -95,7 +95,7 @@
// gdb-check:type = &[usize]
// gdb-command:whatis slice2
-// gdb-check:type = &[type_names::mod1::Enum2]
+// gdb-check:type = &mut [type_names::mod1::Enum2]
// TRAITS
// gdb-command:whatis box_trait
@@ -218,8 +218,8 @@
// cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
// cdb-check:struct alloc::vec::Vec<enum2$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
// cdb-command:dv /t slice*
-// cdb-check:struct slice$<usize> slice1 = [...]
-// cdb-check:struct slice$<enum2$<type_names::mod1::Enum2> > slice2 = [...]
+// cdb-check:struct ref$<slice2$<usize> > slice1 = [...]
+// cdb-check:struct ref_mut$<slice2$<enum2$<type_names::mod1::Enum2> > > slice2 = [...]
// TRAITS
// cdb-command:dv /t *_trait
@@ -417,8 +417,8 @@ fn main() {
let vec1 = vec![0_usize, 2, 3];
let slice1 = &*vec1;
- let vec2 = vec![mod1::Enum2::Variant2(Struct1)];
- let slice2 = &*vec2;
+ let mut vec2 = vec![mod1::Enum2::Variant2(Struct1)];
+ let slice2 = &mut *vec2;
// Trait Objects
let box_trait = Box::new(0_isize) as Box<dyn Trait1>;
diff --git a/src/test/debuginfo/unsized.rs b/src/test/debuginfo/unsized.rs
index 7cb0002ca..b1ec9b068 100644
--- a/src/test/debuginfo/unsized.rs
+++ b/src/test/debuginfo/unsized.rs
@@ -32,13 +32,13 @@
// cdb-command: g
// cdb-command:dx a
-// cdb-check:a [Type: ref$<unsized::Foo<slice$<u8> > >]
-// cdb-check: [+0x000] data_ptr : 0x[...] [Type: unsized::Foo<slice$<u8> > *]
+// cdb-check:a [Type: ref$<unsized::Foo<slice2$<u8> > >]
+// cdb-check: [+0x000] data_ptr : 0x[...] [Type: unsized::Foo<slice2$<u8> > *]
// cdb-check: [...] length : 0x4 [Type: unsigned [...]int[...]
// cdb-command:dx b
-// cdb-check:b [Type: ref$<unsized::Foo<unsized::Foo<slice$<u8> > > >]
-// cdb-check: [+0x000] data_ptr : 0x[...] [Type: unsized::Foo<unsized::Foo<slice$<u8> > > *]
+// cdb-check:b [Type: ref$<unsized::Foo<unsized::Foo<slice2$<u8> > > >]
+// cdb-check: [+0x000] data_ptr : 0x[...] [Type: unsized::Foo<unsized::Foo<slice2$<u8> > > *]
// cdb-check: [...] length : 0x4 [Type: unsigned [...]int[...]
// cdb-command:dx c
@@ -53,8 +53,8 @@
// cdb-check:[...] vtable : 0x[...] [Type: unsigned [...]int[...] (*)[3]]
// cdb-command:dx tuple_slice
-// cdb-check:tuple_slice [Type: ref$<tuple$<i32,i32,slice$<i32> > >]
-// cdb-check: [+0x000] data_ptr : 0x[...] [Type: tuple$<i32,i32,slice$<i32> > *]
+// cdb-check:tuple_slice [Type: ref$<tuple$<i32,i32,slice2$<i32> > >]
+// cdb-check: [+0x000] data_ptr : 0x[...] [Type: tuple$<i32,i32,slice2$<i32> > *]
// cdb-check: [...] length : 0x2 [Type: unsigned [...]int[...]
// cdb-command:dx tuple_dyn
diff --git a/src/test/incremental/hashes/extern_mods.rs b/src/test/incremental/hashes/extern_mods.rs
index ff79acc7f..3121abbea 100644
--- a/src/test/incremental/hashes/extern_mods.rs
+++ b/src/test/incremental/hashes/extern_mods.rs
@@ -128,7 +128,7 @@ extern "C" {
// Change calling convention ---------------------------------------------------
#[cfg(any(cfail1,cfail4))]
extern "C" {
- pub fn change_calling_convention(c: i32);
+ pub fn change_calling_convention(c: (i32,));
}
#[cfg(not(any(cfail1,cfail4)))]
@@ -137,7 +137,7 @@ extern "C" {
#[rustc_clean(cfg = "cfail5", except = "hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg = "cfail6")]
extern "rust-call" {
- pub fn change_calling_convention(c: i32);
+ pub fn change_calling_convention(c: (i32,));
}
// Make function public --------------------------------------------------------
diff --git a/src/test/incremental/issue-101518.rs b/src/test/incremental/issue-101518.rs
new file mode 100644
index 000000000..501be175f
--- /dev/null
+++ b/src/test/incremental/issue-101518.rs
@@ -0,0 +1,31 @@
+// revisions: cfail1
+// should-ice
+// error-pattern: forcing query
+// known-bug: #101518
+
+#[derive(PartialEq, Eq)]
+struct Id<'a> {
+ ns: &'a str,
+}
+fn visit_struct() {
+ let id = Id { ns: "random1" };
+ const FLAG: Id<'static> = Id {
+ ns: "needs_to_be_the_same",
+ };
+ match id {
+ FLAG => {}
+ _ => {}
+ }
+}
+fn visit_struct2() {
+ let id = Id { ns: "random2" };
+ const FLAG: Id<'static> = Id {
+ ns: "needs_to_be_the_same",
+ };
+ match id {
+ FLAG => {}
+ _ => {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
index d41a66871..5f8b2f931 100644
--- a/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
@@ -1,115 +1,115 @@
// MIR for `address_of_reborrow` after SimplifyCfg-initial
| User Type Annotations
-| 0: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:7:5: 7:18, inferred_ty: *const [i32; 10]
-| 1: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:9:5: 9:25, inferred_ty: *const dyn std::marker::Send
-| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:13:12: 13:20, inferred_ty: *const [i32; 10]
-| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:13:12: 13:20, inferred_ty: *const [i32; 10]
-| 4: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:14:12: 14:28, inferred_ty: *const [i32; 10]
-| 5: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:14:12: 14:28, inferred_ty: *const [i32; 10]
-| 6: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send
-| 7: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send
-| 8: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:16:12: 16:24, inferred_ty: *const [i32]
-| 9: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:16:12: 16:24, inferred_ty: *const [i32]
-| 10: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:18:5: 18:18, inferred_ty: *const [i32; 10]
-| 11: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:20:5: 20:25, inferred_ty: *const dyn std::marker::Send
-| 12: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:23:12: 23:20, inferred_ty: *const [i32; 10]
-| 13: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address-of.rs:23:12: 23:20, inferred_ty: *const [i32; 10]
-| 14: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:24:12: 24:28, inferred_ty: *const [i32; 10]
-| 15: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address-of.rs:24:12: 24:28, inferred_ty: *const [i32; 10]
-| 16: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send
-| 17: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address-of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send
-| 18: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:26:12: 26:24, inferred_ty: *const [i32]
-| 19: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address-of.rs:26:12: 26:24, inferred_ty: *const [i32]
-| 20: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:28:5: 28:16, inferred_ty: *mut [i32; 10]
-| 21: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:30:5: 30:23, inferred_ty: *mut dyn std::marker::Send
-| 22: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10]
-| 23: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address-of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10]
-| 24: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address-of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10]
-| 25: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address-of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10]
-| 26: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send
-| 27: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address-of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send
-| 28: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address-of.rs:36:12: 36:22, inferred_ty: *mut [i32]
-| 29: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address-of.rs:36:12: 36:22, inferred_ty: *mut [i32]
+| 0: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:7:5: 7:18, inferred_ty: *const [i32; 10]
+| 1: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:9:5: 9:25, inferred_ty: *const dyn std::marker::Send
+| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:13:12: 13:20, inferred_ty: *const [i32; 10]
+| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:13:12: 13:20, inferred_ty: *const [i32; 10]
+| 4: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address_of.rs:14:12: 14:28, inferred_ty: *const [i32; 10]
+| 5: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address_of.rs:14:12: 14:28, inferred_ty: *const [i32; 10]
+| 6: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send
+| 7: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send
+| 8: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address_of.rs:16:12: 16:24, inferred_ty: *const [i32]
+| 9: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address_of.rs:16:12: 16:24, inferred_ty: *const [i32]
+| 10: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:18:5: 18:18, inferred_ty: *const [i32; 10]
+| 11: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:20:5: 20:25, inferred_ty: *const dyn std::marker::Send
+| 12: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:23:12: 23:20, inferred_ty: *const [i32; 10]
+| 13: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) }, span: $DIR/address_of.rs:23:12: 23:20, inferred_ty: *const [i32; 10]
+| 14: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address_of.rs:24:12: 24:28, inferred_ty: *const [i32; 10]
+| 15: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) }, span: $DIR/address_of.rs:24:12: 24:28, inferred_ty: *const [i32; 10]
+| 16: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send
+| 17: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) }, span: $DIR/address_of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send
+| 18: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address_of.rs:26:12: 26:24, inferred_ty: *const [i32]
+| 19: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) }, span: $DIR/address_of.rs:26:12: 26:24, inferred_ty: *const [i32]
+| 20: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address_of.rs:28:5: 28:16, inferred_ty: *mut [i32; 10]
+| 21: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address_of.rs:30:5: 30:23, inferred_ty: *mut dyn std::marker::Send
+| 22: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address_of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10]
+| 23: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) }, span: $DIR/address_of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10]
+| 24: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address_of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10]
+| 25: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) }, span: $DIR/address_of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10]
+| 26: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address_of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send
+| 27: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) }, span: $DIR/address_of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send
+| 28: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address_of.rs:36:12: 36:22, inferred_ty: *mut [i32]
+| 29: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32]) }, span: $DIR/address_of.rs:36:12: 36:22, inferred_ty: *mut [i32]
|
fn address_of_reborrow() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/address-of.rs:+0:26: +0:26
- let _1: &[i32; 10]; // in scope 0 at $DIR/address-of.rs:+1:9: +1:10
- let _2: [i32; 10]; // in scope 0 at $DIR/address-of.rs:+1:14: +1:21
- let mut _4: [i32; 10]; // in scope 0 at $DIR/address-of.rs:+2:22: +2:29
- let _5: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+4:5: +4:18
- let mut _6: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+4:5: +4:18
- let _7: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+5:5: +5:26
- let _8: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+6:5: +6:25
- let mut _9: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+6:5: +6:25
- let mut _10: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+6:5: +6:6
- let _11: *const [i32]; // in scope 0 at $DIR/address-of.rs:+7:5: +7:22
- let mut _12: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+7:5: +7:6
- let _13: *const i32; // in scope 0 at $DIR/address-of.rs:+8:5: +8:20
- let mut _14: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+8:5: +8:6
- let mut _18: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+12:30: +12:31
- let mut _20: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+13:27: +13:28
- let _21: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+15:5: +15:18
- let mut _22: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+15:5: +15:18
- let _23: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+16:5: +16:26
- let _24: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+17:5: +17:25
- let mut _25: *const dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+17:5: +17:25
- let mut _26: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+17:5: +17:6
- let _27: *const [i32]; // in scope 0 at $DIR/address-of.rs:+18:5: +18:22
- let mut _28: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+18:5: +18:6
- let mut _32: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+22:30: +22:31
- let mut _34: *const [i32; 10]; // in scope 0 at $DIR/address-of.rs:+23:27: +23:28
- let _35: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+25:5: +25:16
- let mut _36: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+25:5: +25:16
- let _37: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+26:5: +26:24
- let _38: *mut dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+27:5: +27:23
- let mut _39: *mut dyn std::marker::Send; // in scope 0 at $DIR/address-of.rs:+27:5: +27:23
- let mut _40: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+27:5: +27:6
- let _41: *mut [i32]; // in scope 0 at $DIR/address-of.rs:+28:5: +28:20
- let mut _42: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+28:5: +28:6
- let mut _46: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+32:28: +32:29
- let mut _48: *mut [i32; 10]; // in scope 0 at $DIR/address-of.rs:+33:25: +33:26
+ let mut _0: (); // return place in scope 0 at $DIR/address_of.rs:+0:26: +0:26
+ let _1: &[i32; 10]; // in scope 0 at $DIR/address_of.rs:+1:9: +1:10
+ let _2: [i32; 10]; // in scope 0 at $DIR/address_of.rs:+1:14: +1:21
+ let mut _4: [i32; 10]; // in scope 0 at $DIR/address_of.rs:+2:22: +2:29
+ let _5: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+4:5: +4:18
+ let mut _6: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+4:5: +4:18
+ let _7: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+5:5: +5:26
+ let _8: *const dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+6:5: +6:25
+ let mut _9: *const dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+6:5: +6:25
+ let mut _10: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+6:5: +6:6
+ let _11: *const [i32]; // in scope 0 at $DIR/address_of.rs:+7:5: +7:22
+ let mut _12: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+7:5: +7:6
+ let _13: *const i32; // in scope 0 at $DIR/address_of.rs:+8:5: +8:20
+ let mut _14: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+8:5: +8:6
+ let mut _18: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+12:30: +12:31
+ let mut _20: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+13:27: +13:28
+ let _21: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+15:5: +15:18
+ let mut _22: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+15:5: +15:18
+ let _23: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+16:5: +16:26
+ let _24: *const dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+17:5: +17:25
+ let mut _25: *const dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+17:5: +17:25
+ let mut _26: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+17:5: +17:6
+ let _27: *const [i32]; // in scope 0 at $DIR/address_of.rs:+18:5: +18:22
+ let mut _28: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+18:5: +18:6
+ let mut _32: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+22:30: +22:31
+ let mut _34: *const [i32; 10]; // in scope 0 at $DIR/address_of.rs:+23:27: +23:28
+ let _35: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+25:5: +25:16
+ let mut _36: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+25:5: +25:16
+ let _37: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+26:5: +26:24
+ let _38: *mut dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+27:5: +27:23
+ let mut _39: *mut dyn std::marker::Send; // in scope 0 at $DIR/address_of.rs:+27:5: +27:23
+ let mut _40: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+27:5: +27:6
+ let _41: *mut [i32]; // in scope 0 at $DIR/address_of.rs:+28:5: +28:20
+ let mut _42: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+28:5: +28:6
+ let mut _46: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+32:28: +32:29
+ let mut _48: *mut [i32; 10]; // in scope 0 at $DIR/address_of.rs:+33:25: +33:26
scope 1 {
- debug y => _1; // in scope 1 at $DIR/address-of.rs:+1:9: +1:10
- let mut _3: &mut [i32; 10]; // in scope 1 at $DIR/address-of.rs:+2:9: +2:14
+ debug y => _1; // in scope 1 at $DIR/address_of.rs:+1:9: +1:10
+ let mut _3: &mut [i32; 10]; // in scope 1 at $DIR/address_of.rs:+2:9: +2:14
scope 2 {
- debug z => _3; // in scope 2 at $DIR/address-of.rs:+2:9: +2:14
- let _15: *const [i32; 10] as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 2 at $DIR/address-of.rs:+10:9: +10:10
+ debug z => _3; // in scope 2 at $DIR/address_of.rs:+2:9: +2:14
+ let _15: *const [i32; 10] as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 2 at $DIR/address_of.rs:+10:9: +10:10
scope 3 {
- debug p => _15; // in scope 3 at $DIR/address-of.rs:+10:9: +10:10
- let _16: *const [i32; 10] as UserTypeProjection { base: UserType(4), projs: [] }; // in scope 3 at $DIR/address-of.rs:+11:9: +11:10
+ debug p => _15; // in scope 3 at $DIR/address_of.rs:+10:9: +10:10
+ let _16: *const [i32; 10] as UserTypeProjection { base: UserType(4), projs: [] }; // in scope 3 at $DIR/address_of.rs:+11:9: +11:10
scope 4 {
- debug p => _16; // in scope 4 at $DIR/address-of.rs:+11:9: +11:10
- let _17: *const dyn std::marker::Send as UserTypeProjection { base: UserType(6), projs: [] }; // in scope 4 at $DIR/address-of.rs:+12:9: +12:10
+ debug p => _16; // in scope 4 at $DIR/address_of.rs:+11:9: +11:10
+ let _17: *const dyn std::marker::Send as UserTypeProjection { base: UserType(6), projs: [] }; // in scope 4 at $DIR/address_of.rs:+12:9: +12:10
scope 5 {
- debug p => _17; // in scope 5 at $DIR/address-of.rs:+12:9: +12:10
- let _19: *const [i32] as UserTypeProjection { base: UserType(8), projs: [] }; // in scope 5 at $DIR/address-of.rs:+13:9: +13:10
+ debug p => _17; // in scope 5 at $DIR/address_of.rs:+12:9: +12:10
+ let _19: *const [i32] as UserTypeProjection { base: UserType(8), projs: [] }; // in scope 5 at $DIR/address_of.rs:+13:9: +13:10
scope 6 {
- debug p => _19; // in scope 6 at $DIR/address-of.rs:+13:9: +13:10
- let _29: *const [i32; 10] as UserTypeProjection { base: UserType(12), projs: [] }; // in scope 6 at $DIR/address-of.rs:+20:9: +20:10
+ debug p => _19; // in scope 6 at $DIR/address_of.rs:+13:9: +13:10
+ let _29: *const [i32; 10] as UserTypeProjection { base: UserType(12), projs: [] }; // in scope 6 at $DIR/address_of.rs:+20:9: +20:10
scope 7 {
- debug p => _29; // in scope 7 at $DIR/address-of.rs:+20:9: +20:10
- let _30: *const [i32; 10] as UserTypeProjection { base: UserType(14), projs: [] }; // in scope 7 at $DIR/address-of.rs:+21:9: +21:10
+ debug p => _29; // in scope 7 at $DIR/address_of.rs:+20:9: +20:10
+ let _30: *const [i32; 10] as UserTypeProjection { base: UserType(14), projs: [] }; // in scope 7 at $DIR/address_of.rs:+21:9: +21:10
scope 8 {
- debug p => _30; // in scope 8 at $DIR/address-of.rs:+21:9: +21:10
- let _31: *const dyn std::marker::Send as UserTypeProjection { base: UserType(16), projs: [] }; // in scope 8 at $DIR/address-of.rs:+22:9: +22:10
+ debug p => _30; // in scope 8 at $DIR/address_of.rs:+21:9: +21:10
+ let _31: *const dyn std::marker::Send as UserTypeProjection { base: UserType(16), projs: [] }; // in scope 8 at $DIR/address_of.rs:+22:9: +22:10
scope 9 {
- debug p => _31; // in scope 9 at $DIR/address-of.rs:+22:9: +22:10
- let _33: *const [i32] as UserTypeProjection { base: UserType(18), projs: [] }; // in scope 9 at $DIR/address-of.rs:+23:9: +23:10
+ debug p => _31; // in scope 9 at $DIR/address_of.rs:+22:9: +22:10
+ let _33: *const [i32] as UserTypeProjection { base: UserType(18), projs: [] }; // in scope 9 at $DIR/address_of.rs:+23:9: +23:10
scope 10 {
- debug p => _33; // in scope 10 at $DIR/address-of.rs:+23:9: +23:10
- let _43: *mut [i32; 10] as UserTypeProjection { base: UserType(22), projs: [] }; // in scope 10 at $DIR/address-of.rs:+30:9: +30:10
+ debug p => _33; // in scope 10 at $DIR/address_of.rs:+23:9: +23:10
+ let _43: *mut [i32; 10] as UserTypeProjection { base: UserType(22), projs: [] }; // in scope 10 at $DIR/address_of.rs:+30:9: +30:10
scope 11 {
- debug p => _43; // in scope 11 at $DIR/address-of.rs:+30:9: +30:10
- let _44: *mut [i32; 10] as UserTypeProjection { base: UserType(24), projs: [] }; // in scope 11 at $DIR/address-of.rs:+31:9: +31:10
+ debug p => _43; // in scope 11 at $DIR/address_of.rs:+30:9: +30:10
+ let _44: *mut [i32; 10] as UserTypeProjection { base: UserType(24), projs: [] }; // in scope 11 at $DIR/address_of.rs:+31:9: +31:10
scope 12 {
- debug p => _44; // in scope 12 at $DIR/address-of.rs:+31:9: +31:10
- let _45: *mut dyn std::marker::Send as UserTypeProjection { base: UserType(26), projs: [] }; // in scope 12 at $DIR/address-of.rs:+32:9: +32:10
+ debug p => _44; // in scope 12 at $DIR/address_of.rs:+31:9: +31:10
+ let _45: *mut dyn std::marker::Send as UserTypeProjection { base: UserType(26), projs: [] }; // in scope 12 at $DIR/address_of.rs:+32:9: +32:10
scope 13 {
- debug p => _45; // in scope 13 at $DIR/address-of.rs:+32:9: +32:10
- let _47: *mut [i32] as UserTypeProjection { base: UserType(28), projs: [] }; // in scope 13 at $DIR/address-of.rs:+33:9: +33:10
+ debug p => _45; // in scope 13 at $DIR/address_of.rs:+32:9: +32:10
+ let _47: *mut [i32] as UserTypeProjection { base: UserType(28), projs: [] }; // in scope 13 at $DIR/address_of.rs:+33:9: +33:10
scope 14 {
- debug p => _47; // in scope 14 at $DIR/address-of.rs:+33:9: +33:10
+ debug p => _47; // in scope 14 at $DIR/address_of.rs:+33:9: +33:10
}
}
}
@@ -126,183 +126,183 @@ fn address_of_reborrow() -> () {
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/address-of.rs:+1:9: +1:10
- StorageLive(_2); // scope 0 at $DIR/address-of.rs:+1:14: +1:21
- _2 = [const 0_i32; 10]; // scope 0 at $DIR/address-of.rs:+1:14: +1:21
- _1 = &_2; // scope 0 at $DIR/address-of.rs:+1:13: +1:21
- FakeRead(ForLet(None), _1); // scope 0 at $DIR/address-of.rs:+1:9: +1:10
- StorageLive(_3); // scope 1 at $DIR/address-of.rs:+2:9: +2:14
- StorageLive(_4); // scope 1 at $DIR/address-of.rs:+2:22: +2:29
- _4 = [const 0_i32; 10]; // scope 1 at $DIR/address-of.rs:+2:22: +2:29
- _3 = &mut _4; // scope 1 at $DIR/address-of.rs:+2:17: +2:29
- FakeRead(ForLet(None), _3); // scope 1 at $DIR/address-of.rs:+2:9: +2:14
- StorageLive(_5); // scope 2 at $DIR/address-of.rs:+4:5: +4:18
- StorageLive(_6); // scope 2 at $DIR/address-of.rs:+4:5: +4:18
- _6 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+4:5: +4:6
- AscribeUserType(_6, o, UserTypeProjection { base: UserType(0), projs: [] }); // scope 2 at $DIR/address-of.rs:+4:5: +4:18
- _5 = _6; // scope 2 at $DIR/address-of.rs:+4:5: +4:18
- StorageDead(_6); // scope 2 at $DIR/address-of.rs:+4:18: +4:19
- StorageDead(_5); // scope 2 at $DIR/address-of.rs:+4:18: +4:19
- StorageLive(_7); // scope 2 at $DIR/address-of.rs:+5:5: +5:26
- _7 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+5:5: +5:6
- StorageDead(_7); // scope 2 at $DIR/address-of.rs:+5:26: +5:27
- StorageLive(_8); // scope 2 at $DIR/address-of.rs:+6:5: +6:25
- StorageLive(_9); // scope 2 at $DIR/address-of.rs:+6:5: +6:25
- StorageLive(_10); // scope 2 at $DIR/address-of.rs:+6:5: +6:6
- _10 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+6:5: +6:6
- _9 = move _10 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 2 at $DIR/address-of.rs:+6:5: +6:6
- StorageDead(_10); // scope 2 at $DIR/address-of.rs:+6:5: +6:6
- AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/address-of.rs:+6:5: +6:25
- _8 = _9; // scope 2 at $DIR/address-of.rs:+6:5: +6:25
- StorageDead(_9); // scope 2 at $DIR/address-of.rs:+6:25: +6:26
- StorageDead(_8); // scope 2 at $DIR/address-of.rs:+6:25: +6:26
- StorageLive(_11); // scope 2 at $DIR/address-of.rs:+7:5: +7:22
- StorageLive(_12); // scope 2 at $DIR/address-of.rs:+7:5: +7:6
- _12 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+7:5: +7:6
- _11 = move _12 as *const [i32] (Pointer(Unsize)); // scope 2 at $DIR/address-of.rs:+7:5: +7:6
- StorageDead(_12); // scope 2 at $DIR/address-of.rs:+7:5: +7:6
- StorageDead(_11); // scope 2 at $DIR/address-of.rs:+7:22: +7:23
- StorageLive(_13); // scope 2 at $DIR/address-of.rs:+8:5: +8:20
- StorageLive(_14); // scope 2 at $DIR/address-of.rs:+8:5: +8:6
- _14 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+8:5: +8:6
- _13 = move _14 as *const i32 (Pointer(ArrayToPointer)); // scope 2 at $DIR/address-of.rs:+8:5: +8:20
- StorageDead(_14); // scope 2 at $DIR/address-of.rs:+8:19: +8:20
- StorageDead(_13); // scope 2 at $DIR/address-of.rs:+8:20: +8:21
- StorageLive(_15); // scope 2 at $DIR/address-of.rs:+10:9: +10:10
- _15 = &raw const (*_1); // scope 2 at $DIR/address-of.rs:+10:23: +10:24
- FakeRead(ForLet(None), _15); // scope 2 at $DIR/address-of.rs:+10:9: +10:10
- AscribeUserType(_15, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 2 at $DIR/address-of.rs:+10:12: +10:20
- StorageLive(_16); // scope 3 at $DIR/address-of.rs:+11:9: +11:10
- _16 = &raw const (*_1); // scope 3 at $DIR/address-of.rs:+11:31: +11:32
- FakeRead(ForLet(None), _16); // scope 3 at $DIR/address-of.rs:+11:9: +11:10
- AscribeUserType(_16, o, UserTypeProjection { base: UserType(5), projs: [] }); // scope 3 at $DIR/address-of.rs:+11:12: +11:28
- StorageLive(_17); // scope 4 at $DIR/address-of.rs:+12:9: +12:10
- StorageLive(_18); // scope 4 at $DIR/address-of.rs:+12:30: +12:31
- _18 = &raw const (*_1); // scope 4 at $DIR/address-of.rs:+12:30: +12:31
- _17 = move _18 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 4 at $DIR/address-of.rs:+12:30: +12:31
- StorageDead(_18); // scope 4 at $DIR/address-of.rs:+12:30: +12:31
- FakeRead(ForLet(None), _17); // scope 4 at $DIR/address-of.rs:+12:9: +12:10
- AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] }); // scope 4 at $DIR/address-of.rs:+12:12: +12:27
- StorageLive(_19); // scope 5 at $DIR/address-of.rs:+13:9: +13:10
- StorageLive(_20); // scope 5 at $DIR/address-of.rs:+13:27: +13:28
- _20 = &raw const (*_1); // scope 5 at $DIR/address-of.rs:+13:27: +13:28
- _19 = move _20 as *const [i32] (Pointer(Unsize)); // scope 5 at $DIR/address-of.rs:+13:27: +13:28
- StorageDead(_20); // scope 5 at $DIR/address-of.rs:+13:27: +13:28
- FakeRead(ForLet(None), _19); // scope 5 at $DIR/address-of.rs:+13:9: +13:10
- AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] }); // scope 5 at $DIR/address-of.rs:+13:12: +13:24
- StorageLive(_21); // scope 6 at $DIR/address-of.rs:+15:5: +15:18
- StorageLive(_22); // scope 6 at $DIR/address-of.rs:+15:5: +15:18
- _22 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+15:5: +15:6
- AscribeUserType(_22, o, UserTypeProjection { base: UserType(10), projs: [] }); // scope 6 at $DIR/address-of.rs:+15:5: +15:18
- _21 = _22; // scope 6 at $DIR/address-of.rs:+15:5: +15:18
- StorageDead(_22); // scope 6 at $DIR/address-of.rs:+15:18: +15:19
- StorageDead(_21); // scope 6 at $DIR/address-of.rs:+15:18: +15:19
- StorageLive(_23); // scope 6 at $DIR/address-of.rs:+16:5: +16:26
- _23 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+16:5: +16:6
- StorageDead(_23); // scope 6 at $DIR/address-of.rs:+16:26: +16:27
- StorageLive(_24); // scope 6 at $DIR/address-of.rs:+17:5: +17:25
- StorageLive(_25); // scope 6 at $DIR/address-of.rs:+17:5: +17:25
- StorageLive(_26); // scope 6 at $DIR/address-of.rs:+17:5: +17:6
- _26 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+17:5: +17:6
- _25 = move _26 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 6 at $DIR/address-of.rs:+17:5: +17:6
- StorageDead(_26); // scope 6 at $DIR/address-of.rs:+17:5: +17:6
- AscribeUserType(_25, o, UserTypeProjection { base: UserType(11), projs: [] }); // scope 6 at $DIR/address-of.rs:+17:5: +17:25
- _24 = _25; // scope 6 at $DIR/address-of.rs:+17:5: +17:25
- StorageDead(_25); // scope 6 at $DIR/address-of.rs:+17:25: +17:26
- StorageDead(_24); // scope 6 at $DIR/address-of.rs:+17:25: +17:26
- StorageLive(_27); // scope 6 at $DIR/address-of.rs:+18:5: +18:22
- StorageLive(_28); // scope 6 at $DIR/address-of.rs:+18:5: +18:6
- _28 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+18:5: +18:6
- _27 = move _28 as *const [i32] (Pointer(Unsize)); // scope 6 at $DIR/address-of.rs:+18:5: +18:6
- StorageDead(_28); // scope 6 at $DIR/address-of.rs:+18:5: +18:6
- StorageDead(_27); // scope 6 at $DIR/address-of.rs:+18:22: +18:23
- StorageLive(_29); // scope 6 at $DIR/address-of.rs:+20:9: +20:10
- _29 = &raw const (*_3); // scope 6 at $DIR/address-of.rs:+20:23: +20:24
- FakeRead(ForLet(None), _29); // scope 6 at $DIR/address-of.rs:+20:9: +20:10
- AscribeUserType(_29, o, UserTypeProjection { base: UserType(13), projs: [] }); // scope 6 at $DIR/address-of.rs:+20:12: +20:20
- StorageLive(_30); // scope 7 at $DIR/address-of.rs:+21:9: +21:10
- _30 = &raw const (*_3); // scope 7 at $DIR/address-of.rs:+21:31: +21:32
- FakeRead(ForLet(None), _30); // scope 7 at $DIR/address-of.rs:+21:9: +21:10
- AscribeUserType(_30, o, UserTypeProjection { base: UserType(15), projs: [] }); // scope 7 at $DIR/address-of.rs:+21:12: +21:28
- StorageLive(_31); // scope 8 at $DIR/address-of.rs:+22:9: +22:10
- StorageLive(_32); // scope 8 at $DIR/address-of.rs:+22:30: +22:31
- _32 = &raw const (*_3); // scope 8 at $DIR/address-of.rs:+22:30: +22:31
- _31 = move _32 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 8 at $DIR/address-of.rs:+22:30: +22:31
- StorageDead(_32); // scope 8 at $DIR/address-of.rs:+22:30: +22:31
- FakeRead(ForLet(None), _31); // scope 8 at $DIR/address-of.rs:+22:9: +22:10
- AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] }); // scope 8 at $DIR/address-of.rs:+22:12: +22:27
- StorageLive(_33); // scope 9 at $DIR/address-of.rs:+23:9: +23:10
- StorageLive(_34); // scope 9 at $DIR/address-of.rs:+23:27: +23:28
- _34 = &raw const (*_3); // scope 9 at $DIR/address-of.rs:+23:27: +23:28
- _33 = move _34 as *const [i32] (Pointer(Unsize)); // scope 9 at $DIR/address-of.rs:+23:27: +23:28
- StorageDead(_34); // scope 9 at $DIR/address-of.rs:+23:27: +23:28
- FakeRead(ForLet(None), _33); // scope 9 at $DIR/address-of.rs:+23:9: +23:10
- AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] }); // scope 9 at $DIR/address-of.rs:+23:12: +23:24
- StorageLive(_35); // scope 10 at $DIR/address-of.rs:+25:5: +25:16
- StorageLive(_36); // scope 10 at $DIR/address-of.rs:+25:5: +25:16
- _36 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+25:5: +25:6
- AscribeUserType(_36, o, UserTypeProjection { base: UserType(20), projs: [] }); // scope 10 at $DIR/address-of.rs:+25:5: +25:16
- _35 = _36; // scope 10 at $DIR/address-of.rs:+25:5: +25:16
- StorageDead(_36); // scope 10 at $DIR/address-of.rs:+25:16: +25:17
- StorageDead(_35); // scope 10 at $DIR/address-of.rs:+25:16: +25:17
- StorageLive(_37); // scope 10 at $DIR/address-of.rs:+26:5: +26:24
- _37 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+26:5: +26:6
- StorageDead(_37); // scope 10 at $DIR/address-of.rs:+26:24: +26:25
- StorageLive(_38); // scope 10 at $DIR/address-of.rs:+27:5: +27:23
- StorageLive(_39); // scope 10 at $DIR/address-of.rs:+27:5: +27:23
- StorageLive(_40); // scope 10 at $DIR/address-of.rs:+27:5: +27:6
- _40 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+27:5: +27:6
- _39 = move _40 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 10 at $DIR/address-of.rs:+27:5: +27:6
- StorageDead(_40); // scope 10 at $DIR/address-of.rs:+27:5: +27:6
- AscribeUserType(_39, o, UserTypeProjection { base: UserType(21), projs: [] }); // scope 10 at $DIR/address-of.rs:+27:5: +27:23
- _38 = _39; // scope 10 at $DIR/address-of.rs:+27:5: +27:23
- StorageDead(_39); // scope 10 at $DIR/address-of.rs:+27:23: +27:24
- StorageDead(_38); // scope 10 at $DIR/address-of.rs:+27:23: +27:24
- StorageLive(_41); // scope 10 at $DIR/address-of.rs:+28:5: +28:20
- StorageLive(_42); // scope 10 at $DIR/address-of.rs:+28:5: +28:6
- _42 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+28:5: +28:6
- _41 = move _42 as *mut [i32] (Pointer(Unsize)); // scope 10 at $DIR/address-of.rs:+28:5: +28:6
- StorageDead(_42); // scope 10 at $DIR/address-of.rs:+28:5: +28:6
- StorageDead(_41); // scope 10 at $DIR/address-of.rs:+28:20: +28:21
- StorageLive(_43); // scope 10 at $DIR/address-of.rs:+30:9: +30:10
- _43 = &raw mut (*_3); // scope 10 at $DIR/address-of.rs:+30:21: +30:22
- FakeRead(ForLet(None), _43); // scope 10 at $DIR/address-of.rs:+30:9: +30:10
- AscribeUserType(_43, o, UserTypeProjection { base: UserType(23), projs: [] }); // scope 10 at $DIR/address-of.rs:+30:12: +30:18
- StorageLive(_44); // scope 11 at $DIR/address-of.rs:+31:9: +31:10
- _44 = &raw mut (*_3); // scope 11 at $DIR/address-of.rs:+31:29: +31:30
- FakeRead(ForLet(None), _44); // scope 11 at $DIR/address-of.rs:+31:9: +31:10
- AscribeUserType(_44, o, UserTypeProjection { base: UserType(25), projs: [] }); // scope 11 at $DIR/address-of.rs:+31:12: +31:26
- StorageLive(_45); // scope 12 at $DIR/address-of.rs:+32:9: +32:10
- StorageLive(_46); // scope 12 at $DIR/address-of.rs:+32:28: +32:29
- _46 = &raw mut (*_3); // scope 12 at $DIR/address-of.rs:+32:28: +32:29
- _45 = move _46 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 12 at $DIR/address-of.rs:+32:28: +32:29
- StorageDead(_46); // scope 12 at $DIR/address-of.rs:+32:28: +32:29
- FakeRead(ForLet(None), _45); // scope 12 at $DIR/address-of.rs:+32:9: +32:10
- AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] }); // scope 12 at $DIR/address-of.rs:+32:12: +32:25
- StorageLive(_47); // scope 13 at $DIR/address-of.rs:+33:9: +33:10
- StorageLive(_48); // scope 13 at $DIR/address-of.rs:+33:25: +33:26
- _48 = &raw mut (*_3); // scope 13 at $DIR/address-of.rs:+33:25: +33:26
- _47 = move _48 as *mut [i32] (Pointer(Unsize)); // scope 13 at $DIR/address-of.rs:+33:25: +33:26
- StorageDead(_48); // scope 13 at $DIR/address-of.rs:+33:25: +33:26
- FakeRead(ForLet(None), _47); // scope 13 at $DIR/address-of.rs:+33:9: +33:10
- AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); // scope 13 at $DIR/address-of.rs:+33:12: +33:22
- _0 = const (); // scope 0 at $DIR/address-of.rs:+0:26: +34:2
- StorageDead(_47); // scope 13 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_45); // scope 12 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_44); // scope 11 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_43); // scope 10 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_33); // scope 9 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_31); // scope 8 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_30); // scope 7 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_29); // scope 6 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_19); // scope 5 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_17); // scope 4 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_16); // scope 3 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_15); // scope 2 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_4); // scope 1 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_3); // scope 1 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_2); // scope 0 at $DIR/address-of.rs:+34:1: +34:2
- StorageDead(_1); // scope 0 at $DIR/address-of.rs:+34:1: +34:2
- return; // scope 0 at $DIR/address-of.rs:+34:2: +34:2
+ StorageLive(_1); // scope 0 at $DIR/address_of.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/address_of.rs:+1:14: +1:21
+ _2 = [const 0_i32; 10]; // scope 0 at $DIR/address_of.rs:+1:14: +1:21
+ _1 = &_2; // scope 0 at $DIR/address_of.rs:+1:13: +1:21
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/address_of.rs:+1:9: +1:10
+ StorageLive(_3); // scope 1 at $DIR/address_of.rs:+2:9: +2:14
+ StorageLive(_4); // scope 1 at $DIR/address_of.rs:+2:22: +2:29
+ _4 = [const 0_i32; 10]; // scope 1 at $DIR/address_of.rs:+2:22: +2:29
+ _3 = &mut _4; // scope 1 at $DIR/address_of.rs:+2:17: +2:29
+ FakeRead(ForLet(None), _3); // scope 1 at $DIR/address_of.rs:+2:9: +2:14
+ StorageLive(_5); // scope 2 at $DIR/address_of.rs:+4:5: +4:18
+ StorageLive(_6); // scope 2 at $DIR/address_of.rs:+4:5: +4:18
+ _6 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+4:5: +4:6
+ AscribeUserType(_6, o, UserTypeProjection { base: UserType(0), projs: [] }); // scope 2 at $DIR/address_of.rs:+4:5: +4:18
+ _5 = _6; // scope 2 at $DIR/address_of.rs:+4:5: +4:18
+ StorageDead(_6); // scope 2 at $DIR/address_of.rs:+4:18: +4:19
+ StorageDead(_5); // scope 2 at $DIR/address_of.rs:+4:18: +4:19
+ StorageLive(_7); // scope 2 at $DIR/address_of.rs:+5:5: +5:26
+ _7 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+5:5: +5:6
+ StorageDead(_7); // scope 2 at $DIR/address_of.rs:+5:26: +5:27
+ StorageLive(_8); // scope 2 at $DIR/address_of.rs:+6:5: +6:25
+ StorageLive(_9); // scope 2 at $DIR/address_of.rs:+6:5: +6:25
+ StorageLive(_10); // scope 2 at $DIR/address_of.rs:+6:5: +6:6
+ _10 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+6:5: +6:6
+ _9 = move _10 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 2 at $DIR/address_of.rs:+6:5: +6:6
+ StorageDead(_10); // scope 2 at $DIR/address_of.rs:+6:5: +6:6
+ AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 2 at $DIR/address_of.rs:+6:5: +6:25
+ _8 = _9; // scope 2 at $DIR/address_of.rs:+6:5: +6:25
+ StorageDead(_9); // scope 2 at $DIR/address_of.rs:+6:25: +6:26
+ StorageDead(_8); // scope 2 at $DIR/address_of.rs:+6:25: +6:26
+ StorageLive(_11); // scope 2 at $DIR/address_of.rs:+7:5: +7:22
+ StorageLive(_12); // scope 2 at $DIR/address_of.rs:+7:5: +7:6
+ _12 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+7:5: +7:6
+ _11 = move _12 as *const [i32] (Pointer(Unsize)); // scope 2 at $DIR/address_of.rs:+7:5: +7:6
+ StorageDead(_12); // scope 2 at $DIR/address_of.rs:+7:5: +7:6
+ StorageDead(_11); // scope 2 at $DIR/address_of.rs:+7:22: +7:23
+ StorageLive(_13); // scope 2 at $DIR/address_of.rs:+8:5: +8:20
+ StorageLive(_14); // scope 2 at $DIR/address_of.rs:+8:5: +8:6
+ _14 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+8:5: +8:6
+ _13 = move _14 as *const i32 (Pointer(ArrayToPointer)); // scope 2 at $DIR/address_of.rs:+8:5: +8:20
+ StorageDead(_14); // scope 2 at $DIR/address_of.rs:+8:19: +8:20
+ StorageDead(_13); // scope 2 at $DIR/address_of.rs:+8:20: +8:21
+ StorageLive(_15); // scope 2 at $DIR/address_of.rs:+10:9: +10:10
+ _15 = &raw const (*_1); // scope 2 at $DIR/address_of.rs:+10:23: +10:24
+ FakeRead(ForLet(None), _15); // scope 2 at $DIR/address_of.rs:+10:9: +10:10
+ AscribeUserType(_15, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 2 at $DIR/address_of.rs:+10:12: +10:20
+ StorageLive(_16); // scope 3 at $DIR/address_of.rs:+11:9: +11:10
+ _16 = &raw const (*_1); // scope 3 at $DIR/address_of.rs:+11:31: +11:32
+ FakeRead(ForLet(None), _16); // scope 3 at $DIR/address_of.rs:+11:9: +11:10
+ AscribeUserType(_16, o, UserTypeProjection { base: UserType(5), projs: [] }); // scope 3 at $DIR/address_of.rs:+11:12: +11:28
+ StorageLive(_17); // scope 4 at $DIR/address_of.rs:+12:9: +12:10
+ StorageLive(_18); // scope 4 at $DIR/address_of.rs:+12:30: +12:31
+ _18 = &raw const (*_1); // scope 4 at $DIR/address_of.rs:+12:30: +12:31
+ _17 = move _18 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 4 at $DIR/address_of.rs:+12:30: +12:31
+ StorageDead(_18); // scope 4 at $DIR/address_of.rs:+12:30: +12:31
+ FakeRead(ForLet(None), _17); // scope 4 at $DIR/address_of.rs:+12:9: +12:10
+ AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] }); // scope 4 at $DIR/address_of.rs:+12:12: +12:27
+ StorageLive(_19); // scope 5 at $DIR/address_of.rs:+13:9: +13:10
+ StorageLive(_20); // scope 5 at $DIR/address_of.rs:+13:27: +13:28
+ _20 = &raw const (*_1); // scope 5 at $DIR/address_of.rs:+13:27: +13:28
+ _19 = move _20 as *const [i32] (Pointer(Unsize)); // scope 5 at $DIR/address_of.rs:+13:27: +13:28
+ StorageDead(_20); // scope 5 at $DIR/address_of.rs:+13:27: +13:28
+ FakeRead(ForLet(None), _19); // scope 5 at $DIR/address_of.rs:+13:9: +13:10
+ AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] }); // scope 5 at $DIR/address_of.rs:+13:12: +13:24
+ StorageLive(_21); // scope 6 at $DIR/address_of.rs:+15:5: +15:18
+ StorageLive(_22); // scope 6 at $DIR/address_of.rs:+15:5: +15:18
+ _22 = &raw const (*_3); // scope 6 at $DIR/address_of.rs:+15:5: +15:6
+ AscribeUserType(_22, o, UserTypeProjection { base: UserType(10), projs: [] }); // scope 6 at $DIR/address_of.rs:+15:5: +15:18
+ _21 = _22; // scope 6 at $DIR/address_of.rs:+15:5: +15:18
+ StorageDead(_22); // scope 6 at $DIR/address_of.rs:+15:18: +15:19
+ StorageDead(_21); // scope 6 at $DIR/address_of.rs:+15:18: +15:19
+ StorageLive(_23); // scope 6 at $DIR/address_of.rs:+16:5: +16:26
+ _23 = &raw const (*_3); // scope 6 at $DIR/address_of.rs:+16:5: +16:6
+ StorageDead(_23); // scope 6 at $DIR/address_of.rs:+16:26: +16:27
+ StorageLive(_24); // scope 6 at $DIR/address_of.rs:+17:5: +17:25
+ StorageLive(_25); // scope 6 at $DIR/address_of.rs:+17:5: +17:25
+ StorageLive(_26); // scope 6 at $DIR/address_of.rs:+17:5: +17:6
+ _26 = &raw const (*_3); // scope 6 at $DIR/address_of.rs:+17:5: +17:6
+ _25 = move _26 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 6 at $DIR/address_of.rs:+17:5: +17:6
+ StorageDead(_26); // scope 6 at $DIR/address_of.rs:+17:5: +17:6
+ AscribeUserType(_25, o, UserTypeProjection { base: UserType(11), projs: [] }); // scope 6 at $DIR/address_of.rs:+17:5: +17:25
+ _24 = _25; // scope 6 at $DIR/address_of.rs:+17:5: +17:25
+ StorageDead(_25); // scope 6 at $DIR/address_of.rs:+17:25: +17:26
+ StorageDead(_24); // scope 6 at $DIR/address_of.rs:+17:25: +17:26
+ StorageLive(_27); // scope 6 at $DIR/address_of.rs:+18:5: +18:22
+ StorageLive(_28); // scope 6 at $DIR/address_of.rs:+18:5: +18:6
+ _28 = &raw const (*_3); // scope 6 at $DIR/address_of.rs:+18:5: +18:6
+ _27 = move _28 as *const [i32] (Pointer(Unsize)); // scope 6 at $DIR/address_of.rs:+18:5: +18:6
+ StorageDead(_28); // scope 6 at $DIR/address_of.rs:+18:5: +18:6
+ StorageDead(_27); // scope 6 at $DIR/address_of.rs:+18:22: +18:23
+ StorageLive(_29); // scope 6 at $DIR/address_of.rs:+20:9: +20:10
+ _29 = &raw const (*_3); // scope 6 at $DIR/address_of.rs:+20:23: +20:24
+ FakeRead(ForLet(None), _29); // scope 6 at $DIR/address_of.rs:+20:9: +20:10
+ AscribeUserType(_29, o, UserTypeProjection { base: UserType(13), projs: [] }); // scope 6 at $DIR/address_of.rs:+20:12: +20:20
+ StorageLive(_30); // scope 7 at $DIR/address_of.rs:+21:9: +21:10
+ _30 = &raw const (*_3); // scope 7 at $DIR/address_of.rs:+21:31: +21:32
+ FakeRead(ForLet(None), _30); // scope 7 at $DIR/address_of.rs:+21:9: +21:10
+ AscribeUserType(_30, o, UserTypeProjection { base: UserType(15), projs: [] }); // scope 7 at $DIR/address_of.rs:+21:12: +21:28
+ StorageLive(_31); // scope 8 at $DIR/address_of.rs:+22:9: +22:10
+ StorageLive(_32); // scope 8 at $DIR/address_of.rs:+22:30: +22:31
+ _32 = &raw const (*_3); // scope 8 at $DIR/address_of.rs:+22:30: +22:31
+ _31 = move _32 as *const dyn std::marker::Send (Pointer(Unsize)); // scope 8 at $DIR/address_of.rs:+22:30: +22:31
+ StorageDead(_32); // scope 8 at $DIR/address_of.rs:+22:30: +22:31
+ FakeRead(ForLet(None), _31); // scope 8 at $DIR/address_of.rs:+22:9: +22:10
+ AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] }); // scope 8 at $DIR/address_of.rs:+22:12: +22:27
+ StorageLive(_33); // scope 9 at $DIR/address_of.rs:+23:9: +23:10
+ StorageLive(_34); // scope 9 at $DIR/address_of.rs:+23:27: +23:28
+ _34 = &raw const (*_3); // scope 9 at $DIR/address_of.rs:+23:27: +23:28
+ _33 = move _34 as *const [i32] (Pointer(Unsize)); // scope 9 at $DIR/address_of.rs:+23:27: +23:28
+ StorageDead(_34); // scope 9 at $DIR/address_of.rs:+23:27: +23:28
+ FakeRead(ForLet(None), _33); // scope 9 at $DIR/address_of.rs:+23:9: +23:10
+ AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] }); // scope 9 at $DIR/address_of.rs:+23:12: +23:24
+ StorageLive(_35); // scope 10 at $DIR/address_of.rs:+25:5: +25:16
+ StorageLive(_36); // scope 10 at $DIR/address_of.rs:+25:5: +25:16
+ _36 = &raw mut (*_3); // scope 10 at $DIR/address_of.rs:+25:5: +25:6
+ AscribeUserType(_36, o, UserTypeProjection { base: UserType(20), projs: [] }); // scope 10 at $DIR/address_of.rs:+25:5: +25:16
+ _35 = _36; // scope 10 at $DIR/address_of.rs:+25:5: +25:16
+ StorageDead(_36); // scope 10 at $DIR/address_of.rs:+25:16: +25:17
+ StorageDead(_35); // scope 10 at $DIR/address_of.rs:+25:16: +25:17
+ StorageLive(_37); // scope 10 at $DIR/address_of.rs:+26:5: +26:24
+ _37 = &raw mut (*_3); // scope 10 at $DIR/address_of.rs:+26:5: +26:6
+ StorageDead(_37); // scope 10 at $DIR/address_of.rs:+26:24: +26:25
+ StorageLive(_38); // scope 10 at $DIR/address_of.rs:+27:5: +27:23
+ StorageLive(_39); // scope 10 at $DIR/address_of.rs:+27:5: +27:23
+ StorageLive(_40); // scope 10 at $DIR/address_of.rs:+27:5: +27:6
+ _40 = &raw mut (*_3); // scope 10 at $DIR/address_of.rs:+27:5: +27:6
+ _39 = move _40 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 10 at $DIR/address_of.rs:+27:5: +27:6
+ StorageDead(_40); // scope 10 at $DIR/address_of.rs:+27:5: +27:6
+ AscribeUserType(_39, o, UserTypeProjection { base: UserType(21), projs: [] }); // scope 10 at $DIR/address_of.rs:+27:5: +27:23
+ _38 = _39; // scope 10 at $DIR/address_of.rs:+27:5: +27:23
+ StorageDead(_39); // scope 10 at $DIR/address_of.rs:+27:23: +27:24
+ StorageDead(_38); // scope 10 at $DIR/address_of.rs:+27:23: +27:24
+ StorageLive(_41); // scope 10 at $DIR/address_of.rs:+28:5: +28:20
+ StorageLive(_42); // scope 10 at $DIR/address_of.rs:+28:5: +28:6
+ _42 = &raw mut (*_3); // scope 10 at $DIR/address_of.rs:+28:5: +28:6
+ _41 = move _42 as *mut [i32] (Pointer(Unsize)); // scope 10 at $DIR/address_of.rs:+28:5: +28:6
+ StorageDead(_42); // scope 10 at $DIR/address_of.rs:+28:5: +28:6
+ StorageDead(_41); // scope 10 at $DIR/address_of.rs:+28:20: +28:21
+ StorageLive(_43); // scope 10 at $DIR/address_of.rs:+30:9: +30:10
+ _43 = &raw mut (*_3); // scope 10 at $DIR/address_of.rs:+30:21: +30:22
+ FakeRead(ForLet(None), _43); // scope 10 at $DIR/address_of.rs:+30:9: +30:10
+ AscribeUserType(_43, o, UserTypeProjection { base: UserType(23), projs: [] }); // scope 10 at $DIR/address_of.rs:+30:12: +30:18
+ StorageLive(_44); // scope 11 at $DIR/address_of.rs:+31:9: +31:10
+ _44 = &raw mut (*_3); // scope 11 at $DIR/address_of.rs:+31:29: +31:30
+ FakeRead(ForLet(None), _44); // scope 11 at $DIR/address_of.rs:+31:9: +31:10
+ AscribeUserType(_44, o, UserTypeProjection { base: UserType(25), projs: [] }); // scope 11 at $DIR/address_of.rs:+31:12: +31:26
+ StorageLive(_45); // scope 12 at $DIR/address_of.rs:+32:9: +32:10
+ StorageLive(_46); // scope 12 at $DIR/address_of.rs:+32:28: +32:29
+ _46 = &raw mut (*_3); // scope 12 at $DIR/address_of.rs:+32:28: +32:29
+ _45 = move _46 as *mut dyn std::marker::Send (Pointer(Unsize)); // scope 12 at $DIR/address_of.rs:+32:28: +32:29
+ StorageDead(_46); // scope 12 at $DIR/address_of.rs:+32:28: +32:29
+ FakeRead(ForLet(None), _45); // scope 12 at $DIR/address_of.rs:+32:9: +32:10
+ AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] }); // scope 12 at $DIR/address_of.rs:+32:12: +32:25
+ StorageLive(_47); // scope 13 at $DIR/address_of.rs:+33:9: +33:10
+ StorageLive(_48); // scope 13 at $DIR/address_of.rs:+33:25: +33:26
+ _48 = &raw mut (*_3); // scope 13 at $DIR/address_of.rs:+33:25: +33:26
+ _47 = move _48 as *mut [i32] (Pointer(Unsize)); // scope 13 at $DIR/address_of.rs:+33:25: +33:26
+ StorageDead(_48); // scope 13 at $DIR/address_of.rs:+33:25: +33:26
+ FakeRead(ForLet(None), _47); // scope 13 at $DIR/address_of.rs:+33:9: +33:10
+ AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); // scope 13 at $DIR/address_of.rs:+33:12: +33:22
+ _0 = const (); // scope 0 at $DIR/address_of.rs:+0:26: +34:2
+ StorageDead(_47); // scope 13 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_45); // scope 12 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_44); // scope 11 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_43); // scope 10 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_33); // scope 9 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_31); // scope 8 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_30); // scope 7 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_29); // scope 6 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_19); // scope 5 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_17); // scope 4 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_16); // scope 3 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_15); // scope 2 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_4); // scope 1 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_3); // scope 1 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_2); // scope 0 at $DIR/address_of.rs:+34:1: +34:2
+ StorageDead(_1); // scope 0 at $DIR/address_of.rs:+34:1: +34:2
+ return; // scope 0 at $DIR/address_of.rs:+34:2: +34:2
}
}
diff --git a/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir
index 060077b8a..4c67376b5 100644
--- a/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/address_of.borrow_and_cast.SimplifyCfg-initial.after.mir
@@ -1,47 +1,47 @@
// MIR for `borrow_and_cast` after SimplifyCfg-initial
fn borrow_and_cast(_1: i32) -> () {
- debug x => _1; // in scope 0 at $DIR/address-of.rs:+0:20: +0:25
- let mut _0: (); // return place in scope 0 at $DIR/address-of.rs:+0:32: +0:32
- let _2: *const i32; // in scope 0 at $DIR/address-of.rs:+1:9: +1:10
- let _3: &i32; // in scope 0 at $DIR/address-of.rs:+1:13: +1:15
- let _5: &mut i32; // in scope 0 at $DIR/address-of.rs:+2:13: +2:19
- let mut _7: &mut i32; // in scope 0 at $DIR/address-of.rs:+3:13: +3:19
+ debug x => _1; // in scope 0 at $DIR/address_of.rs:+0:20: +0:25
+ let mut _0: (); // return place in scope 0 at $DIR/address_of.rs:+0:32: +0:32
+ let _2: *const i32; // in scope 0 at $DIR/address_of.rs:+1:9: +1:10
+ let _3: &i32; // in scope 0 at $DIR/address_of.rs:+1:13: +1:15
+ let _5: &mut i32; // in scope 0 at $DIR/address_of.rs:+2:13: +2:19
+ let mut _7: &mut i32; // in scope 0 at $DIR/address_of.rs:+3:13: +3:19
scope 1 {
- debug p => _2; // in scope 1 at $DIR/address-of.rs:+1:9: +1:10
- let _4: *const i32; // in scope 1 at $DIR/address-of.rs:+2:9: +2:10
+ debug p => _2; // in scope 1 at $DIR/address_of.rs:+1:9: +1:10
+ let _4: *const i32; // in scope 1 at $DIR/address_of.rs:+2:9: +2:10
scope 2 {
- debug q => _4; // in scope 2 at $DIR/address-of.rs:+2:9: +2:10
- let _6: *mut i32; // in scope 2 at $DIR/address-of.rs:+3:9: +3:10
+ debug q => _4; // in scope 2 at $DIR/address_of.rs:+2:9: +2:10
+ let _6: *mut i32; // in scope 2 at $DIR/address_of.rs:+3:9: +3:10
scope 3 {
- debug r => _6; // in scope 3 at $DIR/address-of.rs:+3:9: +3:10
+ debug r => _6; // in scope 3 at $DIR/address_of.rs:+3:9: +3:10
}
}
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/address-of.rs:+1:9: +1:10
- StorageLive(_3); // scope 0 at $DIR/address-of.rs:+1:13: +1:15
- _3 = &_1; // scope 0 at $DIR/address-of.rs:+1:13: +1:15
- _2 = &raw const (*_3); // scope 0 at $DIR/address-of.rs:+1:13: +1:15
- FakeRead(ForLet(None), _2); // scope 0 at $DIR/address-of.rs:+1:9: +1:10
- StorageDead(_3); // scope 0 at $DIR/address-of.rs:+1:29: +1:30
- StorageLive(_4); // scope 1 at $DIR/address-of.rs:+2:9: +2:10
- StorageLive(_5); // scope 1 at $DIR/address-of.rs:+2:13: +2:19
- _5 = &mut _1; // scope 1 at $DIR/address-of.rs:+2:13: +2:19
- _4 = &raw const (*_5); // scope 1 at $DIR/address-of.rs:+2:13: +2:19
- FakeRead(ForLet(None), _4); // scope 1 at $DIR/address-of.rs:+2:9: +2:10
- StorageDead(_5); // scope 1 at $DIR/address-of.rs:+2:33: +2:34
- StorageLive(_6); // scope 2 at $DIR/address-of.rs:+3:9: +3:10
- StorageLive(_7); // scope 2 at $DIR/address-of.rs:+3:13: +3:19
- _7 = &mut _1; // scope 2 at $DIR/address-of.rs:+3:13: +3:19
- _6 = &raw mut (*_7); // scope 2 at $DIR/address-of.rs:+3:13: +3:19
- FakeRead(ForLet(None), _6); // scope 2 at $DIR/address-of.rs:+3:9: +3:10
- StorageDead(_7); // scope 2 at $DIR/address-of.rs:+3:31: +3:32
- _0 = const (); // scope 0 at $DIR/address-of.rs:+0:32: +4:2
- StorageDead(_6); // scope 2 at $DIR/address-of.rs:+4:1: +4:2
- StorageDead(_4); // scope 1 at $DIR/address-of.rs:+4:1: +4:2
- StorageDead(_2); // scope 0 at $DIR/address-of.rs:+4:1: +4:2
- return; // scope 0 at $DIR/address-of.rs:+4:2: +4:2
+ StorageLive(_2); // scope 0 at $DIR/address_of.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/address_of.rs:+1:13: +1:15
+ _3 = &_1; // scope 0 at $DIR/address_of.rs:+1:13: +1:15
+ _2 = &raw const (*_3); // scope 0 at $DIR/address_of.rs:+1:13: +1:15
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/address_of.rs:+1:9: +1:10
+ StorageDead(_3); // scope 0 at $DIR/address_of.rs:+1:29: +1:30
+ StorageLive(_4); // scope 1 at $DIR/address_of.rs:+2:9: +2:10
+ StorageLive(_5); // scope 1 at $DIR/address_of.rs:+2:13: +2:19
+ _5 = &mut _1; // scope 1 at $DIR/address_of.rs:+2:13: +2:19
+ _4 = &raw const (*_5); // scope 1 at $DIR/address_of.rs:+2:13: +2:19
+ FakeRead(ForLet(None), _4); // scope 1 at $DIR/address_of.rs:+2:9: +2:10
+ StorageDead(_5); // scope 1 at $DIR/address_of.rs:+2:33: +2:34
+ StorageLive(_6); // scope 2 at $DIR/address_of.rs:+3:9: +3:10
+ StorageLive(_7); // scope 2 at $DIR/address_of.rs:+3:13: +3:19
+ _7 = &mut _1; // scope 2 at $DIR/address_of.rs:+3:13: +3:19
+ _6 = &raw mut (*_7); // scope 2 at $DIR/address_of.rs:+3:13: +3:19
+ FakeRead(ForLet(None), _6); // scope 2 at $DIR/address_of.rs:+3:9: +3:10
+ StorageDead(_7); // scope 2 at $DIR/address_of.rs:+3:31: +3:32
+ _0 = const (); // scope 0 at $DIR/address_of.rs:+0:32: +4:2
+ StorageDead(_6); // scope 2 at $DIR/address_of.rs:+4:1: +4:2
+ StorageDead(_4); // scope 1 at $DIR/address_of.rs:+4:1: +4:2
+ StorageDead(_2); // scope 0 at $DIR/address_of.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/address_of.rs:+4:2: +4:2
}
}
diff --git a/src/test/mir-opt/address-of.rs b/src/test/mir-opt/address_of.rs
index c4bea5613..c4bea5613 100644
--- a/src/test/mir-opt/address-of.rs
+++ b/src/test/mir-opt/address_of.rs
diff --git a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
index 27f883ed3..af5178d40 100644
--- a/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
@@ -1,22 +1,22 @@
// MIR for `main` after SimplifyCfg-elaborate-drops
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +0:11
- let mut _1: [u32; 3]; // in scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
- let mut _4: &mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
- let mut _5: u32; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
- let mut _6: *mut usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
- let _7: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
- let mut _8: usize; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
- let mut _9: bool; // in scope 0 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ let mut _0: (); // return place in scope 0 at $DIR/array_index_is_temporary.rs:+0:11: +0:11
+ let mut _1: [u32; 3]; // in scope 0 at $DIR/array_index_is_temporary.rs:+1:9: +1:14
+ let mut _4: &mut usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+3:25: +3:31
+ let mut _5: u32; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:12: +4:29
+ let mut _6: *mut usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:25: +4:26
+ let _7: usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:7: +4:8
+ let mut _8: usize; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:5: +4:9
+ let mut _9: bool; // in scope 0 at $DIR/array_index_is_temporary.rs:+4:5: +4:9
scope 1 {
- debug x => _1; // in scope 1 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
- let mut _2: usize; // in scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
+ debug x => _1; // in scope 1 at $DIR/array_index_is_temporary.rs:+1:9: +1:14
+ let mut _2: usize; // in scope 1 at $DIR/array_index_is_temporary.rs:+2:9: +2:14
scope 2 {
- debug y => _2; // in scope 2 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
- let _3: *mut usize; // in scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
+ debug y => _2; // in scope 2 at $DIR/array_index_is_temporary.rs:+2:9: +2:14
+ let _3: *mut usize; // in scope 2 at $DIR/array_index_is_temporary.rs:+3:9: +3:10
scope 3 {
- debug z => _3; // in scope 3 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
+ debug z => _3; // in scope 3 at $DIR/array_index_is_temporary.rs:+3:9: +3:10
scope 4 {
}
}
@@ -24,41 +24,41 @@ fn main() -> () {
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+1:9: +1:14
- _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array-index-is-temporary.rs:+1:17: +1:29
- StorageLive(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+2:9: +2:14
- _2 = const 1_usize; // scope 1 at $DIR/array-index-is-temporary.rs:+2:17: +2:18
- StorageLive(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+3:9: +3:10
- StorageLive(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
- _4 = &mut _2; // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
- _3 = &raw mut (*_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:25: +3:31
- StorageDead(_4); // scope 2 at $DIR/array-index-is-temporary.rs:+3:31: +3:32
- StorageLive(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:12: +4:29
- StorageLive(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
- _6 = _3; // scope 4 at $DIR/array-index-is-temporary.rs:+4:25: +4:26
- _5 = foo(move _6) -> bb1; // scope 4 at $DIR/array-index-is-temporary.rs:+4:21: +4:27
+ StorageLive(_1); // scope 0 at $DIR/array_index_is_temporary.rs:+1:9: +1:14
+ _1 = [const 42_u32, const 43_u32, const 44_u32]; // scope 0 at $DIR/array_index_is_temporary.rs:+1:17: +1:29
+ StorageLive(_2); // scope 1 at $DIR/array_index_is_temporary.rs:+2:9: +2:14
+ _2 = const 1_usize; // scope 1 at $DIR/array_index_is_temporary.rs:+2:17: +2:18
+ StorageLive(_3); // scope 2 at $DIR/array_index_is_temporary.rs:+3:9: +3:10
+ StorageLive(_4); // scope 2 at $DIR/array_index_is_temporary.rs:+3:25: +3:31
+ _4 = &mut _2; // scope 2 at $DIR/array_index_is_temporary.rs:+3:25: +3:31
+ _3 = &raw mut (*_4); // scope 2 at $DIR/array_index_is_temporary.rs:+3:25: +3:31
+ StorageDead(_4); // scope 2 at $DIR/array_index_is_temporary.rs:+3:31: +3:32
+ StorageLive(_5); // scope 3 at $DIR/array_index_is_temporary.rs:+4:12: +4:29
+ StorageLive(_6); // scope 4 at $DIR/array_index_is_temporary.rs:+4:25: +4:26
+ _6 = _3; // scope 4 at $DIR/array_index_is_temporary.rs:+4:25: +4:26
+ _5 = foo(move _6) -> bb1; // scope 4 at $DIR/array_index_is_temporary.rs:+4:21: +4:27
// mir::Constant
- // + span: $DIR/array-index-is-temporary.rs:16:21: 16:24
+ // + span: $DIR/array_index_is_temporary.rs:16:21: 16:24
// + literal: Const { ty: unsafe fn(*mut usize) -> u32 {foo}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_6); // scope 4 at $DIR/array-index-is-temporary.rs:+4:26: +4:27
- StorageLive(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
- _7 = _2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:7: +4:8
- _8 = Len(_1); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
- _9 = Lt(_7, _8); // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
- assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:9
+ StorageDead(_6); // scope 4 at $DIR/array_index_is_temporary.rs:+4:26: +4:27
+ StorageLive(_7); // scope 3 at $DIR/array_index_is_temporary.rs:+4:7: +4:8
+ _7 = _2; // scope 3 at $DIR/array_index_is_temporary.rs:+4:7: +4:8
+ _8 = Len(_1); // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:9
+ _9 = Lt(_7, _8); // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:9
+ assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> bb2; // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:9
}
bb2: {
- _1[_7] = move _5; // scope 3 at $DIR/array-index-is-temporary.rs:+4:5: +4:29
- StorageDead(_5); // scope 3 at $DIR/array-index-is-temporary.rs:+4:28: +4:29
- StorageDead(_7); // scope 3 at $DIR/array-index-is-temporary.rs:+4:29: +4:30
- _0 = const (); // scope 0 at $DIR/array-index-is-temporary.rs:+0:11: +5:2
- StorageDead(_3); // scope 2 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
- StorageDead(_2); // scope 1 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
- StorageDead(_1); // scope 0 at $DIR/array-index-is-temporary.rs:+5:1: +5:2
- return; // scope 0 at $DIR/array-index-is-temporary.rs:+5:2: +5:2
+ _1[_7] = move _5; // scope 3 at $DIR/array_index_is_temporary.rs:+4:5: +4:29
+ StorageDead(_5); // scope 3 at $DIR/array_index_is_temporary.rs:+4:28: +4:29
+ StorageDead(_7); // scope 3 at $DIR/array_index_is_temporary.rs:+4:29: +4:30
+ _0 = const (); // scope 0 at $DIR/array_index_is_temporary.rs:+0:11: +5:2
+ StorageDead(_3); // scope 2 at $DIR/array_index_is_temporary.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/array_index_is_temporary.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/array_index_is_temporary.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/array_index_is_temporary.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/array-index-is-temporary.rs b/src/test/mir-opt/array_index_is_temporary.rs
index e7bde81d4..e7bde81d4 100644
--- a/src/test/mir-opt/array-index-is-temporary.rs
+++ b/src/test/mir-opt/array_index_is_temporary.rs
diff --git a/src/test/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir b/src/test/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir
new file mode 100644
index 000000000..20dd251e7
--- /dev/null
+++ b/src/test/mir-opt/building/custom/arbitrary_let.arbitrary_let.built.after.mir
@@ -0,0 +1,22 @@
+// MIR for `arbitrary_let` after built
+
+fn arbitrary_let(_1: i32) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/arbitrary_let.rs:+0:29: +0:32
+ let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ goto -> bb2; // scope 0 at $DIR/arbitrary_let.rs:+4:13: +4:25
+ }
+
+ bb1: {
+ _0 = _3; // scope 0 at $DIR/arbitrary_let.rs:+7:13: +7:20
+ return; // scope 0 at $DIR/arbitrary_let.rs:+8:13: +8:21
+ }
+
+ bb2: {
+ _3 = _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ goto -> bb1; // scope 0 at $DIR/arbitrary_let.rs:+12:13: +12:24
+ }
+}
diff --git a/src/test/mir-opt/building/custom/arbitrary_let.rs b/src/test/mir-opt/building/custom/arbitrary_let.rs
new file mode 100644
index 000000000..776df3151
--- /dev/null
+++ b/src/test/mir-opt/building/custom/arbitrary_let.rs
@@ -0,0 +1,28 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+use core::ptr::{addr_of, addr_of_mut};
+
+// EMIT_MIR arbitrary_let.arbitrary_let.built.after.mir
+#[custom_mir(dialect = "built")]
+fn arbitrary_let(x: i32) -> i32 {
+ mir!(
+ {
+ let y = x;
+ Goto(second)
+ }
+ third = {
+ RET = z;
+ Return()
+ }
+ second = {
+ let z = y;
+ Goto(third)
+ }
+ )
+}
+
+fn main() {
+ assert_eq!(arbitrary_let(5), 5);
+}
diff --git a/src/test/mir-opt/building/custom/consts.consts.built.after.mir b/src/test/mir-opt/building/custom/consts.consts.built.after.mir
new file mode 100644
index 000000000..ba753cfc2
--- /dev/null
+++ b/src/test/mir-opt/building/custom/consts.consts.built.after.mir
@@ -0,0 +1,22 @@
+// MIR for `consts` after built
+
+fn consts() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/consts.rs:+0:27: +0:27
+ let mut _1: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _2: i8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _3: u32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _4: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _5: fn() {consts::<10>}; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _1 = const 5_u8; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _2 = const _; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _3 = const C; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _4 = const _; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _5 = consts::<10>; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ // mir::Constant
+ // + span: $DIR/consts.rs:16:18: 16:30
+ // + literal: Const { ty: fn() {consts::<10>}, val: Value(<ZST>) }
+ return; // scope 0 at $DIR/consts.rs:+7:9: +7:17
+ }
+}
diff --git a/src/test/mir-opt/building/custom/consts.rs b/src/test/mir-opt/building/custom/consts.rs
new file mode 100644
index 000000000..ff4fe1a93
--- /dev/null
+++ b/src/test/mir-opt/building/custom/consts.rs
@@ -0,0 +1,36 @@
+#![feature(custom_mir, core_intrinsics, inline_const)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+const D: i32 = 5;
+
+// EMIT_MIR consts.consts.built.after.mir
+#[custom_mir(dialect = "built")]
+fn consts<const C: u32>() {
+ mir!({
+ let _a = 5_u8;
+ let _b = const { 5_i8 };
+ let _c = C;
+ let _d = D;
+ let _e = consts::<10>;
+ Return()
+ })
+}
+
+static S: i32 = 5;
+static mut T: i32 = 10;
+// EMIT_MIR consts.statics.built.after.mir
+#[custom_mir(dialect = "built")]
+fn statics() {
+ mir!({
+ let _a: &i32 = Static(S);
+ let _b: *mut i32 = StaticMut(T);
+ Return()
+ })
+}
+
+fn main() {
+ consts::<5>();
+ statics();
+}
diff --git a/src/test/mir-opt/building/custom/consts.statics.built.after.mir b/src/test/mir-opt/building/custom/consts.statics.built.after.mir
new file mode 100644
index 000000000..ee768e263
--- /dev/null
+++ b/src/test/mir-opt/building/custom/consts.statics.built.after.mir
@@ -0,0 +1,27 @@
+// MIR for `statics` after built
+
+fn statics() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/consts.rs:+0:14: +0:14
+ let mut _1: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _2: *mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _1 = const {alloc1: &i32}; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ // mir::Constant
+ // + span: $DIR/consts.rs:27:31: 27:32
+ // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
+ _2 = const {alloc2: *mut i32}; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ // mir::Constant
+ // + span: $DIR/consts.rs:28:38: 28:39
+ // + literal: Const { ty: *mut i32, val: Value(Scalar(alloc2)) }
+ return; // scope 0 at $DIR/consts.rs:+4:9: +4:17
+ }
+}
+
+alloc2 (static: T, size: 4, align: 4) {
+ 0a 00 00 00 │ ....
+}
+
+alloc1 (static: S, size: 4, align: 4) {
+ 05 00 00 00 │ ....
+}
diff --git a/src/test/mir-opt/building/custom/references.immut_ref.built.after.mir b/src/test/mir-opt/building/custom/references.immut_ref.built.after.mir
new file mode 100644
index 000000000..4d38d45c0
--- /dev/null
+++ b/src/test/mir-opt/building/custom/references.immut_ref.built.after.mir
@@ -0,0 +1,14 @@
+// MIR for `immut_ref` after built
+
+fn immut_ref(_1: &i32) -> &i32 {
+ let mut _0: &i32; // return place in scope 0 at $DIR/references.rs:+0:30: +0:34
+ let mut _2: *const i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _2 = &raw const (*_1); // scope 0 at $DIR/references.rs:+5:13: +5:29
+ Retag([raw] _2); // scope 0 at $DIR/references.rs:+6:13: +6:24
+ _0 = &(*_2); // scope 0 at $DIR/references.rs:+7:13: +7:23
+ Retag(_0); // scope 0 at $DIR/references.rs:+8:13: +8:23
+ return; // scope 0 at $DIR/references.rs:+9:13: +9:21
+ }
+}
diff --git a/src/test/mir-opt/building/custom/references.mut_ref.built.after.mir b/src/test/mir-opt/building/custom/references.mut_ref.built.after.mir
new file mode 100644
index 000000000..01bc8a9cd
--- /dev/null
+++ b/src/test/mir-opt/building/custom/references.mut_ref.built.after.mir
@@ -0,0 +1,14 @@
+// MIR for `mut_ref` after built
+
+fn mut_ref(_1: &mut i32) -> &mut i32 {
+ let mut _0: &mut i32; // return place in scope 0 at $DIR/references.rs:+0:32: +0:40
+ let mut _2: *mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _2 = &raw mut (*_1); // scope 0 at $DIR/references.rs:+5:13: +5:33
+ Retag([raw] _2); // scope 0 at $DIR/references.rs:+6:13: +6:24
+ _0 = &mut (*_2); // scope 0 at $DIR/references.rs:+7:13: +7:26
+ Retag(_0); // scope 0 at $DIR/references.rs:+8:13: +8:23
+ return; // scope 0 at $DIR/references.rs:+9:13: +9:21
+ }
+}
diff --git a/src/test/mir-opt/building/custom/references.rs b/src/test/mir-opt/building/custom/references.rs
new file mode 100644
index 000000000..dee85722e
--- /dev/null
+++ b/src/test/mir-opt/building/custom/references.rs
@@ -0,0 +1,43 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+use core::ptr::{addr_of, addr_of_mut};
+
+// EMIT_MIR references.mut_ref.built.after.mir
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub fn mut_ref(x: &mut i32) -> &mut i32 {
+ mir!(
+ let t: *mut i32;
+
+ {
+ t = addr_of_mut!(*x);
+ RetagRaw(t);
+ RET = &mut *t;
+ Retag(RET);
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR references.immut_ref.built.after.mir
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub fn immut_ref(x: &i32) -> &i32 {
+ mir!(
+ let t: *const i32;
+
+ {
+ t = addr_of!(*x);
+ RetagRaw(t);
+ RET = & *t;
+ Retag(RET);
+ Return()
+ }
+ )
+}
+
+fn main() {
+ let mut x = 5;
+ assert_eq!(*mut_ref(&mut x), 5);
+ assert_eq!(*immut_ref(&x), 5);
+}
diff --git a/src/test/mir-opt/building/custom/simple_assign.rs b/src/test/mir-opt/building/custom/simple_assign.rs
new file mode 100644
index 000000000..ec6dbe1d0
--- /dev/null
+++ b/src/test/mir-opt/building/custom/simple_assign.rs
@@ -0,0 +1,37 @@
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+// EMIT_MIR simple_assign.simple.built.after.mir
+#[custom_mir(dialect = "built")]
+pub fn simple(x: i32) -> i32 {
+ mir!(
+ let temp1: i32;
+ let temp2: _;
+
+ {
+ temp1 = x;
+ Goto(exit)
+ }
+
+ exit = {
+ temp2 = Move(temp1);
+ RET = temp2;
+ Return()
+ }
+ )
+}
+
+// EMIT_MIR simple_assign.simple_ref.built.after.mir
+#[custom_mir(dialect = "built")]
+pub fn simple_ref(x: &mut i32) -> &mut i32 {
+ mir!({
+ RET = Move(x);
+ Return()
+ })
+}
+
+fn main() {
+ assert_eq!(5, simple(5));
+}
diff --git a/src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir b/src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir
new file mode 100644
index 000000000..d7560fde6
--- /dev/null
+++ b/src/test/mir-opt/building/custom/simple_assign.simple.built.after.mir
@@ -0,0 +1,18 @@
+// MIR for `simple` after built
+
+fn simple(_1: i32) -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/simple_assign.rs:+0:26: +0:29
+ let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+
+ bb0: {
+ _2 = _1; // scope 0 at $DIR/simple_assign.rs:+6:13: +6:22
+ goto -> bb1; // scope 0 at $DIR/simple_assign.rs:+7:13: +7:23
+ }
+
+ bb1: {
+ _3 = move _2; // scope 0 at $DIR/simple_assign.rs:+11:13: +11:32
+ _0 = _3; // scope 0 at $DIR/simple_assign.rs:+12:13: +12:24
+ return; // scope 0 at $DIR/simple_assign.rs:+13:13: +13:21
+ }
+}
diff --git a/src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir b/src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir
new file mode 100644
index 000000000..2b0e8f104
--- /dev/null
+++ b/src/test/mir-opt/building/custom/simple_assign.simple_ref.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `simple_ref` after built
+
+fn simple_ref(_1: &mut i32) -> &mut i32 {
+ let mut _0: &mut i32; // return place in scope 0 at $DIR/simple_assign.rs:+0:35: +0:43
+
+ bb0: {
+ _0 = move _1; // scope 0 at $DIR/simple_assign.rs:+2:9: +2:22
+ return; // scope 0 at $DIR/simple_assign.rs:+3:9: +3:17
+ }
+}
diff --git a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir b/src/test/mir-opt/building/enum_cast.bar.built.after.mir
index e58085f70..0746e0b49 100644
--- a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
+++ b/src/test/mir-opt/building/enum_cast.bar.built.after.mir
@@ -1,15 +1,21 @@
-// MIR for `bar` 0 mir_map
+// MIR for `bar` after built
fn bar(_1: Bar) -> usize {
debug bar => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
let _2: Bar; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
let mut _3: isize; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let mut _4: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ let mut _5: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
bb0: {
StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
_2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
_3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _4 = Ge(const 1_isize, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ assume(_4); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _5 = Le(const 0_isize, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ assume(_5); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
_0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
diff --git a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir b/src/test/mir-opt/building/enum_cast.boo.built.after.mir
index 525c6234e..699c876b0 100644
--- a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
+++ b/src/test/mir-opt/building/enum_cast.boo.built.after.mir
@@ -1,15 +1,21 @@
-// MIR for `boo` 0 mir_map
+// MIR for `boo` after built
fn boo(_1: Boo) -> usize {
debug boo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
let mut _0: usize; // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
let _2: Boo; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
let mut _3: u8; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+ let mut _4: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ let mut _5: bool; // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
bb0: {
StorageLive(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
_2 = move _1; // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
_3 = discriminant(_2); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _4 = Ge(const 1_u8, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ assume(_4); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ _5 = Le(const 0_u8, _3); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+ assume(_5); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
_0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
return; // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
diff --git a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir b/src/test/mir-opt/building/enum_cast.droppy.built.after.mir
index bb5faa480..5231c2eab 100644
--- a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
+++ b/src/test/mir-opt/building/enum_cast.droppy.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `droppy` 0 mir_map
+// MIR for `droppy` after built
fn droppy() -> () {
let mut _0: (); // return place in scope 0 at $DIR/enum_cast.rs:+0:13: +0:13
@@ -6,7 +6,9 @@ fn droppy() -> () {
let _2: Droppy; // in scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
let _4: Droppy; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
let mut _5: isize; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
- let _6: Droppy; // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+ let mut _6: bool; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:27
+ let mut _7: bool; // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:27
+ let _8: Droppy; // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
scope 1 {
debug x => _2; // in scope 1 at $DIR/enum_cast.rs:+2:13: +2:14
scope 2 {
@@ -17,7 +19,7 @@ fn droppy() -> () {
}
}
scope 4 {
- debug z => _6; // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10
+ debug z => _8; // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10
}
bb0: {
@@ -29,6 +31,10 @@ fn droppy() -> () {
StorageLive(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
_4 = move _2; // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
_5 = discriminant(_4); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ _6 = Ge(const 2_isize, _5); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ assume(_6); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ _7 = Le(const 0_isize, _5); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+ assume(_7); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
_3 = move _5 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
drop(_4) -> [return: bb1, unwind: bb4]; // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27
}
@@ -44,15 +50,15 @@ fn droppy() -> () {
bb2: {
StorageDead(_2); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
StorageDead(_1); // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
- StorageLive(_6); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
- _6 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22
- FakeRead(ForLet(None), _6); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+ StorageLive(_8); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+ _8 = Droppy::B; // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22
+ FakeRead(ForLet(None), _8); // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
_0 = const (); // scope 0 at $DIR/enum_cast.rs:+0:13: +8:2
- drop(_6) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+ drop(_8) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
}
bb3: {
- StorageDead(_6); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+ StorageDead(_8); // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
return; // scope 0 at $DIR/enum_cast.rs:+8:2: +8:2
}
diff --git a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir b/src/test/mir-opt/building/enum_cast.foo.built.after.mir
index a1d29a0b9..17e0abf2e 100644
--- a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
+++ b/src/test/mir-opt/building/enum_cast.foo.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `foo` 0 mir_map
+// MIR for `foo` after built
fn foo(_1: Foo) -> usize {
debug foo => _1; // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
diff --git a/src/test/mir-opt/enum_cast.rs b/src/test/mir-opt/building/enum_cast.rs
index 090142aaf..98fd5acfb 100644
--- a/src/test/mir-opt/enum_cast.rs
+++ b/src/test/mir-opt/building/enum_cast.rs
@@ -1,6 +1,6 @@
-// EMIT_MIR enum_cast.foo.mir_map.0.mir
-// EMIT_MIR enum_cast.bar.mir_map.0.mir
-// EMIT_MIR enum_cast.boo.mir_map.0.mir
+// EMIT_MIR enum_cast.foo.built.after.mir
+// EMIT_MIR enum_cast.bar.built.after.mir
+// EMIT_MIR enum_cast.boo.built.after.mir
enum Foo {
A
@@ -27,7 +27,7 @@ fn boo(boo: Boo) -> usize {
boo as usize
}
-// EMIT_MIR enum_cast.droppy.mir_map.0.mir
+// EMIT_MIR enum_cast.droppy.built.after.mir
enum Droppy {
A, B, C
}
diff --git a/src/test/mir-opt/issue_101867.main.mir_map.0.mir b/src/test/mir-opt/building/issue_101867.main.built.after.mir
index 42a9e5587..0ebd840cf 100644
--- a/src/test/mir-opt/issue_101867.main.mir_map.0.mir
+++ b/src/test/mir-opt/building/issue_101867.main.built.after.mir
@@ -1,33 +1,33 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
| User Type Annotations
-| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue-101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
-| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue-101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
+| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<u8>) }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
|
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-101867.rs:+0:11: +0:11
- let _1: std::option::Option<u8> as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue-101867.rs:+1:9: +1:10
- let mut _2: !; // in scope 0 at $DIR/issue-101867.rs:+2:26: +4:6
+ let mut _0: (); // return place in scope 0 at $DIR/issue_101867.rs:+0:11: +0:11
+ let _1: std::option::Option<u8> as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue_101867.rs:+1:9: +1:10
+ let mut _2: !; // in scope 0 at $DIR/issue_101867.rs:+2:26: +4:6
let _3: (); // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
let mut _4: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
- let mut _6: isize; // in scope 0 at $DIR/issue-101867.rs:+2:9: +2:16
+ let mut _6: isize; // in scope 0 at $DIR/issue_101867.rs:+2:9: +2:16
scope 1 {
- debug x => _1; // in scope 1 at $DIR/issue-101867.rs:+1:9: +1:10
- let _5: u8; // in scope 1 at $DIR/issue-101867.rs:+2:14: +2:15
+ debug x => _1; // in scope 1 at $DIR/issue_101867.rs:+1:9: +1:10
+ let _5: u8; // in scope 1 at $DIR/issue_101867.rs:+2:14: +2:15
scope 2 {
- debug y => _5; // in scope 2 at $DIR/issue-101867.rs:+2:14: +2:15
+ debug y => _5; // in scope 2 at $DIR/issue_101867.rs:+2:14: +2:15
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-101867.rs:+1:9: +1:10
- _1 = Option::<u8>::Some(const 1_u8); // scope 0 at $DIR/issue-101867.rs:+1:25: +1:32
- FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue-101867.rs:+1:9: +1:10
- AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-101867.rs:+1:12: +1:22
- StorageLive(_5); // scope 1 at $DIR/issue-101867.rs:+2:14: +2:15
- FakeRead(ForMatchedPlace(None), _1); // scope 1 at $DIR/issue-101867.rs:+2:19: +2:20
- _6 = discriminant(_1); // scope 1 at $DIR/issue-101867.rs:+2:19: +2:20
- switchInt(move _6) -> [1_isize: bb4, otherwise: bb3]; // scope 1 at $DIR/issue-101867.rs:+2:9: +2:16
+ StorageLive(_1); // scope 0 at $DIR/issue_101867.rs:+1:9: +1:10
+ _1 = Option::<u8>::Some(const 1_u8); // scope 0 at $DIR/issue_101867.rs:+1:25: +1:32
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue_101867.rs:+1:9: +1:10
+ AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue_101867.rs:+1:12: +1:22
+ StorageLive(_5); // scope 1 at $DIR/issue_101867.rs:+2:14: +2:15
+ FakeRead(ForMatchedPlace(None), _1); // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20
+ _6 = discriminant(_1); // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20
+ switchInt(move _6) -> [1_isize: bb4, otherwise: bb3]; // scope 1 at $DIR/issue_101867.rs:+2:9: +2:16
}
bb1: {
@@ -44,32 +44,32 @@ fn main() -> () {
bb2: {
StorageDead(_4); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
- StorageDead(_3); // scope 1 at $DIR/issue-101867.rs:+3:16: +3:17
- unreachable; // scope 1 at $DIR/issue-101867.rs:+2:26: +4:6
+ StorageDead(_3); // scope 1 at $DIR/issue_101867.rs:+3:16: +3:17
+ unreachable; // scope 1 at $DIR/issue_101867.rs:+2:26: +4:6
}
bb3: {
- goto -> bb6; // scope 1 at $DIR/issue-101867.rs:+2:19: +2:20
+ goto -> bb6; // scope 1 at $DIR/issue_101867.rs:+2:19: +2:20
}
bb4: {
- falseEdge -> [real: bb5, imaginary: bb3]; // scope 1 at $DIR/issue-101867.rs:+2:9: +2:16
+ falseEdge -> [real: bb5, imaginary: bb3]; // scope 1 at $DIR/issue_101867.rs:+2:9: +2:16
}
bb5: {
- _5 = ((_1 as Some).0: u8); // scope 1 at $DIR/issue-101867.rs:+2:14: +2:15
- _0 = const (); // scope 0 at $DIR/issue-101867.rs:+0:11: +5:2
- StorageDead(_5); // scope 1 at $DIR/issue-101867.rs:+5:1: +5:2
- StorageDead(_1); // scope 0 at $DIR/issue-101867.rs:+5:1: +5:2
- return; // scope 0 at $DIR/issue-101867.rs:+5:2: +5:2
+ _5 = ((_1 as Some).0: u8); // scope 1 at $DIR/issue_101867.rs:+2:14: +2:15
+ _0 = const (); // scope 0 at $DIR/issue_101867.rs:+0:11: +5:2
+ StorageDead(_5); // scope 1 at $DIR/issue_101867.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/issue_101867.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/issue_101867.rs:+5:2: +5:2
}
bb6: {
- StorageDead(_5); // scope 1 at $DIR/issue-101867.rs:+5:1: +5:2
- goto -> bb1; // scope 0 at $DIR/issue-101867.rs:+0:11: +5:2
+ StorageDead(_5); // scope 1 at $DIR/issue_101867.rs:+5:1: +5:2
+ goto -> bb1; // scope 0 at $DIR/issue_101867.rs:+0:11: +5:2
}
bb7 (cleanup): {
- resume; // scope 0 at $DIR/issue-101867.rs:+0:1: +5:2
+ resume; // scope 0 at $DIR/issue_101867.rs:+0:1: +5:2
}
}
diff --git a/src/test/mir-opt/issue-101867.rs b/src/test/mir-opt/building/issue_101867.rs
index 8a357eb79..a32d8cb37 100644
--- a/src/test/mir-opt/issue-101867.rs
+++ b/src/test/mir-opt/building/issue_101867.rs
@@ -1,4 +1,4 @@
-// EMIT_MIR issue_101867.main.mir_map.0.mir
+// EMIT_MIR issue_101867.main.built.after.mir
fn main() {
let x: Option<u8> = Some(1);
let Some(y) = x else {
diff --git a/src/test/mir-opt/issue_49232.main.mir_map.0.mir b/src/test/mir-opt/building/issue_49232.main.built.after.mir
index 821323b5e..9182bcaa2 100644
--- a/src/test/mir-opt/issue_49232.main.mir_map.0.mir
+++ b/src/test/mir-opt/building/issue_49232.main.built.after.mir
@@ -1,82 +1,82 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-49232.rs:+0:11: +0:11
- let mut _1: (); // in scope 0 at $DIR/issue-49232.rs:+0:1: +10:2
- let _2: i32; // in scope 0 at $DIR/issue-49232.rs:+2:13: +2:19
- let mut _3: bool; // in scope 0 at $DIR/issue-49232.rs:+3:19: +3:23
- let mut _4: !; // in scope 0 at $DIR/issue-49232.rs:+5:25: +5:30
- let _5: (); // in scope 0 at $DIR/issue-49232.rs:+8:9: +8:22
- let mut _6: &i32; // in scope 0 at $DIR/issue-49232.rs:+8:14: +8:21
+ let mut _0: (); // return place in scope 0 at $DIR/issue_49232.rs:+0:11: +0:11
+ let mut _1: (); // in scope 0 at $DIR/issue_49232.rs:+0:1: +10:2
+ let _2: i32; // in scope 0 at $DIR/issue_49232.rs:+2:13: +2:19
+ let mut _3: bool; // in scope 0 at $DIR/issue_49232.rs:+3:19: +3:23
+ let mut _4: !; // in scope 0 at $DIR/issue_49232.rs:+5:25: +5:30
+ let _5: (); // in scope 0 at $DIR/issue_49232.rs:+8:9: +8:22
+ let mut _6: &i32; // in scope 0 at $DIR/issue_49232.rs:+8:14: +8:21
scope 1 {
- debug beacon => _2; // in scope 1 at $DIR/issue-49232.rs:+2:13: +2:19
+ debug beacon => _2; // in scope 1 at $DIR/issue_49232.rs:+2:13: +2:19
}
bb0: {
- goto -> bb1; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6
+ goto -> bb1; // scope 0 at $DIR/issue_49232.rs:+1:5: +9:6
}
bb1: {
- falseUnwind -> [real: bb2, cleanup: bb11]; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6
+ falseUnwind -> [real: bb2, cleanup: bb11]; // scope 0 at $DIR/issue_49232.rs:+1:5: +9:6
}
bb2: {
- StorageLive(_2); // scope 0 at $DIR/issue-49232.rs:+2:13: +2:19
- StorageLive(_3); // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23
- _3 = const true; // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23
- FakeRead(ForMatchedPlace(None), _3); // scope 0 at $DIR/issue-49232.rs:+3:19: +3:23
- switchInt(_3) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/issue-49232.rs:+3:13: +3:23
+ StorageLive(_2); // scope 0 at $DIR/issue_49232.rs:+2:13: +2:19
+ StorageLive(_3); // scope 0 at $DIR/issue_49232.rs:+3:19: +3:23
+ _3 = const true; // scope 0 at $DIR/issue_49232.rs:+3:19: +3:23
+ FakeRead(ForMatchedPlace(None), _3); // scope 0 at $DIR/issue_49232.rs:+3:19: +3:23
+ switchInt(_3) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/issue_49232.rs:+3:13: +3:23
}
bb3: {
- falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at $DIR/issue-49232.rs:+4:17: +4:22
+ falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at $DIR/issue_49232.rs:+4:17: +4:22
}
bb4: {
- _0 = const (); // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30
- goto -> bb10; // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30
+ _0 = const (); // scope 0 at $DIR/issue_49232.rs:+5:25: +5:30
+ goto -> bb10; // scope 0 at $DIR/issue_49232.rs:+5:25: +5:30
}
bb5: {
- _2 = const 4_i32; // scope 0 at $DIR/issue-49232.rs:+4:26: +4:27
- goto -> bb8; // scope 0 at $DIR/issue-49232.rs:+4:26: +4:27
+ _2 = const 4_i32; // scope 0 at $DIR/issue_49232.rs:+4:26: +4:27
+ goto -> bb8; // scope 0 at $DIR/issue_49232.rs:+4:26: +4:27
}
bb6: {
- unreachable; // scope 0 at $DIR/issue-49232.rs:+5:25: +5:30
+ unreachable; // scope 0 at $DIR/issue_49232.rs:+5:25: +5:30
}
bb7: {
- goto -> bb8; // scope 0 at $DIR/issue-49232.rs:+6:13: +6:14
+ goto -> bb8; // scope 0 at $DIR/issue_49232.rs:+6:13: +6:14
}
bb8: {
- FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-49232.rs:+2:13: +2:19
- StorageDead(_3); // scope 0 at $DIR/issue-49232.rs:+7:10: +7:11
- StorageLive(_5); // scope 1 at $DIR/issue-49232.rs:+8:9: +8:22
- StorageLive(_6); // scope 1 at $DIR/issue-49232.rs:+8:14: +8:21
- _6 = &_2; // scope 1 at $DIR/issue-49232.rs:+8:14: +8:21
- _5 = std::mem::drop::<&i32>(move _6) -> [return: bb9, unwind: bb11]; // scope 1 at $DIR/issue-49232.rs:+8:9: +8:22
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_49232.rs:+2:13: +2:19
+ StorageDead(_3); // scope 0 at $DIR/issue_49232.rs:+7:10: +7:11
+ StorageLive(_5); // scope 1 at $DIR/issue_49232.rs:+8:9: +8:22
+ StorageLive(_6); // scope 1 at $DIR/issue_49232.rs:+8:14: +8:21
+ _6 = &_2; // scope 1 at $DIR/issue_49232.rs:+8:14: +8:21
+ _5 = std::mem::drop::<&i32>(move _6) -> [return: bb9, unwind: bb11]; // scope 1 at $DIR/issue_49232.rs:+8:9: +8:22
// mir::Constant
- // + span: $DIR/issue-49232.rs:13:9: 13:13
+ // + span: $DIR/issue_49232.rs:13:9: 13:13
// + literal: Const { ty: fn(&i32) {std::mem::drop::<&i32>}, val: Value(<ZST>) }
}
bb9: {
- StorageDead(_6); // scope 1 at $DIR/issue-49232.rs:+8:21: +8:22
- StorageDead(_5); // scope 1 at $DIR/issue-49232.rs:+8:22: +8:23
- _1 = const (); // scope 0 at $DIR/issue-49232.rs:+1:10: +9:6
- StorageDead(_2); // scope 0 at $DIR/issue-49232.rs:+9:5: +9:6
- goto -> bb1; // scope 0 at $DIR/issue-49232.rs:+1:5: +9:6
+ StorageDead(_6); // scope 1 at $DIR/issue_49232.rs:+8:21: +8:22
+ StorageDead(_5); // scope 1 at $DIR/issue_49232.rs:+8:22: +8:23
+ _1 = const (); // scope 0 at $DIR/issue_49232.rs:+1:10: +9:6
+ StorageDead(_2); // scope 0 at $DIR/issue_49232.rs:+9:5: +9:6
+ goto -> bb1; // scope 0 at $DIR/issue_49232.rs:+1:5: +9:6
}
bb10: {
- StorageDead(_3); // scope 0 at $DIR/issue-49232.rs:+7:10: +7:11
- StorageDead(_2); // scope 0 at $DIR/issue-49232.rs:+9:5: +9:6
- return; // scope 0 at $DIR/issue-49232.rs:+10:2: +10:2
+ StorageDead(_3); // scope 0 at $DIR/issue_49232.rs:+7:10: +7:11
+ StorageDead(_2); // scope 0 at $DIR/issue_49232.rs:+9:5: +9:6
+ return; // scope 0 at $DIR/issue_49232.rs:+10:2: +10:2
}
bb11 (cleanup): {
- resume; // scope 0 at $DIR/issue-49232.rs:+0:1: +10:2
+ resume; // scope 0 at $DIR/issue_49232.rs:+0:1: +10:2
}
}
diff --git a/src/test/mir-opt/issue-49232.rs b/src/test/mir-opt/building/issue_49232.rs
index 86494c76a..7e9f0de81 100644
--- a/src/test/mir-opt/issue-49232.rs
+++ b/src/test/mir-opt/building/issue_49232.rs
@@ -1,7 +1,7 @@
// We must mark a variable whose initialization fails due to an
// abort statement as StorageDead.
-// EMIT_MIR issue_49232.main.mir_map.0.mir
+// EMIT_MIR issue_49232.main.built.after.mir
fn main() {
loop {
let beacon = {
diff --git a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/building/match_false_edges.full_tested_match.built.after.mir
index b193a8d76..9a190c3d6 100644
--- a/src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
+++ b/src/test/mir-opt/building/match_false_edges.full_tested_match.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `full_tested_match` after PromoteTemps
+// MIR for `full_tested_match` after built
fn full_tested_match() -> () {
let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:+0:28: +0:28
@@ -12,7 +12,6 @@ fn full_tested_match() -> () {
let mut _8: i32; // in scope 0 at $DIR/match_false_edges.rs:+2:35: +2:36
let _9: i32; // in scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15
let mut _10: i32; // in scope 0 at $DIR/match_false_edges.rs:+3:24: +3:25
- let mut _11: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
scope 1 {
}
scope 2 {
@@ -34,7 +33,7 @@ fn full_tested_match() -> () {
bb1: {
_1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:+4:17: +4:23
- goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+4:17: +4:23
+ goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:+4:17: +4:23
}
bb2: {
@@ -42,7 +41,7 @@ fn full_tested_match() -> () {
}
bb3: {
- falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:16
+ falseEdge -> [real: bb10, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:16
}
bb4: {
@@ -51,14 +50,10 @@ fn full_tested_match() -> () {
bb5: {
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
- _11 = const _; // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
- // mir::Constant
- // + span: $DIR/match_false_edges.rs:14:14: 14:15
- // + literal: Const { ty: &Option<i32>, val: Unevaluated(full_tested_match, [], Some(promoted[0])) }
- _6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
+ _6 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
_4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
- _7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ _7 = guard() -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
// mir::Constant
// + span: $DIR/match_false_edges.rs:14:20: 14:25
// + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) }
@@ -80,16 +75,20 @@ fn full_tested_match() -> () {
StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:+2:36: +2:37
StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
- goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
}
bb8: {
+ goto -> bb9; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ }
+
+ bb9: {
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
goto -> bb3; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
}
- bb9: {
+ bb10: {
StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15
_9 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+3:14: +3:15
StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:+3:24: +3:25
@@ -97,17 +96,17 @@ fn full_tested_match() -> () {
_1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:+3:20: +3:26
StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:+3:25: +3:26
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26
- goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26
+ goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:+3:25: +3:26
}
- bb10: {
+ bb11: {
StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
_0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:28: +6:2
return; // scope 0 at $DIR/match_false_edges.rs:+6:2: +6:2
}
- bb11 (cleanup): {
+ bb12 (cleanup): {
resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2
}
}
diff --git a/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir b/src/test/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir
index 145ed878f..1c9953e7e 100644
--- a/src/test/mir-opt/match_false_edges.full_tested_match2.PromoteTemps.before.mir
+++ b/src/test/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `full_tested_match2` before PromoteTemps
+// MIR for `full_tested_match2` after built
fn full_tested_match2() -> () {
let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:+0:29: +0:29
@@ -32,7 +32,7 @@ fn full_tested_match2() -> () {
}
bb1: {
- falseEdge -> [real: bb9, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:13
+ falseEdge -> [real: bb10, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:13
}
bb2: {
@@ -47,7 +47,7 @@ fn full_tested_match2() -> () {
_1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:+4:20: +4:26
StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:+4:25: +4:26
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:+4:25: +4:26
- goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+4:25: +4:26
+ goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:+4:25: +4:26
}
bb4: {
@@ -59,7 +59,7 @@ fn full_tested_match2() -> () {
_6 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:15
_4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:27
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
- _7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ _7 = guard() -> [return: bb6, unwind: bb12]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
// mir::Constant
// + span: $DIR/match_false_edges.rs:25:20: 25:25
// + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) }
@@ -81,28 +81,32 @@ fn full_tested_match2() -> () {
StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:+2:36: +2:37
StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
- goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
+ goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
}
bb8: {
+ goto -> bb9; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
+ }
+
+ bb9: {
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:26: +2:27
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:36: +2:37
falseEdge -> [real: bb3, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:20: +2:27
}
- bb9: {
+ bb10: {
_1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23
- goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23
+ goto -> bb11; // scope 0 at $DIR/match_false_edges.rs:+3:17: +3:23
}
- bb10: {
+ bb11: {
StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7
_0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:29: +6:2
return; // scope 0 at $DIR/match_false_edges.rs:+6:2: +6:2
}
- bb11 (cleanup): {
+ bb12 (cleanup): {
resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +6:2
}
}
diff --git a/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir b/src/test/mir-opt/building/match_false_edges.main.built.after.mir
index 8f40e8a88..08c67d39d 100644
--- a/src/test/mir-opt/match_false_edges.main.PromoteTemps.before.mir
+++ b/src/test/mir-opt/building/match_false_edges.main.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `main` before PromoteTemps
+// MIR for `main` after built
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:+0:11: +0:11
@@ -43,41 +43,54 @@ fn main() -> () {
}
bb1: {
- falseEdge -> [real: bb9, imaginary: bb4]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
+ falseEdge -> [real: bb13, imaginary: bb6]; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
}
bb2: {
- falseEdge -> [real: bb5, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:17
+ falseEdge -> [real: bb8, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:9: +2:17
}
bb3: {
+ goto -> bb1; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+ }
+
+ bb4: {
+ _3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
+ switchInt(move _3) -> [1_isize: bb6, otherwise: bb5]; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+ }
+
+ bb5: {
StorageLive(_14); // scope 0 at $DIR/match_false_edges.rs:+5:9: +5:11
_14 = _2; // scope 0 at $DIR/match_false_edges.rs:+5:9: +5:11
_1 = const 4_i32; // scope 5 at $DIR/match_false_edges.rs:+5:15: +5:16
StorageDead(_14); // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16
- goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16
+ goto -> bb19; // scope 0 at $DIR/match_false_edges.rs:+5:15: +5:16
}
- bb4: {
- falseEdge -> [real: bb10, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+4:9: +4:16
+ bb6: {
+ falseEdge -> [real: bb14, imaginary: bb5]; // scope 0 at $DIR/match_false_edges.rs:+4:9: +4:16
}
- bb5: {
+ bb7: {
+ goto -> bb5; // scope 0 at $DIR/match_false_edges.rs:+1:13: +1:26
+ }
+
+ bb8: {
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16
_7 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+2:14: +2:16
_5 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
StorageLive(_8); // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
- _8 = guard() -> [return: bb6, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ _8 = guard() -> [return: bb9, unwind: bb20]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
// mir::Constant
// + span: $DIR/match_false_edges.rs:34:21: 34:26
// + literal: Const { ty: fn() -> bool {guard}, val: Value(<ZST>) }
}
- bb6: {
- switchInt(move _8) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ bb9: {
+ switchInt(move _8) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
}
- bb7: {
+ bb10: {
StorageDead(_8); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
FakeRead(ForGuardBinding, _7); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
@@ -86,41 +99,45 @@ fn main() -> () {
_1 = const 1_i32; // scope 2 at $DIR/match_false_edges.rs:+2:32: +2:33
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
- goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
+ goto -> bb19; // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
}
- bb8: {
+ bb11: {
+ goto -> bb12; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ }
+
+ bb12: {
StorageDead(_8); // scope 0 at $DIR/match_false_edges.rs:+2:27: +2:28
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:+2:32: +2:33
- falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
+ falseEdge -> [real: bb3, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:+2:21: +2:28
}
- bb9: {
+ bb13: {
StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
_9 = _2; // scope 0 at $DIR/match_false_edges.rs:+3:9: +3:11
_1 = const 2_i32; // scope 3 at $DIR/match_false_edges.rs:+3:15: +3:16
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16
- goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16
+ goto -> bb19; // scope 0 at $DIR/match_false_edges.rs:+3:15: +3:16
}
- bb10: {
+ bb14: {
StorageLive(_11); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
_11 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:+4:14: +4:15
_5 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:+1:19: +1:26
StorageLive(_12); // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
StorageLive(_13); // scope 0 at $DIR/match_false_edges.rs:+4:27: +4:28
_13 = (*_11); // scope 0 at $DIR/match_false_edges.rs:+4:27: +4:28
- _12 = guard2(move _13) -> [return: bb11, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ _12 = guard2(move _13) -> [return: bb15, unwind: bb20]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
// mir::Constant
// + span: $DIR/match_false_edges.rs:36:20: 36:26
// + literal: Const { ty: fn(i32) -> bool {guard2}, val: Value(<ZST>) }
}
- bb11: {
- switchInt(move _12) -> [false: bb13, otherwise: bb12]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ bb15: {
+ switchInt(move _12) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
}
- bb12: {
+ bb16: {
StorageDead(_13); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
StorageDead(_12); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
@@ -130,24 +147,28 @@ fn main() -> () {
_1 = const 3_i32; // scope 4 at $DIR/match_false_edges.rs:+4:33: +4:34
StorageDead(_10); // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
- goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
+ goto -> bb19; // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
}
- bb13: {
+ bb17: {
+ goto -> bb18; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ }
+
+ bb18: {
StorageDead(_13); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
StorageDead(_12); // scope 0 at $DIR/match_false_edges.rs:+4:28: +4:29
StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:+4:33: +4:34
- falseEdge -> [real: bb3, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
+ falseEdge -> [real: bb7, imaginary: bb5]; // scope 0 at $DIR/match_false_edges.rs:+4:20: +4:29
}
- bb14: {
+ bb19: {
StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+6:6: +6:7
StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+6:6: +6:7
_0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:11: +7:2
return; // scope 0 at $DIR/match_false_edges.rs:+7:2: +7:2
}
- bb15 (cleanup): {
+ bb20 (cleanup): {
resume; // scope 0 at $DIR/match_false_edges.rs:+0:1: +7:2
}
}
diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/building/match_false_edges.rs
index 3603253da..ddfcc1493 100644
--- a/src/test/mir-opt/match_false_edges.rs
+++ b/src/test/mir-opt/building/match_false_edges.rs
@@ -8,7 +8,7 @@ fn guard2(_: i32) -> bool {
// no_mangle to make sure this gets instantiated even in an executable.
#[no_mangle]
-// EMIT_MIR match_false_edges.full_tested_match.PromoteTemps.after.mir
+// EMIT_MIR match_false_edges.full_tested_match.built.after.mir
pub fn full_tested_match() {
let _ = match Some(42) {
Some(x) if guard() => (1, x),
@@ -19,7 +19,7 @@ pub fn full_tested_match() {
// no_mangle to make sure this gets instantiated even in an executable.
#[no_mangle]
-// EMIT_MIR match_false_edges.full_tested_match2.PromoteTemps.before.mir
+// EMIT_MIR match_false_edges.full_tested_match2.built.after.mir
pub fn full_tested_match2() {
let _ = match Some(42) {
Some(x) if guard() => (1, x),
@@ -28,7 +28,7 @@ pub fn full_tested_match2() {
};
}
-// EMIT_MIR match_false_edges.main.PromoteTemps.before.mir
+// EMIT_MIR match_false_edges.main.built.after.mir
fn main() {
let _ = match Some(1) {
Some(_w) if guard() => 1,
diff --git a/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir b/src/test/mir-opt/building/receiver_ptr_mutability.main.built.after.mir
index 45797ec06..41eb00363 100644
--- a/src/test/mir-opt/receiver_ptr_mutability.main.mir_map.0.mir
+++ b/src/test/mir-opt/building/receiver_ptr_mutability.main.built.after.mir
@@ -1,96 +1,96 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
| User Type Annotations
-| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test
-| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:14:14: 14:23, inferred_ty: *mut Test
-| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test
-| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver-ptr-mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test
+| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver_ptr_mutability.rs:14:14: 14:23, inferred_ty: *mut Test
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(*mut Test) }, span: $DIR/receiver_ptr_mutability.rs:14:14: 14:23, inferred_ty: *mut Test
+| 2: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver_ptr_mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test
+| 3: user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], value: Ty(&&&&*mut Test) }, span: $DIR/receiver_ptr_mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test
|
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/receiver-ptr-mutability.rs:+0:11: +0:11
- let _1: *mut Test as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12
- let _2: (); // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
- let mut _3: *const Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
- let mut _4: *mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8
- let _6: &&&&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41
- let _7: &&&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41
- let _8: &&*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41
- let _9: &*mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41
- let _10: (); // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
- let mut _11: *const Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
- let mut _12: *mut Test; // in scope 0 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ let mut _0: (); // return place in scope 0 at $DIR/receiver_ptr_mutability.rs:+0:11: +0:11
+ let _1: *mut Test as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+1:9: +1:12
+ let _2: (); // in scope 0 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12
+ let mut _3: *const Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12
+ let mut _4: *mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:8
+ let _6: &&&&*mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+5:34: +5:41
+ let _7: &&&*mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+5:35: +5:41
+ let _8: &&*mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+5:36: +5:41
+ let _9: &*mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+5:37: +5:41
+ let _10: (); // in scope 0 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16
+ let mut _11: *const Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16
+ let mut _12: *mut Test; // in scope 0 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16
scope 1 {
- debug ptr => _1; // in scope 1 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12
- let _5: &&&&*mut Test as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16
+ debug ptr => _1; // in scope 1 at $DIR/receiver_ptr_mutability.rs:+1:9: +1:12
+ let _5: &&&&*mut Test as UserTypeProjection { base: UserType(2), projs: [] }; // in scope 1 at $DIR/receiver_ptr_mutability.rs:+5:9: +5:16
scope 2 {
- debug ptr_ref => _5; // in scope 2 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16
+ debug ptr_ref => _5; // in scope 2 at $DIR/receiver_ptr_mutability.rs:+5:9: +5:16
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12
- _1 = null_mut::<Test>() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:26: +1:46
+ StorageLive(_1); // scope 0 at $DIR/receiver_ptr_mutability.rs:+1:9: +1:12
+ _1 = null_mut::<Test>() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/receiver_ptr_mutability.rs:+1:26: +1:46
// mir::Constant
- // + span: $DIR/receiver-ptr-mutability.rs:14:26: 14:44
+ // + span: $DIR/receiver_ptr_mutability.rs:14:26: 14:44
// + literal: Const { ty: fn() -> *mut Test {null_mut::<Test>}, val: Value(<ZST>) }
}
bb1: {
- FakeRead(ForLet(None), _1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:9: +1:12
- AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/receiver-ptr-mutability.rs:+1:14: +1:23
- StorageLive(_2); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
- StorageLive(_3); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
- StorageLive(_4); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8
- _4 = _1; // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:8
- _3 = move _4 as *const Test (Pointer(MutToConstPointer)); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
- StorageDead(_4); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:7: +2:8
- _2 = Test::x(move _3) -> [return: bb2, unwind: bb4]; // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:5: +2:12
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/receiver_ptr_mutability.rs:+1:9: +1:12
+ AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/receiver_ptr_mutability.rs:+1:14: +1:23
+ StorageLive(_2); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12
+ StorageLive(_3); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12
+ StorageLive(_4); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:8
+ _4 = _1; // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:8
+ _3 = move _4 as *const Test (Pointer(MutToConstPointer)); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12
+ StorageDead(_4); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:7: +2:8
+ _2 = Test::x(move _3) -> [return: bb2, unwind: bb4]; // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:5: +2:12
// mir::Constant
- // + span: $DIR/receiver-ptr-mutability.rs:15:9: 15:10
+ // + span: $DIR/receiver_ptr_mutability.rs:15:9: 15:10
// + literal: Const { ty: fn(*const Test) {Test::x}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_3); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:11: +2:12
- StorageDead(_2); // scope 1 at $DIR/receiver-ptr-mutability.rs:+2:12: +2:13
- StorageLive(_5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16
- StorageLive(_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41
- StorageLive(_7); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41
- StorageLive(_8); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41
- StorageLive(_9); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41
- _9 = &_1; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:37: +5:41
- _8 = &_9; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:36: +5:41
- _7 = &_8; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:35: +5:41
- _6 = &_7; // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41
- _5 = &(*_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:34: +5:41
- FakeRead(ForLet(None), _5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:9: +5:16
- AscribeUserType(_5, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:18: +5:31
- StorageDead(_6); // scope 1 at $DIR/receiver-ptr-mutability.rs:+5:41: +5:42
- StorageLive(_10); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
- StorageLive(_11); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
- StorageLive(_12); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
- _12 = (*(*(*(*_5)))); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
- _11 = move _12 as *const Test (Pointer(MutToConstPointer)); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
- StorageDead(_12); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:11: +6:12
- _10 = Test::x(move _11) -> [return: bb3, unwind: bb4]; // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:5: +6:16
+ StorageDead(_3); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:11: +2:12
+ StorageDead(_2); // scope 1 at $DIR/receiver_ptr_mutability.rs:+2:12: +2:13
+ StorageLive(_5); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:9: +5:16
+ StorageLive(_6); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:34: +5:41
+ StorageLive(_7); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:35: +5:41
+ StorageLive(_8); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:36: +5:41
+ StorageLive(_9); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:37: +5:41
+ _9 = &_1; // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:37: +5:41
+ _8 = &_9; // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:36: +5:41
+ _7 = &_8; // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:35: +5:41
+ _6 = &_7; // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:34: +5:41
+ _5 = &(*_6); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:34: +5:41
+ FakeRead(ForLet(None), _5); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:9: +5:16
+ AscribeUserType(_5, o, UserTypeProjection { base: UserType(3), projs: [] }); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:18: +5:31
+ StorageDead(_6); // scope 1 at $DIR/receiver_ptr_mutability.rs:+5:41: +5:42
+ StorageLive(_10); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16
+ StorageLive(_11); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16
+ StorageLive(_12); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16
+ _12 = (*(*(*(*_5)))); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16
+ _11 = move _12 as *const Test (Pointer(MutToConstPointer)); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16
+ StorageDead(_12); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:11: +6:12
+ _10 = Test::x(move _11) -> [return: bb3, unwind: bb4]; // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:5: +6:16
// mir::Constant
- // + span: $DIR/receiver-ptr-mutability.rs:19:13: 19:14
+ // + span: $DIR/receiver_ptr_mutability.rs:19:13: 19:14
// + literal: Const { ty: fn(*const Test) {Test::x}, val: Value(<ZST>) }
}
bb3: {
- StorageDead(_11); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:15: +6:16
- StorageDead(_10); // scope 2 at $DIR/receiver-ptr-mutability.rs:+6:16: +6:17
- _0 = const (); // scope 0 at $DIR/receiver-ptr-mutability.rs:+0:11: +7:2
- StorageDead(_9); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2
- StorageDead(_8); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2
- StorageDead(_7); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2
- StorageDead(_5); // scope 1 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2
- StorageDead(_1); // scope 0 at $DIR/receiver-ptr-mutability.rs:+7:1: +7:2
- return; // scope 0 at $DIR/receiver-ptr-mutability.rs:+7:2: +7:2
+ StorageDead(_11); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:15: +6:16
+ StorageDead(_10); // scope 2 at $DIR/receiver_ptr_mutability.rs:+6:16: +6:17
+ _0 = const (); // scope 0 at $DIR/receiver_ptr_mutability.rs:+0:11: +7:2
+ StorageDead(_9); // scope 1 at $DIR/receiver_ptr_mutability.rs:+7:1: +7:2
+ StorageDead(_8); // scope 1 at $DIR/receiver_ptr_mutability.rs:+7:1: +7:2
+ StorageDead(_7); // scope 1 at $DIR/receiver_ptr_mutability.rs:+7:1: +7:2
+ StorageDead(_5); // scope 1 at $DIR/receiver_ptr_mutability.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/receiver_ptr_mutability.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/receiver_ptr_mutability.rs:+7:2: +7:2
}
bb4 (cleanup): {
- resume; // scope 0 at $DIR/receiver-ptr-mutability.rs:+0:1: +7:2
+ resume; // scope 0 at $DIR/receiver_ptr_mutability.rs:+0:1: +7:2
}
}
diff --git a/src/test/mir-opt/receiver-ptr-mutability.rs b/src/test/mir-opt/building/receiver_ptr_mutability.rs
index 8e2ff0451..668530968 100644
--- a/src/test/mir-opt/receiver-ptr-mutability.rs
+++ b/src/test/mir-opt/building/receiver_ptr_mutability.rs
@@ -1,4 +1,4 @@
-// EMIT_MIR receiver_ptr_mutability.main.mir_map.0.mir
+// EMIT_MIR receiver_ptr_mutability.main.built.after.mir
#![feature(arbitrary_self_types)]
diff --git a/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir b/src/test/mir-opt/building/simple_match.match_bool.built.after.mir
index 3bef6aa05..a4516026c 100644
--- a/src/test/mir-opt/simple_match.match_bool.mir_map.0.mir
+++ b/src/test/mir-opt/building/simple_match.match_bool.built.after.mir
@@ -1,29 +1,29 @@
-// MIR for `match_bool` 0 mir_map
+// MIR for `match_bool` after built
fn match_bool(_1: bool) -> usize {
- debug x => _1; // in scope 0 at $DIR/simple-match.rs:+0:15: +0:16
- let mut _0: usize; // return place in scope 0 at $DIR/simple-match.rs:+0:27: +0:32
+ debug x => _1; // in scope 0 at $DIR/simple_match.rs:+0:15: +0:16
+ let mut _0: usize; // return place in scope 0 at $DIR/simple_match.rs:+0:27: +0:32
bb0: {
- FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple-match.rs:+1:11: +1:12
- switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple-match.rs:+1:5: +1:12
+ FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/simple_match.rs:+1:11: +1:12
+ switchInt(_1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/simple_match.rs:+1:5: +1:12
}
bb1: {
- falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple-match.rs:+2:9: +2:13
+ falseEdge -> [real: bb3, imaginary: bb2]; // scope 0 at $DIR/simple_match.rs:+2:9: +2:13
}
bb2: {
- _0 = const 20_usize; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
- goto -> bb4; // scope 0 at $DIR/simple-match.rs:+3:14: +3:16
+ _0 = const 20_usize; // scope 0 at $DIR/simple_match.rs:+3:14: +3:16
+ goto -> bb4; // scope 0 at $DIR/simple_match.rs:+3:14: +3:16
}
bb3: {
- _0 = const 10_usize; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
- goto -> bb4; // scope 0 at $DIR/simple-match.rs:+2:17: +2:19
+ _0 = const 10_usize; // scope 0 at $DIR/simple_match.rs:+2:17: +2:19
+ goto -> bb4; // scope 0 at $DIR/simple_match.rs:+2:17: +2:19
}
bb4: {
- return; // scope 0 at $DIR/simple-match.rs:+5:2: +5:2
+ return; // scope 0 at $DIR/simple_match.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/simple-match.rs b/src/test/mir-opt/building/simple_match.rs
index 103033c4e..0ef97dde6 100644
--- a/src/test/mir-opt/simple-match.rs
+++ b/src/test/mir-opt/building/simple_match.rs
@@ -1,7 +1,7 @@
// Test that we don't generate unnecessarily large MIR for very simple matches
-// EMIT_MIR simple_match.match_bool.mir_map.0.mir
+// EMIT_MIR simple_match.match_bool.built.after.mir
fn match_bool(x: bool) -> usize {
match x {
true => 10,
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir b/src/test/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir
index e50067ea2..1d3f77e07 100644
--- a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir
+++ b/src/test/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `XXX` 0 mir_map
+// MIR for `XXX` after built
static XXX: &Foo = {
let mut _0: &Foo; // return place in scope 0 at $DIR/storage_live_dead_in_statics.rs:+0:13: +0:25
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.rs b/src/test/mir-opt/building/storage_live_dead_in_statics.rs
index b03de8612..79f709148 100644
--- a/src/test/mir-opt/storage_live_dead_in_statics.rs
+++ b/src/test/mir-opt/building/storage_live_dead_in_statics.rs
@@ -1,7 +1,7 @@
// Check that when we compile the static `XXX` into MIR, we do not
// generate `StorageStart` or `StorageEnd` statements.
-// EMIT_MIR storage_live_dead_in_statics.XXX.mir_map.0.mir
+// EMIT_MIR storage_live_dead_in_statics.XXX.built.after.mir
static XXX: &'static Foo = &Foo {
tup: "hi",
data: &[
diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir b/src/test/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
index 6a5021139..234cd0839 100644
--- a/src/test/mir-opt/uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
+++ b/src/test/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `move_out_by_subslice` 0 mir_map
+// MIR for `move_out_by_subslice` after built
fn move_out_by_subslice() -> () {
let mut _0: (); // return place in scope 0 at $DIR/uniform_array_move_out.rs:+0:27: +0:27
diff --git a/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir b/src/test/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
index 23a50b22a..24a189498 100644
--- a/src/test/mir-opt/uniform_array_move_out.move_out_from_end.mir_map.0.mir
+++ b/src/test/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
@@ -1,4 +1,4 @@
-// MIR for `move_out_from_end` 0 mir_map
+// MIR for `move_out_from_end` after built
fn move_out_from_end() -> () {
let mut _0: (); // return place in scope 0 at $DIR/uniform_array_move_out.rs:+0:24: +0:24
diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/building/uniform_array_move_out.rs
index 35e425528..e925036ec 100644
--- a/src/test/mir-opt/uniform_array_move_out.rs
+++ b/src/test/mir-opt/building/uniform_array_move_out.rs
@@ -1,12 +1,12 @@
#![feature(box_syntax)]
-// EMIT_MIR uniform_array_move_out.move_out_from_end.mir_map.0.mir
+// EMIT_MIR uniform_array_move_out.move_out_from_end.built.after.mir
fn move_out_from_end() {
let a = [box 1, box 2];
let [.., _y] = a;
}
-// EMIT_MIR uniform_array_move_out.move_out_by_subslice.mir_map.0.mir
+// EMIT_MIR uniform_array_move_out.move_out_by_subslice.built.after.mir
fn move_out_by_subslice() {
let a = [box 1, box 2];
let [_y @ ..] = a;
diff --git a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
index a092f3752..e959e1b2f 100644
--- a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
+++ b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff
@@ -30,14 +30,19 @@
- debug s => _9; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10
+ debug s => const "hello, world!"; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10
let _10: (bool, bool, u32); // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ let _16: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ let _17: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ let _18: u32; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
scope 6 {
- debug f => _10; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ debug f => (bool, bool, u32){ .0 => _16, .1 => _17, .2 => _18, }; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10
let _11: std::option::Option<u16>; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
scope 7 {
debug o => _11; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10
let _12: Point; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ let _19: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ let _20: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
scope 8 {
- debug p => _12; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ debug p => Point{ .0 => _19, .1 => _20, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10
let _13: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
scope 9 {
- debug a => _13; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10
@@ -78,19 +83,25 @@
// mir::Constant
// + span: $DIR/const_debuginfo.rs:14:13: 14:28
// + literal: Const { ty: &str, val: Value(Slice(..)) }
- StorageLive(_10); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
- Deinit(_10); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
- (_10.0: bool) = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
- (_10.1: bool) = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
- (_10.2: u32) = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ StorageLive(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ StorageLive(_17); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ StorageLive(_18); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
+ Deinit(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ Deinit(_17); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ Deinit(_18); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ _16 = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ _17 = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
+ _18 = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
StorageLive(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
Deinit(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
((_11 as Some).0: u16) = const 99_u16; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
discriminant(_11) = 1; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
- StorageLive(_12); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
- Deinit(_12); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
- (_12.0: u32) = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
- (_12.1: u32) = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ StorageLive(_19); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ StorageLive(_20); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
+ Deinit(_19); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ Deinit(_20); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ _19 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
+ _20 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
StorageLive(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
StorageLive(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16
_14 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16
@@ -101,9 +112,12 @@
StorageDead(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22
nop; // scope 0 at $DIR/const_debuginfo.rs:+0:11: +14:2
StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2
- StorageDead(_12); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_19); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_20); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2
StorageDead(_11); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2
- StorageDead(_10); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_16); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_17); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
+ StorageDead(_18); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2
StorageDead(_9); // scope 4 at $DIR/const_debuginfo.rs:+14:1: +14:2
StorageDead(_4); // scope 3 at $DIR/const_debuginfo.rs:+14:1: +14:2
StorageDead(_3); // scope 2 at $DIR/const_debuginfo.rs:+14:1: +14:2
diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir
index 7650769de..028480bdc 100644
--- a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir
@@ -1,20 +1,20 @@
// MIR for `BAR::promoted[0]` after SimplifyCfg-elaborate-drops
promoted[0] in BAR: &[&i32; 1] = {
- let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
- let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35
- let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
- let mut _3: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
+ let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
+ let mut _1: [&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:35
+ let mut _2: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:34
+ let mut _3: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:33: +0:34
bb0: {
- _3 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
+ _3 = const {alloc1: &i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:33: +0:34
// mir::Constant
- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
+ // + span: $DIR/const_promotion_extern_static.rs:9:33: 9:34
// + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
- _2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
- _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35
- _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
- return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ _2 = &(*_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:34
+ _1 = [move _2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:35
+ _0 = &_1; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
+ return; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
}
}
diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
index f8a7c687e..2ef437811 100644
--- a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
@@ -2,49 +2,49 @@
+ // MIR for `BAR` after PromoteTemps
static mut BAR: *const &i32 = {
- let mut _0: *const &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:17: +0:28
- let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
- let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
- let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35
- let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
- let _5: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
-+ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ let mut _0: *const &i32; // return place in scope 0 at $DIR/const_promotion_extern_static.rs:+0:17: +0:28
+ let mut _1: &[&i32]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
+ let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
+ let _3: [&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:35
+ let mut _4: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:34
+ let _5: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:33: +0:34
++ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
bb0: {
- StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
- StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
-- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35
-- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
-- StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
-- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:33: +0:34
-+ _6 = const _; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
+ StorageLive(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
+ StorageLive(_2); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
+- StorageLive(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:35
+- StorageLive(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:34
+- StorageLive(_5); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:33: +0:34
+- _5 = const {alloc1: &i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:33: +0:34
++ _6 = const _; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
// mir::Constant
-- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
+- // + span: $DIR/const_promotion_extern_static.rs:9:33: 9:34
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
-- _4 = &(*_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:34
-- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:35
-- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
-+ // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:44
+- _4 = &(*_5); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:34
+- _3 = [move _4]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:35
+- _2 = &_3; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
++ // + span: $DIR/const_promotion_extern_static.rs:9:31: 9:44
+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(BAR, [], Some(promoted[0])) }
-+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
- _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
-- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:34: +0:35
- StorageDead(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:34: +0:35
- _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:44
++ _2 = &(*_6); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
+ _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
+- StorageDead(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:34: +0:35
+ StorageDead(_2); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:34: +0:35
+ _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:44
// mir::Constant
- // + span: $DIR/const-promotion-extern-static.rs:9:36: 9:42
+ // + span: $DIR/const_promotion_extern_static.rs:9:36: 9:42
// + literal: Const { ty: for<'a> fn(&'a [&i32]) -> *const &i32 {core::slice::<impl [&i32]>::as_ptr}, val: Value(<ZST>) }
}
bb1: {
-- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44
-- StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44
- StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:43: +0:44
- return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:45
+- StorageDead(_5); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:43: +0:44
+- StorageDead(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:43: +0:44
+ StorageDead(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:43: +0:44
+ return; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:45
}
bb2 (cleanup): {
- resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:45
+ resume; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:45
}
- }
-
diff --git a/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir b/src/test/mir-opt/const_promotion_extern_static.BOP.built.after.mir
index 90920fbe7..476fc49a1 100644
--- a/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir
+++ b/src/test/mir-opt/const_promotion_extern_static.BOP.built.after.mir
@@ -1,17 +1,17 @@
-// MIR for `BOP` 0 mir_map
+// MIR for `BOP` after built
static BOP: &i32 = {
- let mut _0: &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:13: +0:17
- let _1: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23
- let _2: i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23
+ let mut _0: &i32; // return place in scope 0 at $DIR/const_promotion_extern_static.rs:+0:13: +0:17
+ let _1: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:20: +0:23
+ let _2: i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:21: +0:23
bb0: {
- StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23
- StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23
- _2 = const 13_i32; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:21: +0:23
- _1 = &_2; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23
- _0 = &(*_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:20: +0:23
- StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:22: +0:23
- return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:24
+ StorageLive(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:20: +0:23
+ StorageLive(_2); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:21: +0:23
+ _2 = const 13_i32; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:21: +0:23
+ _1 = &_2; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:20: +0:23
+ _0 = &(*_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:20: +0:23
+ StorageDead(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:22: +0:23
+ return; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:24
}
}
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
index 71827eab1..41657b53f 100644
--- a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
@@ -1,20 +1,20 @@
// MIR for `FOO::promoted[0]` after SimplifyCfg-elaborate-drops
promoted[0] in FOO: &[&i32; 1] = {
- let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
- let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46
- let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45
- let mut _3: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
+ let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
+ let mut _1: [&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46
+ let mut _2: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45
+ let mut _3: *const i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43
bb0: {
- _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
+ _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43
// mir::Constant
- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
+ // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43
// + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
- _2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:41: +0:43
- _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46
- _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
- return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ _2 = &(*_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43
+ _1 = [move _2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46
+ _0 = &_1; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
+ return; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
}
}
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
index e938ca28a..25ba0face 100644
--- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
@@ -2,51 +2,51 @@
+ // MIR for `FOO` after PromoteTemps
static mut FOO: *const &i32 = {
- let mut _0: *const &i32; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:+0:17: +0:28
- let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
- let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
- let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46
- let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45
- let _5: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
-+ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ let mut _0: *const &i32; // return place in scope 0 at $DIR/const_promotion_extern_static.rs:+0:17: +0:28
+ let mut _1: &[&i32]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
+ let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
+ let _3: [&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46
+ let mut _4: &i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45
+ let _5: *const i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43
++ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
scope 1 {
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
- StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
-- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46
-- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:32: +0:45
-- StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
-- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:+0:42: +0:43
-+ _6 = const _; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
+ StorageLive(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
+ StorageLive(_2); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
+- StorageLive(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46
+- StorageLive(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45
+- StorageLive(_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43
+- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43
++ _6 = const _; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
// mir::Constant
-- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
+- // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43
- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
-- _4 = &(*_5); // scope 1 at $DIR/const-promotion-extern-static.rs:+0:41: +0:43
-- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:46
-- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
-+ // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:55
+- _4 = &(*_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43
+- _3 = [move _4]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46
+- _2 = &_3; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
++ // + span: $DIR/const_promotion_extern_static.rs:13:31: 13:55
+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(FOO, [], Some(promoted[0])) }
-+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
- _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
-- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:45: +0:46
- StorageDead(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:45: +0:46
- _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:31: +0:55
++ _2 = &(*_6); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
+ _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
+- StorageDead(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:45: +0:46
+ StorageDead(_2); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:45: +0:46
+ _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55
// mir::Constant
- // + span: $DIR/const-promotion-extern-static.rs:13:47: 13:53
+ // + span: $DIR/const_promotion_extern_static.rs:13:47: 13:53
// + literal: Const { ty: for<'a> fn(&'a [&i32]) -> *const &i32 {core::slice::<impl [&i32]>::as_ptr}, val: Value(<ZST>) }
}
bb1: {
-- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55
-- StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55
- StorageDead(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:+0:54: +0:55
- return; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:56
+- StorageDead(_5); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:54: +0:55
+- StorageDead(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:54: +0:55
+ StorageDead(_1); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:54: +0:55
+ return; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:56
}
bb2 (cleanup): {
- resume; // scope 0 at $DIR/const-promotion-extern-static.rs:+0:1: +0:56
+ resume; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:1: +0:56
}
}
-
diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const_promotion_extern_static.rs
index a0d4e9b2c..e4261cfe5 100644
--- a/src/test/mir-opt/const-promotion-extern-static.rs
+++ b/src/test/mir-opt/const_promotion_extern_static.rs
@@ -12,7 +12,7 @@ static mut BAR: *const &i32 = [&Y].as_ptr();
// EMIT_MIR const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
static mut FOO: *const &i32 = [unsafe { &X }].as_ptr();
-// EMIT_MIR const_promotion_extern_static.BOP.mir_map.0.mir
+// EMIT_MIR const_promotion_extern_static.BOP.built.after.mir
static BOP: &i32 = &13;
fn main() {}
diff --git a/src/test/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir b/src/test/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir
new file mode 100644
index 000000000..cfc9a72e3
--- /dev/null
+++ b/src/test/mir-opt/const_prop/aggregate.main.PreCodegen.after.mir
@@ -0,0 +1,28 @@
+// MIR for `main` after PreCodegen
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/aggregate.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/aggregate.rs:+1:9: +1:10
+ let mut _2: i32; // in scope 0 at $DIR/aggregate.rs:+1:13: +1:24
+ let mut _3: (i32, i32, i32); // in scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/aggregate.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/aggregate.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/aggregate.rs:+1:13: +1:24
+ StorageLive(_3); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ Deinit(_3); // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ (_3.0: i32) = const 0_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ (_3.1: i32) = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ (_3.2: i32) = const 2_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:22
+ _2 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:24
+ _1 = const 1_i32; // scope 0 at $DIR/aggregate.rs:+1:13: +1:28
+ StorageDead(_2); // scope 0 at $DIR/aggregate.rs:+1:27: +1:28
+ StorageDead(_3); // scope 0 at $DIR/aggregate.rs:+1:28: +1:29
+ _0 = const (); // scope 0 at $DIR/aggregate.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/aggregate.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/aggregate.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/aggregate.rs b/src/test/mir-opt/const_prop/aggregate.rs
index 493d0508a..6a3080384 100644
--- a/src/test/mir-opt/const_prop/aggregate.rs
+++ b/src/test/mir-opt/const_prop/aggregate.rs
@@ -2,6 +2,7 @@
// compile-flags: -O
// EMIT_MIR aggregate.main.ConstProp.diff
+// EMIT_MIR aggregate.main.PreCodegen.after.mir
fn main() {
let x = (0, 1, 2).1 + 0;
}
diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
index a07bdd998..8b3b9d0a4 100644
--- a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff
@@ -2,15 +2,15 @@
+ // MIR for `hello` after ConstProp
fn hello() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:+0:14: +0:14
- let mut _1: bool; // in scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+ let mut _0: (); // return place in scope 0 at $DIR/control_flow_simplification.rs:+0:14: +0:14
+ let mut _1: bool; // in scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21
let mut _2: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
bb0: {
- StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
- _1 = const _; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
-- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
-+ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control-flow-simplification.rs:+1:8: +1:21
+ StorageLive(_1); // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21
+ _1 = const _; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21
+- switchInt(move _1) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21
++ switchInt(const false) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/control_flow_simplification.rs:+1:8: +1:21
}
bb1: {
@@ -25,9 +25,9 @@
}
bb2: {
- nop; // scope 0 at $DIR/control-flow-simplification.rs:+3:6: +3:6
- StorageDead(_1); // scope 0 at $DIR/control-flow-simplification.rs:+3:5: +3:6
- return; // scope 0 at $DIR/control-flow-simplification.rs:+4:2: +4:2
+ nop; // scope 0 at $DIR/control_flow_simplification.rs:+3:6: +3:6
+ StorageDead(_1); // scope 0 at $DIR/control_flow_simplification.rs:+3:5: +3:6
+ return; // scope 0 at $DIR/control_flow_simplification.rs:+4:2: +4:2
}
}
diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir
index 70f979775..9f7528f0c 100644
--- a/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir
+++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.PreCodegen.before.mir
@@ -1,9 +1,9 @@
// MIR for `hello` before PreCodegen
fn hello() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:+0:14: +0:14
+ let mut _0: (); // return place in scope 0 at $DIR/control_flow_simplification.rs:+0:14: +0:14
bb0: {
- return; // scope 0 at $DIR/control-flow-simplification.rs:+4:2: +4:2
+ return; // scope 0 at $DIR/control_flow_simplification.rs:+4:2: +4:2
}
}
diff --git a/src/test/mir-opt/const_prop/control-flow-simplification.rs b/src/test/mir-opt/const_prop/control_flow_simplification.rs
index 7dbe8e734..7dbe8e734 100644
--- a/src/test/mir-opt/const_prop/control-flow-simplification.rs
+++ b/src/test/mir-opt/const_prop/control_flow_simplification.rs
diff --git a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff
index 9d541dcab..7d8e647cb 100644
--- a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff
@@ -2,32 +2,32 @@
+ // MIR for `main` after ConstProp
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-66971.rs:+0:11: +0:11
- let _1: (); // in scope 0 at $DIR/issue-66971.rs:+1:5: +1:23
- let mut _2: ((), u8, u8); // in scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
- let mut _3: (); // in scope 0 at $DIR/issue-66971.rs:+1:13: +1:15
+ let mut _0: (); // return place in scope 0 at $DIR/issue_66971.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/issue_66971.rs:+1:5: +1:23
+ let mut _2: ((), u8, u8); // in scope 0 at $DIR/issue_66971.rs:+1:12: +1:22
+ let mut _3: (); // in scope 0 at $DIR/issue_66971.rs:+1:13: +1:15
bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23
- StorageLive(_2); // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
- StorageLive(_3); // scope 0 at $DIR/issue-66971.rs:+1:13: +1:15
- nop; // scope 0 at $DIR/issue-66971.rs:+1:13: +1:15
- Deinit(_2); // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
- nop; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
- (_2.1: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
- (_2.2: u8) = const 0_u8; // scope 0 at $DIR/issue-66971.rs:+1:12: +1:22
- StorageDead(_3); // scope 0 at $DIR/issue-66971.rs:+1:21: +1:22
- _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue-66971.rs:+1:5: +1:23
+ StorageLive(_1); // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23
+ StorageLive(_2); // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22
+ StorageLive(_3); // scope 0 at $DIR/issue_66971.rs:+1:13: +1:15
+ nop; // scope 0 at $DIR/issue_66971.rs:+1:13: +1:15
+ Deinit(_2); // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22
+ nop; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22
+ (_2.1: u8) = const 0_u8; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22
+ (_2.2: u8) = const 0_u8; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22
+ StorageDead(_3); // scope 0 at $DIR/issue_66971.rs:+1:21: +1:22
+ _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23
// mir::Constant
- // + span: $DIR/issue-66971.rs:17:5: 17:11
+ // + span: $DIR/issue_66971.rs:17:5: 17:11
// + literal: Const { ty: fn(((), u8, u8)) {encode}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_2); // scope 0 at $DIR/issue-66971.rs:+1:22: +1:23
- StorageDead(_1); // scope 0 at $DIR/issue-66971.rs:+1:23: +1:24
- nop; // scope 0 at $DIR/issue-66971.rs:+0:11: +2:2
- return; // scope 0 at $DIR/issue-66971.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/issue_66971.rs:+1:22: +1:23
+ StorageDead(_1); // scope 0 at $DIR/issue_66971.rs:+1:23: +1:24
+ nop; // scope 0 at $DIR/issue_66971.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/issue_66971.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/const_prop/issue-66971.rs b/src/test/mir-opt/const_prop/issue_66971.rs
index 6ca03438e..6ca03438e 100644
--- a/src/test/mir-opt/const_prop/issue-66971.rs
+++ b/src/test/mir-opt/const_prop/issue_66971.rs
diff --git a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
index b79d81476..79cd8bf48 100644
--- a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff
@@ -2,33 +2,33 @@
+ // MIR for `main` after ConstProp
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-67019.rs:+0:11: +0:11
- let _1: (); // in scope 0 at $DIR/issue-67019.rs:+1:5: +1:20
- let mut _2: ((u8, u8),); // in scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
- let mut _3: (u8, u8); // in scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
+ let mut _0: (); // return place in scope 0 at $DIR/issue_67019.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/issue_67019.rs:+1:5: +1:20
+ let mut _2: ((u8, u8),); // in scope 0 at $DIR/issue_67019.rs:+1:10: +1:19
+ let mut _3: (u8, u8); // in scope 0 at $DIR/issue_67019.rs:+1:11: +1:17
bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20
- StorageLive(_2); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
- StorageLive(_3); // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
- Deinit(_3); // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
- (_3.0: u8) = const 1_u8; // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
- (_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue-67019.rs:+1:11: +1:17
- Deinit(_2); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
-- (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
-+ (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue-67019.rs:+1:10: +1:19
- StorageDead(_3); // scope 0 at $DIR/issue-67019.rs:+1:18: +1:19
- _1 = test(move _2) -> bb1; // scope 0 at $DIR/issue-67019.rs:+1:5: +1:20
+ StorageLive(_1); // scope 0 at $DIR/issue_67019.rs:+1:5: +1:20
+ StorageLive(_2); // scope 0 at $DIR/issue_67019.rs:+1:10: +1:19
+ StorageLive(_3); // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17
+ Deinit(_3); // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17
+ (_3.0: u8) = const 1_u8; // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17
+ (_3.1: u8) = const 2_u8; // scope 0 at $DIR/issue_67019.rs:+1:11: +1:17
+ Deinit(_2); // scope 0 at $DIR/issue_67019.rs:+1:10: +1:19
+- (_2.0: (u8, u8)) = move _3; // scope 0 at $DIR/issue_67019.rs:+1:10: +1:19
++ (_2.0: (u8, u8)) = const (1_u8, 2_u8); // scope 0 at $DIR/issue_67019.rs:+1:10: +1:19
+ StorageDead(_3); // scope 0 at $DIR/issue_67019.rs:+1:18: +1:19
+ _1 = test(move _2) -> bb1; // scope 0 at $DIR/issue_67019.rs:+1:5: +1:20
// mir::Constant
- // + span: $DIR/issue-67019.rs:12:5: 12:9
+ // + span: $DIR/issue_67019.rs:12:5: 12:9
// + literal: Const { ty: fn(((u8, u8),)) {test}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_2); // scope 0 at $DIR/issue-67019.rs:+1:19: +1:20
- StorageDead(_1); // scope 0 at $DIR/issue-67019.rs:+1:20: +1:21
- nop; // scope 0 at $DIR/issue-67019.rs:+0:11: +2:2
- return; // scope 0 at $DIR/issue-67019.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/issue_67019.rs:+1:19: +1:20
+ StorageDead(_1); // scope 0 at $DIR/issue_67019.rs:+1:20: +1:21
+ nop; // scope 0 at $DIR/issue_67019.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/issue_67019.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/const_prop/issue-67019.rs b/src/test/mir-opt/const_prop/issue_67019.rs
index ffc6fa1f2..ffc6fa1f2 100644
--- a/src/test/mir-opt/const_prop/issue-67019.rs
+++ b/src/test/mir-opt/const_prop/issue_67019.rs
diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
index 186a95373..2e4b0e79e 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff
@@ -8,8 +8,10 @@
scope 1 {
debug a => _1; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10
let mut _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ let mut _6: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ let mut _7: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
scope 2 {
- debug x => _2; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ debug x => (i32, i32){ .0 => _6, .1 => _7, }; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
let _4: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
scope 3 {
debug y => _4; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
@@ -30,23 +32,26 @@
}
bb1: {
- StorageLive(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
- Deinit(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
- (_2.0: i32) = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
- (_2.1: i32) = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ StorageLive(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ StorageLive(_7); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
+ Deinit(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ Deinit(_7); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ _6 = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
+ _7 = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
_3 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
- (_2.1: i32) = move _3; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12
+ _7 = move _3; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12
StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
StorageLive(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
- _4 = (_2.1: i32); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16
+ _4 = _7; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16
StorageLive(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
-- _5 = (_2.0: i32); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
+- _5 = _6; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
+ _5 = const 1_i32; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
nop; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +6:2
StorageDead(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
StorageDead(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
- StorageDead(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
+ StorageDead(_7); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
StorageDead(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
return; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:2: +6:2
}
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
index 94aadfaf8..7e8ebd31a 100644
--- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff
@@ -10,6 +10,8 @@
let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
scope 1 {
debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
@@ -51,13 +53,16 @@
StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
- StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
- Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
- (_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
- (_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
-- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
+ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ Deinit(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ Deinit(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
+ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
+ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
+ StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2
StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
index 94aadfaf8..7e8ebd31a 100644
--- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff
@@ -10,6 +10,8 @@
let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
scope 1 {
debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
@@ -51,13 +53,16 @@
StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
- StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
- Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
- (_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
- (_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
-- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
+ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ Deinit(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ Deinit(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
+ _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
+ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
+ StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2
StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir
new file mode 100644
index 000000000..9db87cfc8
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir
@@ -0,0 +1,27 @@
+// MIR for `main` after PreCodegen
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir
new file mode 100644
index 000000000..9db87cfc8
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir
@@ -0,0 +1,27 @@
+// MIR for `main` after PreCodegen
+
+fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+}
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff
new file mode 100644
index 000000000..3f9f3b2ea
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff
@@ -0,0 +1,72 @@
+- // MIR for `main` before ScalarReplacementOfAggregates
++ // MIR for `main` after ScalarReplacementOfAggregates
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ }
+
+ bb1: {
+ _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _6 = Len(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ }
+
+ bb2: {
+ _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+- StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- (_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- (_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
+- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
++ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ Deinit(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ Deinit(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
++ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
++ StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
+ nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2
+ StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff
new file mode 100644
index 000000000..3f9f3b2ea
--- /dev/null
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff
@@ -0,0 +1,72 @@
+- // MIR for `main` before ScalarReplacementOfAggregates
++ // MIR for `main` after ScalarReplacementOfAggregates
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let mut _2: (i32, bool); // in scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ let mut _4: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ scope 3 {
+ debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
+ _2 = CheckedAdd(const 2_i32, const 2_i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ assert(!move (_2.1: bool), "attempt to compute `{} + {}`, which would overflow", const 2_i32, const 2_i32) -> bb1; // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ }
+
+ bb1: {
+ _1 = move (_2.0: i32); // scope 0 at $DIR/optimizes_into_variable.rs:+1:13: +1:18
+ StorageLive(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
+ StorageLive(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:31
+ StorageLive(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _5 = const 3_usize; // scope 1 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
+ _6 = Len(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ _7 = Lt(_5, _6); // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb2; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ }
+
+ bb2: {
+ _3 = _4[_5]; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
+ StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
+ StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
+- StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- (_9.0: u32) = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- (_9.1: u32) = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
+- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
+- StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
++ StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ Deinit(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ Deinit(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
++ StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
++ StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
+ nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2
+ StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.rs b/src/test/mir-opt/const_prop/optimizes_into_variable.rs
index c0fbd2558..025666548 100644
--- a/src/test/mir-opt/const_prop/optimizes_into_variable.rs
+++ b/src/test/mir-opt/const_prop/optimizes_into_variable.rs
@@ -7,8 +7,10 @@ struct Point {
}
// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR optimizes_into_variable.main.ScalarReplacementOfAggregates.diff
// EMIT_MIR optimizes_into_variable.main.ConstProp.diff
// EMIT_MIR optimizes_into_variable.main.SimplifyLocals.after.mir
+// EMIT_MIR optimizes_into_variable.main.PreCodegen.after.mir
fn main() {
let x = 2 + 2;
let y = [0, 1, 2, 3, 4, 5][3];
diff --git a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
index c00eae96e..03df5c950 100644
--- a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
+++ b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
@@ -2,5 +2,5 @@ digraph Cov_0_4 {
graph [fontname="Courier, monospace"];
node [fontname="Courier, monospace"];
edge [fontname="Courier, monospace"];
- bcb0__Cov_0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 18:1-20:2<br/> 19:5-19:9: @0[0]: Coverage::Counter(1) for $DIR/coverage_graphviz.rs:18:1 - 20:2<br/> 20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>];
+ bcb0__Cov_0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 18:1-20:2<br align="left"/> 19:5-19:9: @0[0]: Coverage::Counter(1) for $DIR/coverage_graphviz.rs:18:1 - 20:2<br align="left"/> 20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>];
}
diff --git a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
index ca0eb7e84..fd21b14af 100644
--- a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
+++ b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
@@ -2,10 +2,10 @@ digraph Cov_0_3 {
graph [fontname="Courier, monospace"];
node [fontname="Courier, monospace"];
edge [fontname="Courier, monospace"];
- bcb3__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb3</td></tr><tr><td align="left" balign="left">Counter(bcb3) at 13:10-13:10<br/> 13:10-13:10: @5[0]: Coverage::Counter(2) for $DIR/coverage_graphviz.rs:13:10 - 13:11</td></tr><tr><td align="left" balign="left">bb5: Goto</td></tr></table>>];
- bcb2__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb2</td></tr><tr><td align="left" balign="left">Expression(bcb1:(bcb0 + bcb3) - bcb3) at 12:13-12:18<br/> 12:13-12:18: @4[0]: Coverage::Expression(4294967293) = 4294967294 + 0 for $DIR/coverage_graphviz.rs:15:1 - 15:2<br/>Expression(bcb2:(bcb1:(bcb0 + bcb3) - bcb3) + 0) at 15:2-15:2<br/> 15:2-15:2: @4.Return: return</td></tr><tr><td align="left" balign="left">bb4: Return</td></tr></table>>];
- bcb1__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb1</td></tr><tr><td align="left" balign="left">Expression(bcb0 + bcb3) at 10:5-11:17<br/> 11:12-11:17: @2.Call: _2 = bar() -&gt; [return: bb3, unwind: bb6]</td></tr><tr><td align="left" balign="left">bb1: FalseUnwind<br/>bb2: Call</td></tr><tr><td align="left" balign="left">bb3: SwitchInt</td></tr></table>>];
- bcb0__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 9:1-9:11<br/> </td></tr><tr><td align="left" balign="left">bb0: Goto</td></tr></table>>];
+ bcb3__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb3</td></tr><tr><td align="left" balign="left">Counter(bcb3) at 13:10-13:10<br align="left"/> 13:10-13:10: @5[0]: Coverage::Counter(2) for $DIR/coverage_graphviz.rs:13:10 - 13:11</td></tr><tr><td align="left" balign="left">bb5: Goto</td></tr></table>>];
+ bcb2__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb2</td></tr><tr><td align="left" balign="left">Expression(bcb1:(bcb0 + bcb3) - bcb3) at 12:13-12:18<br align="left"/> 12:13-12:18: @4[0]: Coverage::Expression(4294967293) = 4294967294 + 0 for $DIR/coverage_graphviz.rs:15:1 - 15:2<br align="left"/>Expression(bcb2:(bcb1:(bcb0 + bcb3) - bcb3) + 0) at 15:2-15:2<br align="left"/> 15:2-15:2: @4.Return: return</td></tr><tr><td align="left" balign="left">bb4: Return</td></tr></table>>];
+ bcb1__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb1</td></tr><tr><td align="left" balign="left">Expression(bcb0 + bcb3) at 10:5-11:17<br align="left"/> 11:12-11:17: @2.Call: _2 = bar() -&gt; [return: bb3, unwind: bb6]</td></tr><tr><td align="left" balign="left">bb1: FalseUnwind<br align="left"/>bb2: Call</td></tr><tr><td align="left" balign="left">bb3: SwitchInt</td></tr></table>>];
+ bcb0__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 9:1-9:11<br align="left"/> </td></tr><tr><td align="left" balign="left">bb0: Goto</td></tr></table>>];
bcb3__Cov_0_3 -> bcb1__Cov_0_3 [label=<>];
bcb1__Cov_0_3 -> bcb3__Cov_0_3 [label=<false>];
bcb1__Cov_0_3 -> bcb2__Cov_0_3 [label=<otherwise>];
diff --git a/src/test/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff
new file mode 100644
index 000000000..bf9ab8669
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/cast.main.DataflowConstProp.diff
@@ -0,0 +1,37 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/cast.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/cast.rs:+1:9: +1:10
+ let mut _3: u8; // in scope 0 at $DIR/cast.rs:+2:13: +2:20
+ let mut _4: i32; // in scope 0 at $DIR/cast.rs:+2:13: +2:14
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/cast.rs:+1:9: +1:10
+ let _2: u8; // in scope 1 at $DIR/cast.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/cast.rs:+2:9: +2:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/cast.rs:+1:9: +1:10
+ _1 = const 257_i32; // scope 0 at $DIR/cast.rs:+1:13: +1:16
+ StorageLive(_2); // scope 1 at $DIR/cast.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/cast.rs:+2:13: +2:20
+ StorageLive(_4); // scope 1 at $DIR/cast.rs:+2:13: +2:14
+- _4 = _1; // scope 1 at $DIR/cast.rs:+2:13: +2:14
+- _3 = move _4 as u8 (IntToInt); // scope 1 at $DIR/cast.rs:+2:13: +2:20
++ _4 = const 257_i32; // scope 1 at $DIR/cast.rs:+2:13: +2:14
++ _3 = const 1_u8; // scope 1 at $DIR/cast.rs:+2:13: +2:20
+ StorageDead(_4); // scope 1 at $DIR/cast.rs:+2:19: +2:20
+- _2 = Add(move _3, const 1_u8); // scope 1 at $DIR/cast.rs:+2:13: +2:24
++ _2 = const 2_u8; // scope 1 at $DIR/cast.rs:+2:13: +2:24
+ StorageDead(_3); // scope 1 at $DIR/cast.rs:+2:23: +2:24
+ _0 = const (); // scope 0 at $DIR/cast.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/cast.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/cast.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/cast.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/cast.rs b/src/test/mir-opt/dataflow-const-prop/cast.rs
new file mode 100644
index 000000000..484403f7f
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/cast.rs
@@ -0,0 +1,7 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR cast.main.DataflowConstProp.diff
+fn main() {
+ let a = 257;
+ let b = a as u8 + 1;
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff
new file mode 100644
index 000000000..a4ebd0c8c
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff
@@ -0,0 +1,80 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/checked.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/checked.rs:+1:9: +1:10
+ let mut _4: i32; // in scope 0 at $DIR/checked.rs:+3:13: +3:14
+ let mut _5: i32; // in scope 0 at $DIR/checked.rs:+3:17: +3:18
+ let mut _6: (i32, bool); // in scope 0 at $DIR/checked.rs:+3:13: +3:18
+ let mut _9: i32; // in scope 0 at $DIR/checked.rs:+6:13: +6:14
+ let mut _10: (i32, bool); // in scope 0 at $DIR/checked.rs:+6:13: +6:18
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/checked.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/checked.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/checked.rs:+2:9: +2:10
+ let _3: i32; // in scope 2 at $DIR/checked.rs:+3:9: +3:10
+ scope 3 {
+ debug c => _3; // in scope 3 at $DIR/checked.rs:+3:9: +3:10
+ let _7: i32; // in scope 3 at $DIR/checked.rs:+5:9: +5:10
+ scope 4 {
+ debug d => _7; // in scope 4 at $DIR/checked.rs:+5:9: +5:10
+ let _8: i32; // in scope 4 at $DIR/checked.rs:+6:9: +6:10
+ scope 5 {
+ debug e => _8; // in scope 5 at $DIR/checked.rs:+6:9: +6:10
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/checked.rs:+1:9: +1:10
+ _1 = const 1_i32; // scope 0 at $DIR/checked.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/checked.rs:+2:9: +2:10
+ _2 = const 2_i32; // scope 1 at $DIR/checked.rs:+2:13: +2:14
+ StorageLive(_3); // scope 2 at $DIR/checked.rs:+3:9: +3:10
+ StorageLive(_4); // scope 2 at $DIR/checked.rs:+3:13: +3:14
+- _4 = _1; // scope 2 at $DIR/checked.rs:+3:13: +3:14
++ _4 = const 1_i32; // scope 2 at $DIR/checked.rs:+3:13: +3:14
+ StorageLive(_5); // scope 2 at $DIR/checked.rs:+3:17: +3:18
+- _5 = _2; // scope 2 at $DIR/checked.rs:+3:17: +3:18
+- _6 = CheckedAdd(_4, _5); // scope 2 at $DIR/checked.rs:+3:13: +3:18
+- assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, move _5) -> bb1; // scope 2 at $DIR/checked.rs:+3:13: +3:18
++ _5 = const 2_i32; // scope 2 at $DIR/checked.rs:+3:17: +3:18
++ _6 = CheckedAdd(const 1_i32, const 2_i32); // scope 2 at $DIR/checked.rs:+3:13: +3:18
++ assert(!const false, "attempt to compute `{} + {}`, which would overflow", const 1_i32, const 2_i32) -> bb1; // scope 2 at $DIR/checked.rs:+3:13: +3:18
+ }
+
+ bb1: {
+- _3 = move (_6.0: i32); // scope 2 at $DIR/checked.rs:+3:13: +3:18
++ _3 = const 3_i32; // scope 2 at $DIR/checked.rs:+3:13: +3:18
+ StorageDead(_5); // scope 2 at $DIR/checked.rs:+3:17: +3:18
+ StorageDead(_4); // scope 2 at $DIR/checked.rs:+3:17: +3:18
+ StorageLive(_7); // scope 3 at $DIR/checked.rs:+5:9: +5:10
+ _7 = const _; // scope 3 at $DIR/checked.rs:+5:13: +5:21
+ StorageLive(_8); // scope 4 at $DIR/checked.rs:+6:9: +6:10
+ StorageLive(_9); // scope 4 at $DIR/checked.rs:+6:13: +6:14
+- _9 = _7; // scope 4 at $DIR/checked.rs:+6:13: +6:14
+- _10 = CheckedAdd(_9, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18
+- assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18
++ _9 = const i32::MAX; // scope 4 at $DIR/checked.rs:+6:13: +6:14
++ _10 = CheckedAdd(const i32::MAX, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18
++ assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18
+ }
+
+ bb2: {
+- _8 = move (_10.0: i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18
++ _8 = const i32::MIN; // scope 4 at $DIR/checked.rs:+6:13: +6:18
+ StorageDead(_9); // scope 4 at $DIR/checked.rs:+6:17: +6:18
+ _0 = const (); // scope 0 at $DIR/checked.rs:+0:11: +7:2
+ StorageDead(_8); // scope 4 at $DIR/checked.rs:+7:1: +7:2
+ StorageDead(_7); // scope 3 at $DIR/checked.rs:+7:1: +7:2
+ StorageDead(_3); // scope 2 at $DIR/checked.rs:+7:1: +7:2
+ StorageDead(_2); // scope 1 at $DIR/checked.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/checked.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/checked.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/checked.rs b/src/test/mir-opt/dataflow-const-prop/checked.rs
new file mode 100644
index 000000000..0738a4ee5
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/checked.rs
@@ -0,0 +1,13 @@
+// unit-test: DataflowConstProp
+// compile-flags: -Coverflow-checks=on
+
+// EMIT_MIR checked.main.DataflowConstProp.diff
+#[allow(arithmetic_overflow)]
+fn main() {
+ let a = 1;
+ let b = 2;
+ let c = a + b;
+
+ let d = i32::MAX;
+ let e = d + 1;
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff
new file mode 100644
index 000000000..2ced794e6
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/enum.main.DataflowConstProp.diff
@@ -0,0 +1,61 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/enum.rs:+0:11: +0:11
+ let _1: E; // in scope 0 at $DIR/enum.rs:+1:9: +1:10
+ let mut _3: isize; // in scope 0 at $DIR/enum.rs:+2:23: +2:31
+ scope 1 {
+ debug e => _1; // in scope 1 at $DIR/enum.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/enum.rs:+2:9: +2:10
+ let _4: i32; // in scope 1 at $DIR/enum.rs:+2:29: +2:30
+ let _5: i32; // in scope 1 at $DIR/enum.rs:+2:44: +2:45
+ scope 2 {
+ debug x => _2; // in scope 2 at $DIR/enum.rs:+2:9: +2:10
+ }
+ scope 3 {
+ debug x => _4; // in scope 3 at $DIR/enum.rs:+2:29: +2:30
+ }
+ scope 4 {
+ debug x => _5; // in scope 4 at $DIR/enum.rs:+2:44: +2:45
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/enum.rs:+1:9: +1:10
+ Deinit(_1); // scope 0 at $DIR/enum.rs:+1:13: +1:21
+ ((_1 as V1).0: i32) = const 0_i32; // scope 0 at $DIR/enum.rs:+1:13: +1:21
+ discriminant(_1) = 0; // scope 0 at $DIR/enum.rs:+1:13: +1:21
+ StorageLive(_2); // scope 1 at $DIR/enum.rs:+2:9: +2:10
+ _3 = discriminant(_1); // scope 1 at $DIR/enum.rs:+2:19: +2:20
+ switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 1 at $DIR/enum.rs:+2:13: +2:20
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 1 at $DIR/enum.rs:+2:44: +2:45
+ _5 = ((_1 as V2).0: i32); // scope 1 at $DIR/enum.rs:+2:44: +2:45
+ _2 = _5; // scope 4 at $DIR/enum.rs:+2:50: +2:51
+ StorageDead(_5); // scope 1 at $DIR/enum.rs:+2:50: +2:51
+ goto -> bb4; // scope 1 at $DIR/enum.rs:+2:50: +2:51
+ }
+
+ bb2: {
+ unreachable; // scope 1 at $DIR/enum.rs:+2:19: +2:20
+ }
+
+ bb3: {
+ StorageLive(_4); // scope 1 at $DIR/enum.rs:+2:29: +2:30
+ _4 = ((_1 as V1).0: i32); // scope 1 at $DIR/enum.rs:+2:29: +2:30
+ _2 = _4; // scope 3 at $DIR/enum.rs:+2:35: +2:36
+ StorageDead(_4); // scope 1 at $DIR/enum.rs:+2:35: +2:36
+ goto -> bb4; // scope 1 at $DIR/enum.rs:+2:35: +2:36
+ }
+
+ bb4: {
+ _0 = const (); // scope 0 at $DIR/enum.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/enum.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/enum.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/enum.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/enum.rs b/src/test/mir-opt/dataflow-const-prop/enum.rs
new file mode 100644
index 000000000..13288577d
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/enum.rs
@@ -0,0 +1,13 @@
+// unit-test: DataflowConstProp
+
+// Not trackable, because variants could be aliased.
+enum E {
+ V1(i32),
+ V2(i32)
+}
+
+// EMIT_MIR enum.main.DataflowConstProp.diff
+fn main() {
+ let e = E::V1(0);
+ let x = match e { E::V1(x) => x, E::V2(x) => x };
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff
new file mode 100644
index 000000000..26808c70f
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/if.main.DataflowConstProp.diff
@@ -0,0 +1,112 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/if.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/if.rs:+1:9: +1:10
+ let mut _3: bool; // in scope 0 at $DIR/if.rs:+2:16: +2:22
+ let mut _4: i32; // in scope 0 at $DIR/if.rs:+2:16: +2:17
+ let mut _6: i32; // in scope 0 at $DIR/if.rs:+3:13: +3:14
+ let mut _8: bool; // in scope 0 at $DIR/if.rs:+5:16: +5:22
+ let mut _9: i32; // in scope 0 at $DIR/if.rs:+5:16: +5:17
+ let mut _10: i32; // in scope 0 at $DIR/if.rs:+5:36: +5:37
+ let mut _12: i32; // in scope 0 at $DIR/if.rs:+6:13: +6:14
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/if.rs:+1:9: +1:10
+ let _2: i32; // in scope 1 at $DIR/if.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/if.rs:+2:9: +2:10
+ let _5: i32; // in scope 2 at $DIR/if.rs:+3:9: +3:10
+ scope 3 {
+ debug c => _5; // in scope 3 at $DIR/if.rs:+3:9: +3:10
+ let _7: i32; // in scope 3 at $DIR/if.rs:+5:9: +5:10
+ scope 4 {
+ debug d => _7; // in scope 4 at $DIR/if.rs:+5:9: +5:10
+ let _11: i32; // in scope 4 at $DIR/if.rs:+6:9: +6:10
+ scope 5 {
+ debug e => _11; // in scope 5 at $DIR/if.rs:+6:9: +6:10
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/if.rs:+1:9: +1:10
+ _1 = const 1_i32; // scope 0 at $DIR/if.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/if.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/if.rs:+2:16: +2:22
+ StorageLive(_4); // scope 1 at $DIR/if.rs:+2:16: +2:17
+- _4 = _1; // scope 1 at $DIR/if.rs:+2:16: +2:17
+- _3 = Eq(move _4, const 1_i32); // scope 1 at $DIR/if.rs:+2:16: +2:22
++ _4 = const 1_i32; // scope 1 at $DIR/if.rs:+2:16: +2:17
++ _3 = const true; // scope 1 at $DIR/if.rs:+2:16: +2:22
+ StorageDead(_4); // scope 1 at $DIR/if.rs:+2:21: +2:22
+- switchInt(move _3) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22
++ switchInt(const true) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if.rs:+2:16: +2:22
+ }
+
+ bb1: {
+ _2 = const 2_i32; // scope 1 at $DIR/if.rs:+2:25: +2:26
+ goto -> bb3; // scope 1 at $DIR/if.rs:+2:13: +2:39
+ }
+
+ bb2: {
+ _2 = const 3_i32; // scope 1 at $DIR/if.rs:+2:36: +2:37
+ goto -> bb3; // scope 1 at $DIR/if.rs:+2:13: +2:39
+ }
+
+ bb3: {
+ StorageDead(_3); // scope 1 at $DIR/if.rs:+2:38: +2:39
+ StorageLive(_5); // scope 2 at $DIR/if.rs:+3:9: +3:10
+ StorageLive(_6); // scope 2 at $DIR/if.rs:+3:13: +3:14
+- _6 = _2; // scope 2 at $DIR/if.rs:+3:13: +3:14
+- _5 = Add(move _6, const 1_i32); // scope 2 at $DIR/if.rs:+3:13: +3:18
++ _6 = const 2_i32; // scope 2 at $DIR/if.rs:+3:13: +3:14
++ _5 = const 3_i32; // scope 2 at $DIR/if.rs:+3:13: +3:18
+ StorageDead(_6); // scope 2 at $DIR/if.rs:+3:17: +3:18
+ StorageLive(_7); // scope 3 at $DIR/if.rs:+5:9: +5:10
+ StorageLive(_8); // scope 3 at $DIR/if.rs:+5:16: +5:22
+ StorageLive(_9); // scope 3 at $DIR/if.rs:+5:16: +5:17
+- _9 = _1; // scope 3 at $DIR/if.rs:+5:16: +5:17
+- _8 = Eq(move _9, const 1_i32); // scope 3 at $DIR/if.rs:+5:16: +5:22
++ _9 = const 1_i32; // scope 3 at $DIR/if.rs:+5:16: +5:17
++ _8 = const true; // scope 3 at $DIR/if.rs:+5:16: +5:22
+ StorageDead(_9); // scope 3 at $DIR/if.rs:+5:21: +5:22
+- switchInt(move _8) -> [false: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22
++ switchInt(const true) -> [false: bb5, otherwise: bb4]; // scope 3 at $DIR/if.rs:+5:16: +5:22
+ }
+
+ bb4: {
+- _7 = _1; // scope 3 at $DIR/if.rs:+5:25: +5:26
++ _7 = const 1_i32; // scope 3 at $DIR/if.rs:+5:25: +5:26
+ goto -> bb6; // scope 3 at $DIR/if.rs:+5:13: +5:43
+ }
+
+ bb5: {
+ StorageLive(_10); // scope 3 at $DIR/if.rs:+5:36: +5:37
+ _10 = _1; // scope 3 at $DIR/if.rs:+5:36: +5:37
+ _7 = Add(move _10, const 1_i32); // scope 3 at $DIR/if.rs:+5:36: +5:41
+ StorageDead(_10); // scope 3 at $DIR/if.rs:+5:40: +5:41
+ goto -> bb6; // scope 3 at $DIR/if.rs:+5:13: +5:43
+ }
+
+ bb6: {
+ StorageDead(_8); // scope 3 at $DIR/if.rs:+5:42: +5:43
+ StorageLive(_11); // scope 4 at $DIR/if.rs:+6:9: +6:10
+ StorageLive(_12); // scope 4 at $DIR/if.rs:+6:13: +6:14
+- _12 = _7; // scope 4 at $DIR/if.rs:+6:13: +6:14
+- _11 = Add(move _12, const 1_i32); // scope 4 at $DIR/if.rs:+6:13: +6:18
++ _12 = const 1_i32; // scope 4 at $DIR/if.rs:+6:13: +6:14
++ _11 = const 2_i32; // scope 4 at $DIR/if.rs:+6:13: +6:18
+ StorageDead(_12); // scope 4 at $DIR/if.rs:+6:17: +6:18
+ _0 = const (); // scope 0 at $DIR/if.rs:+0:11: +7:2
+ StorageDead(_11); // scope 4 at $DIR/if.rs:+7:1: +7:2
+ StorageDead(_7); // scope 3 at $DIR/if.rs:+7:1: +7:2
+ StorageDead(_5); // scope 2 at $DIR/if.rs:+7:1: +7:2
+ StorageDead(_2); // scope 1 at $DIR/if.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/if.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/if.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/if.rs b/src/test/mir-opt/dataflow-const-prop/if.rs
new file mode 100644
index 000000000..34fc35790
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/if.rs
@@ -0,0 +1,11 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR if.main.DataflowConstProp.diff
+fn main() {
+ let a = 1;
+ let b = if a == 1 { 2 } else { 3 };
+ let c = b + 1;
+
+ let d = if a == 1 { a } else { a + 1 };
+ let e = d + 1;
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
new file mode 100644
index 000000000..bf4557ed3
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
@@ -0,0 +1,45 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/inherit_overflow.rs:+0:11: +0:11
+ let mut _1: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ let mut _2: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ let mut _3: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ scope 1 {
+ }
+ scope 2 (inlined <u8 as Add>::add) { // at $DIR/inherit_overflow.rs:7:13: 7:47
+ debug self => _2; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ debug other => _3; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ let mut _4: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ let mut _5: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ let mut _6: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ StorageLive(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ _2 = const u8::MAX; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ StorageLive(_3); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ _3 = const 1_u8; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ StorageLive(_4); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ _4 = const u8::MAX; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ _5 = const 1_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ _6 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ }
+
+ bb1: {
+- _1 = move (_6.0: u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
++ _1 = const 0_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ StorageDead(_5); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ StorageDead(_4); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ StorageDead(_3); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ StorageDead(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+ StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:47: +3:48
+ nop; // scope 0 at $DIR/inherit_overflow.rs:+0:11: +4:2
+ return; // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/inherit_overflow.rs b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.rs
new file mode 100644
index 000000000..2f2d9d010
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.rs
@@ -0,0 +1,8 @@
+// compile-flags: -Zunsound-mir-opts
+
+// EMIT_MIR inherit_overflow.main.DataflowConstProp.diff
+fn main() {
+ // After inlining, this will contain a `CheckedBinaryOp`. The overflow
+ // must be ignored by the constant propagation to avoid triggering a panic.
+ let _ = <u8 as std::ops::Add>::add(255, 1);
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff
new file mode 100644
index 000000000..881d80f7c
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/issue_81605.f.DataflowConstProp.diff
@@ -0,0 +1,35 @@
+- // MIR for `f` before DataflowConstProp
++ // MIR for `f` after DataflowConstProp
+
+ fn f() -> usize {
+ let mut _0: usize; // return place in scope 0 at $DIR/issue_81605.rs:+0:11: +0:16
+ let mut _1: usize; // in scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+ let mut _2: bool; // in scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+ StorageLive(_2); // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+ _2 = const true; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
++ switchInt(const true) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/issue_81605.rs:+1:12: +1:16
+ }
+
+ bb1: {
+ _1 = const 1_usize; // scope 0 at $DIR/issue_81605.rs:+1:19: +1:20
+ goto -> bb3; // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+ }
+
+ bb2: {
+ _1 = const 2_usize; // scope 0 at $DIR/issue_81605.rs:+1:30: +1:31
+ goto -> bb3; // scope 0 at $DIR/issue_81605.rs:+1:9: +1:33
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/issue_81605.rs:+1:32: +1:33
+- _0 = Add(const 1_usize, move _1); // scope 0 at $DIR/issue_81605.rs:+1:5: +1:33
++ _0 = const 2_usize; // scope 0 at $DIR/issue_81605.rs:+1:5: +1:33
+ StorageDead(_1); // scope 0 at $DIR/issue_81605.rs:+1:32: +1:33
+ return; // scope 0 at $DIR/issue_81605.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/issue_81605.rs b/src/test/mir-opt/dataflow-const-prop/issue_81605.rs
new file mode 100644
index 000000000..d75e2a28b
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/issue_81605.rs
@@ -0,0 +1,10 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR issue_81605.f.DataflowConstProp.diff
+fn f() -> usize {
+ 1 + if true { 1 } else { 2 }
+}
+
+fn main() {
+ f();
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff
new file mode 100644
index 000000000..158f187f1
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/ref_without_sb.main.DataflowConstProp.diff
@@ -0,0 +1,55 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/ref_without_sb.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/ref_without_sb.rs:+1:9: +1:14
+ let _2: (); // in scope 0 at $DIR/ref_without_sb.rs:+2:5: +2:15
+ let mut _3: &i32; // in scope 0 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ let _4: &i32; // in scope 0 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ let _5: (); // in scope 0 at $DIR/ref_without_sb.rs:+4:5: +4:20
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/ref_without_sb.rs:+1:9: +1:14
+ let _6: i32; // in scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10
+ scope 2 {
+ debug b => _6; // in scope 2 at $DIR/ref_without_sb.rs:+6:9: +6:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/ref_without_sb.rs:+1:9: +1:14
+ _1 = const 0_i32; // scope 0 at $DIR/ref_without_sb.rs:+1:17: +1:18
+ StorageLive(_2); // scope 1 at $DIR/ref_without_sb.rs:+2:5: +2:15
+ StorageLive(_3); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ StorageLive(_4); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ _4 = &_1; // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ _3 = &(*_4); // scope 1 at $DIR/ref_without_sb.rs:+2:12: +2:14
+ _2 = escape::<i32>(move _3) -> bb1; // scope 1 at $DIR/ref_without_sb.rs:+2:5: +2:15
+ // mir::Constant
+ // + span: $DIR/ref_without_sb.rs:12:5: 12:11
+ // + literal: Const { ty: for<'a> fn(&'a i32) {escape::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 1 at $DIR/ref_without_sb.rs:+2:14: +2:15
+ StorageDead(_4); // scope 1 at $DIR/ref_without_sb.rs:+2:15: +2:16
+ StorageDead(_2); // scope 1 at $DIR/ref_without_sb.rs:+2:15: +2:16
+ _1 = const 1_i32; // scope 1 at $DIR/ref_without_sb.rs:+3:5: +3:10
+ StorageLive(_5); // scope 1 at $DIR/ref_without_sb.rs:+4:5: +4:20
+ _5 = some_function() -> bb2; // scope 1 at $DIR/ref_without_sb.rs:+4:5: +4:20
+ // mir::Constant
+ // + span: $DIR/ref_without_sb.rs:14:5: 14:18
+ // + literal: Const { ty: fn() {some_function}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_5); // scope 1 at $DIR/ref_without_sb.rs:+4:20: +4:21
+ StorageLive(_6); // scope 1 at $DIR/ref_without_sb.rs:+6:9: +6:10
+ _6 = _1; // scope 1 at $DIR/ref_without_sb.rs:+6:13: +6:14
+ _0 = const (); // scope 0 at $DIR/ref_without_sb.rs:+0:11: +7:2
+ StorageDead(_6); // scope 1 at $DIR/ref_without_sb.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/ref_without_sb.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/ref_without_sb.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/ref_without_sb.rs b/src/test/mir-opt/dataflow-const-prop/ref_without_sb.rs
new file mode 100644
index 000000000..2fd480b09
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/ref_without_sb.rs
@@ -0,0 +1,17 @@
+// unit-test: DataflowConstProp
+
+#[inline(never)]
+fn escape<T>(x: &T) {}
+
+#[inline(never)]
+fn some_function() {}
+
+// EMIT_MIR ref_without_sb.main.DataflowConstProp.diff
+fn main() {
+ let mut a = 0;
+ escape(&a);
+ a = 1;
+ some_function();
+ // This should currently not be propagated.
+ let b = a;
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff
new file mode 100644
index 000000000..f66b00a9a
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/repr_transparent.main.DataflowConstProp.diff
@@ -0,0 +1,44 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/repr_transparent.rs:+0:11: +0:11
+ let _1: I32; // in scope 0 at $DIR/repr_transparent.rs:+1:9: +1:10
+ let mut _3: i32; // in scope 0 at $DIR/repr_transparent.rs:+2:17: +2:26
+ let mut _4: i32; // in scope 0 at $DIR/repr_transparent.rs:+2:17: +2:20
+ let mut _5: i32; // in scope 0 at $DIR/repr_transparent.rs:+2:23: +2:26
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/repr_transparent.rs:+1:9: +1:10
+ let _2: I32; // in scope 1 at $DIR/repr_transparent.rs:+2:9: +2:10
+ scope 2 {
+ debug y => _2; // in scope 2 at $DIR/repr_transparent.rs:+2:9: +2:10
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/repr_transparent.rs:+1:9: +1:10
+ Deinit(_1); // scope 0 at $DIR/repr_transparent.rs:+1:13: +1:19
+ (_1.0: i32) = const 0_i32; // scope 0 at $DIR/repr_transparent.rs:+1:13: +1:19
+ StorageLive(_2); // scope 1 at $DIR/repr_transparent.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26
+ StorageLive(_4); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20
+- _4 = (_1.0: i32); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20
++ _4 = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:20
+ StorageLive(_5); // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26
+- _5 = (_1.0: i32); // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26
+- _3 = Add(move _4, move _5); // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26
++ _5 = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:23: +2:26
++ _3 = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:17: +2:26
+ StorageDead(_5); // scope 1 at $DIR/repr_transparent.rs:+2:25: +2:26
+ StorageDead(_4); // scope 1 at $DIR/repr_transparent.rs:+2:25: +2:26
+ Deinit(_2); // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27
+- (_2.0: i32) = move _3; // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27
++ (_2.0: i32) = const 0_i32; // scope 1 at $DIR/repr_transparent.rs:+2:13: +2:27
+ StorageDead(_3); // scope 1 at $DIR/repr_transparent.rs:+2:26: +2:27
+ _0 = const (); // scope 0 at $DIR/repr_transparent.rs:+0:11: +3:2
+ StorageDead(_2); // scope 1 at $DIR/repr_transparent.rs:+3:1: +3:2
+ StorageDead(_1); // scope 0 at $DIR/repr_transparent.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/repr_transparent.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/repr_transparent.rs b/src/test/mir-opt/dataflow-const-prop/repr_transparent.rs
new file mode 100644
index 000000000..4ce0ca4df
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/repr_transparent.rs
@@ -0,0 +1,12 @@
+// unit-test: DataflowConstProp
+
+// The struct has scalar ABI, but is not a scalar type.
+// Make sure that we handle this correctly.
+#[repr(transparent)]
+struct I32(i32);
+
+// EMIT_MIR repr_transparent.main.DataflowConstProp.diff
+fn main() {
+ let x = I32(0);
+ let y = I32(x.0 + x.0);
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff
new file mode 100644
index 000000000..df08eff94
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/self_assign.main.DataflowConstProp.diff
@@ -0,0 +1,46 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/self_assign.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/self_assign.rs:+1:9: +1:14
+ let mut _2: i32; // in scope 0 at $DIR/self_assign.rs:+2:9: +2:10
+ let mut _3: i32; // in scope 0 at $DIR/self_assign.rs:+3:9: +3:10
+ let mut _5: &i32; // in scope 0 at $DIR/self_assign.rs:+6:9: +6:10
+ let mut _6: i32; // in scope 0 at $DIR/self_assign.rs:+7:9: +7:11
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/self_assign.rs:+1:9: +1:14
+ let mut _4: &i32; // in scope 1 at $DIR/self_assign.rs:+5:9: +5:14
+ scope 2 {
+ debug b => _4; // in scope 2 at $DIR/self_assign.rs:+5:9: +5:14
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/self_assign.rs:+1:9: +1:14
+ _1 = const 0_i32; // scope 0 at $DIR/self_assign.rs:+1:17: +1:18
+ StorageLive(_2); // scope 1 at $DIR/self_assign.rs:+2:9: +2:10
+ _2 = _1; // scope 1 at $DIR/self_assign.rs:+2:9: +2:10
+ _1 = Add(move _2, const 1_i32); // scope 1 at $DIR/self_assign.rs:+2:5: +2:14
+ StorageDead(_2); // scope 1 at $DIR/self_assign.rs:+2:13: +2:14
+ StorageLive(_3); // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
+ _3 = _1; // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
+ _1 = move _3; // scope 1 at $DIR/self_assign.rs:+3:5: +3:10
+ StorageDead(_3); // scope 1 at $DIR/self_assign.rs:+3:9: +3:10
+ StorageLive(_4); // scope 1 at $DIR/self_assign.rs:+5:9: +5:14
+ _4 = &_1; // scope 1 at $DIR/self_assign.rs:+5:17: +5:19
+ StorageLive(_5); // scope 2 at $DIR/self_assign.rs:+6:9: +6:10
+ _5 = _4; // scope 2 at $DIR/self_assign.rs:+6:9: +6:10
+ _4 = move _5; // scope 2 at $DIR/self_assign.rs:+6:5: +6:10
+ StorageDead(_5); // scope 2 at $DIR/self_assign.rs:+6:9: +6:10
+ StorageLive(_6); // scope 2 at $DIR/self_assign.rs:+7:9: +7:11
+ _6 = (*_4); // scope 2 at $DIR/self_assign.rs:+7:9: +7:11
+ _1 = move _6; // scope 2 at $DIR/self_assign.rs:+7:5: +7:11
+ StorageDead(_6); // scope 2 at $DIR/self_assign.rs:+7:10: +7:11
+ _0 = const (); // scope 0 at $DIR/self_assign.rs:+0:11: +8:2
+ StorageDead(_4); // scope 1 at $DIR/self_assign.rs:+8:1: +8:2
+ StorageDead(_1); // scope 0 at $DIR/self_assign.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/self_assign.rs:+8:2: +8:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/self_assign.rs b/src/test/mir-opt/dataflow-const-prop/self_assign.rs
new file mode 100644
index 000000000..8de2195f9
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/self_assign.rs
@@ -0,0 +1,12 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR self_assign.main.DataflowConstProp.diff
+fn main() {
+ let mut a = 0;
+ a = a + 1;
+ a = a;
+
+ let mut b = &a;
+ b = b;
+ a = *b;
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff
new file mode 100644
index 000000000..c09e4061e
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/self_assign_add.main.DataflowConstProp.diff
@@ -0,0 +1,23 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/self_assign_add.rs:+0:11: +0:11
+ let mut _1: i32; // in scope 0 at $DIR/self_assign_add.rs:+1:9: +1:14
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/self_assign_add.rs:+1:9: +1:14
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/self_assign_add.rs:+1:9: +1:14
+ _1 = const 0_i32; // scope 0 at $DIR/self_assign_add.rs:+1:17: +1:18
+- _1 = Add(_1, const 1_i32); // scope 1 at $DIR/self_assign_add.rs:+2:5: +2:11
+- _1 = Add(_1, const 1_i32); // scope 1 at $DIR/self_assign_add.rs:+3:5: +3:11
++ _1 = const 1_i32; // scope 1 at $DIR/self_assign_add.rs:+2:5: +2:11
++ _1 = const 2_i32; // scope 1 at $DIR/self_assign_add.rs:+3:5: +3:11
+ _0 = const (); // scope 0 at $DIR/self_assign_add.rs:+0:11: +4:2
+ StorageDead(_1); // scope 0 at $DIR/self_assign_add.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/self_assign_add.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/self_assign_add.rs b/src/test/mir-opt/dataflow-const-prop/self_assign_add.rs
new file mode 100644
index 000000000..e32827624
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/self_assign_add.rs
@@ -0,0 +1,8 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR self_assign_add.main.DataflowConstProp.diff
+fn main() {
+ let mut a = 0;
+ a += 1;
+ a += 1;
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff
new file mode 100644
index 000000000..8126d4b85
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.diff
@@ -0,0 +1,56 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/sibling_ptr.rs:+0:11: +0:11
+ let mut _1: (u8, u8); // in scope 0 at $DIR/sibling_ptr.rs:+1:9: +1:14
+ let _2: (); // in scope 0 at $DIR/sibling_ptr.rs:+2:5: +5:6
+ let mut _4: *mut u8; // in scope 0 at $DIR/sibling_ptr.rs:+4:10: +4:18
+ let mut _5: *mut u8; // in scope 0 at $DIR/sibling_ptr.rs:+4:10: +4:11
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/sibling_ptr.rs:+1:9: +1:14
+ let _6: u8; // in scope 1 at $DIR/sibling_ptr.rs:+6:9: +6:11
+ scope 2 {
+ let _3: *mut u8; // in scope 2 at $DIR/sibling_ptr.rs:+3:13: +3:14
+ scope 3 {
+ debug p => _3; // in scope 3 at $DIR/sibling_ptr.rs:+3:13: +3:14
+ }
+ }
+ scope 4 {
+ debug x1 => _6; // in scope 4 at $DIR/sibling_ptr.rs:+6:9: +6:11
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/sibling_ptr.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33
+ (_1.0: u8) = const 0_u8; // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33
+ (_1.1: u8) = const 0_u8; // scope 0 at $DIR/sibling_ptr.rs:+1:27: +1:33
+ StorageLive(_2); // scope 1 at $DIR/sibling_ptr.rs:+2:5: +5:6
+ StorageLive(_3); // scope 2 at $DIR/sibling_ptr.rs:+3:13: +3:14
+ _3 = &raw mut (_1.0: u8); // scope 2 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ StorageLive(_4); // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18
+ StorageLive(_5); // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11
+ _5 = _3; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:11
+ _4 = ptr::mut_ptr::<impl *mut u8>::add(move _5, const 1_usize) -> bb1; // scope 3 at $DIR/sibling_ptr.rs:+4:10: +4:18
+ // mir::Constant
+ // + span: $DIR/sibling_ptr.rs:8:12: 8:15
+ // + literal: Const { ty: unsafe fn(*mut u8, usize) -> *mut u8 {ptr::mut_ptr::<impl *mut u8>::add}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_5); // scope 3 at $DIR/sibling_ptr.rs:+4:17: +4:18
+ (*_4) = const 1_u8; // scope 3 at $DIR/sibling_ptr.rs:+4:9: +4:22
+ StorageDead(_4); // scope 3 at $DIR/sibling_ptr.rs:+4:22: +4:23
+ _2 = const (); // scope 2 at $DIR/sibling_ptr.rs:+2:5: +5:6
+ StorageDead(_3); // scope 2 at $DIR/sibling_ptr.rs:+5:5: +5:6
+ StorageDead(_2); // scope 1 at $DIR/sibling_ptr.rs:+5:5: +5:6
+ StorageLive(_6); // scope 1 at $DIR/sibling_ptr.rs:+6:9: +6:11
+ _6 = (_1.1: u8); // scope 1 at $DIR/sibling_ptr.rs:+6:14: +6:17
+ _0 = const (); // scope 0 at $DIR/sibling_ptr.rs:+0:11: +7:2
+ StorageDead(_6); // scope 1 at $DIR/sibling_ptr.rs:+7:1: +7:2
+ StorageDead(_1); // scope 0 at $DIR/sibling_ptr.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/sibling_ptr.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/sibling_ptr.rs b/src/test/mir-opt/dataflow-const-prop/sibling_ptr.rs
new file mode 100644
index 000000000..87ef00d18
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/sibling_ptr.rs
@@ -0,0 +1,11 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR sibling_ptr.main.DataflowConstProp.diff
+fn main() {
+ let mut x: (u8, u8) = (0, 0);
+ unsafe {
+ let p = std::ptr::addr_of_mut!(x.0);
+ *p.add(1) = 1;
+ }
+ let x1 = x.1; // should not be propagated
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff
new file mode 100644
index 000000000..cfb2706c1
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.diff
@@ -0,0 +1,52 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/struct.rs:+0:11: +0:11
+ let mut _1: S; // in scope 0 at $DIR/struct.rs:+1:9: +1:14
+ let mut _3: i32; // in scope 0 at $DIR/struct.rs:+2:13: +2:16
+ let mut _5: i32; // in scope 0 at $DIR/struct.rs:+4:13: +4:14
+ let mut _6: i32; // in scope 0 at $DIR/struct.rs:+4:17: +4:20
+ scope 1 {
+ debug s => _1; // in scope 1 at $DIR/struct.rs:+1:9: +1:14
+ let _2: i32; // in scope 1 at $DIR/struct.rs:+2:9: +2:10
+ scope 2 {
+ debug a => _2; // in scope 2 at $DIR/struct.rs:+2:9: +2:10
+ let _4: i32; // in scope 2 at $DIR/struct.rs:+4:9: +4:10
+ scope 3 {
+ debug b => _4; // in scope 3 at $DIR/struct.rs:+4:9: +4:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/struct.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/struct.rs:+1:17: +1:21
+ (_1.0: i32) = const 1_i32; // scope 0 at $DIR/struct.rs:+1:17: +1:21
+ StorageLive(_2); // scope 1 at $DIR/struct.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/struct.rs:+2:13: +2:16
+- _3 = (_1.0: i32); // scope 1 at $DIR/struct.rs:+2:13: +2:16
+- _2 = Add(move _3, const 2_i32); // scope 1 at $DIR/struct.rs:+2:13: +2:20
++ _3 = const 1_i32; // scope 1 at $DIR/struct.rs:+2:13: +2:16
++ _2 = const 3_i32; // scope 1 at $DIR/struct.rs:+2:13: +2:20
+ StorageDead(_3); // scope 1 at $DIR/struct.rs:+2:19: +2:20
+ (_1.0: i32) = const 3_i32; // scope 2 at $DIR/struct.rs:+3:5: +3:12
+ StorageLive(_4); // scope 2 at $DIR/struct.rs:+4:9: +4:10
+ StorageLive(_5); // scope 2 at $DIR/struct.rs:+4:13: +4:14
+- _5 = _2; // scope 2 at $DIR/struct.rs:+4:13: +4:14
++ _5 = const 3_i32; // scope 2 at $DIR/struct.rs:+4:13: +4:14
+ StorageLive(_6); // scope 2 at $DIR/struct.rs:+4:17: +4:20
+- _6 = (_1.0: i32); // scope 2 at $DIR/struct.rs:+4:17: +4:20
+- _4 = Add(move _5, move _6); // scope 2 at $DIR/struct.rs:+4:13: +4:20
++ _6 = const 3_i32; // scope 2 at $DIR/struct.rs:+4:17: +4:20
++ _4 = const 6_i32; // scope 2 at $DIR/struct.rs:+4:13: +4:20
+ StorageDead(_6); // scope 2 at $DIR/struct.rs:+4:19: +4:20
+ StorageDead(_5); // scope 2 at $DIR/struct.rs:+4:19: +4:20
+ _0 = const (); // scope 0 at $DIR/struct.rs:+0:11: +5:2
+ StorageDead(_4); // scope 2 at $DIR/struct.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/struct.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/struct.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/struct.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/struct.rs b/src/test/mir-opt/dataflow-const-prop/struct.rs
new file mode 100644
index 000000000..841b279e0
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/struct.rs
@@ -0,0 +1,11 @@
+// unit-test: DataflowConstProp
+
+struct S(i32);
+
+// EMIT_MIR struct.main.DataflowConstProp.diff
+fn main() {
+ let mut s = S(1);
+ let a = s.0 + 2;
+ s.0 = 3;
+ let b = a + s.0;
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff
new file mode 100644
index 000000000..8018400e7
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/terminator.main.DataflowConstProp.diff
@@ -0,0 +1,40 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/terminator.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/terminator.rs:+1:9: +1:10
+ let _2: (); // in scope 0 at $DIR/terminator.rs:+3:5: +3:15
+ let mut _3: i32; // in scope 0 at $DIR/terminator.rs:+3:9: +3:14
+ let mut _4: i32; // in scope 0 at $DIR/terminator.rs:+3:9: +3:10
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/terminator.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/terminator.rs:+1:9: +1:10
+ _1 = const 1_i32; // scope 0 at $DIR/terminator.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/terminator.rs:+3:5: +3:15
+ StorageLive(_3); // scope 1 at $DIR/terminator.rs:+3:9: +3:14
+ StorageLive(_4); // scope 1 at $DIR/terminator.rs:+3:9: +3:10
+- _4 = _1; // scope 1 at $DIR/terminator.rs:+3:9: +3:10
+- _3 = Add(move _4, const 1_i32); // scope 1 at $DIR/terminator.rs:+3:9: +3:14
++ _4 = const 1_i32; // scope 1 at $DIR/terminator.rs:+3:9: +3:10
++ _3 = const 2_i32; // scope 1 at $DIR/terminator.rs:+3:9: +3:14
+ StorageDead(_4); // scope 1 at $DIR/terminator.rs:+3:13: +3:14
+- _2 = foo(move _3) -> bb1; // scope 1 at $DIR/terminator.rs:+3:5: +3:15
++ _2 = foo(const 2_i32) -> bb1; // scope 1 at $DIR/terminator.rs:+3:5: +3:15
+ // mir::Constant
+ // + span: $DIR/terminator.rs:9:5: 9:8
+ // + literal: Const { ty: fn(i32) {foo}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ StorageDead(_3); // scope 1 at $DIR/terminator.rs:+3:14: +3:15
+ StorageDead(_2); // scope 1 at $DIR/terminator.rs:+3:15: +3:16
+ _0 = const (); // scope 0 at $DIR/terminator.rs:+0:11: +4:2
+ StorageDead(_1); // scope 0 at $DIR/terminator.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/terminator.rs:+4:2: +4:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/terminator.rs b/src/test/mir-opt/dataflow-const-prop/terminator.rs
new file mode 100644
index 000000000..d151f666a
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/terminator.rs
@@ -0,0 +1,10 @@
+// unit-test: DataflowConstProp
+
+fn foo(n: i32) {}
+
+// EMIT_MIR terminator.main.DataflowConstProp.diff
+fn main() {
+ let a = 1;
+ // Checks that we propagate into terminators.
+ foo(a + 1);
+}
diff --git a/src/test/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff
new file mode 100644
index 000000000..e028def00
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/tuple.main.DataflowConstProp.diff
@@ -0,0 +1,75 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/tuple.rs:+0:11: +0:11
+ let mut _1: (i32, i32); // in scope 0 at $DIR/tuple.rs:+1:9: +1:14
+ let mut _3: i32; // in scope 0 at $DIR/tuple.rs:+2:13: +2:22
+ let mut _4: i32; // in scope 0 at $DIR/tuple.rs:+2:13: +2:16
+ let mut _5: i32; // in scope 0 at $DIR/tuple.rs:+2:19: +2:22
+ let mut _7: i32; // in scope 0 at $DIR/tuple.rs:+4:13: +4:22
+ let mut _8: i32; // in scope 0 at $DIR/tuple.rs:+4:13: +4:16
+ let mut _9: i32; // in scope 0 at $DIR/tuple.rs:+4:19: +4:22
+ let mut _10: i32; // in scope 0 at $DIR/tuple.rs:+4:25: +4:26
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/tuple.rs:+1:9: +1:14
+ let _2: i32; // in scope 1 at $DIR/tuple.rs:+2:9: +2:10
+ scope 2 {
+ debug b => _2; // in scope 2 at $DIR/tuple.rs:+2:9: +2:10
+ let _6: i32; // in scope 2 at $DIR/tuple.rs:+4:9: +4:10
+ scope 3 {
+ debug c => _6; // in scope 3 at $DIR/tuple.rs:+4:9: +4:10
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/tuple.rs:+1:9: +1:14
+ Deinit(_1); // scope 0 at $DIR/tuple.rs:+1:17: +1:23
+ (_1.0: i32) = const 1_i32; // scope 0 at $DIR/tuple.rs:+1:17: +1:23
+ (_1.1: i32) = const 2_i32; // scope 0 at $DIR/tuple.rs:+1:17: +1:23
+ StorageLive(_2); // scope 1 at $DIR/tuple.rs:+2:9: +2:10
+ StorageLive(_3); // scope 1 at $DIR/tuple.rs:+2:13: +2:22
+ StorageLive(_4); // scope 1 at $DIR/tuple.rs:+2:13: +2:16
+- _4 = (_1.0: i32); // scope 1 at $DIR/tuple.rs:+2:13: +2:16
++ _4 = const 1_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:16
+ StorageLive(_5); // scope 1 at $DIR/tuple.rs:+2:19: +2:22
+- _5 = (_1.1: i32); // scope 1 at $DIR/tuple.rs:+2:19: +2:22
+- _3 = Add(move _4, move _5); // scope 1 at $DIR/tuple.rs:+2:13: +2:22
++ _5 = const 2_i32; // scope 1 at $DIR/tuple.rs:+2:19: +2:22
++ _3 = const 3_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:22
+ StorageDead(_5); // scope 1 at $DIR/tuple.rs:+2:21: +2:22
+ StorageDead(_4); // scope 1 at $DIR/tuple.rs:+2:21: +2:22
+- _2 = Add(move _3, const 3_i32); // scope 1 at $DIR/tuple.rs:+2:13: +2:26
++ _2 = const 6_i32; // scope 1 at $DIR/tuple.rs:+2:13: +2:26
+ StorageDead(_3); // scope 1 at $DIR/tuple.rs:+2:25: +2:26
+ Deinit(_1); // scope 2 at $DIR/tuple.rs:+3:5: +3:15
+ (_1.0: i32) = const 2_i32; // scope 2 at $DIR/tuple.rs:+3:5: +3:15
+ (_1.1: i32) = const 3_i32; // scope 2 at $DIR/tuple.rs:+3:5: +3:15
+ StorageLive(_6); // scope 2 at $DIR/tuple.rs:+4:9: +4:10
+ StorageLive(_7); // scope 2 at $DIR/tuple.rs:+4:13: +4:22
+ StorageLive(_8); // scope 2 at $DIR/tuple.rs:+4:13: +4:16
+- _8 = (_1.0: i32); // scope 2 at $DIR/tuple.rs:+4:13: +4:16
++ _8 = const 2_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:16
+ StorageLive(_9); // scope 2 at $DIR/tuple.rs:+4:19: +4:22
+- _9 = (_1.1: i32); // scope 2 at $DIR/tuple.rs:+4:19: +4:22
+- _7 = Add(move _8, move _9); // scope 2 at $DIR/tuple.rs:+4:13: +4:22
++ _9 = const 3_i32; // scope 2 at $DIR/tuple.rs:+4:19: +4:22
++ _7 = const 5_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:22
+ StorageDead(_9); // scope 2 at $DIR/tuple.rs:+4:21: +4:22
+ StorageDead(_8); // scope 2 at $DIR/tuple.rs:+4:21: +4:22
+ StorageLive(_10); // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+- _10 = _2; // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+- _6 = Add(move _7, move _10); // scope 2 at $DIR/tuple.rs:+4:13: +4:26
++ _10 = const 6_i32; // scope 2 at $DIR/tuple.rs:+4:25: +4:26
++ _6 = const 11_i32; // scope 2 at $DIR/tuple.rs:+4:13: +4:26
+ StorageDead(_10); // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+ StorageDead(_7); // scope 2 at $DIR/tuple.rs:+4:25: +4:26
+ _0 = const (); // scope 0 at $DIR/tuple.rs:+0:11: +5:2
+ StorageDead(_6); // scope 2 at $DIR/tuple.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/tuple.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/tuple.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/tuple.rs:+5:2: +5:2
+ }
+ }
+
diff --git a/src/test/mir-opt/dataflow-const-prop/tuple.rs b/src/test/mir-opt/dataflow-const-prop/tuple.rs
new file mode 100644
index 000000000..92c70eab0
--- /dev/null
+++ b/src/test/mir-opt/dataflow-const-prop/tuple.rs
@@ -0,0 +1,9 @@
+// unit-test: DataflowConstProp
+
+// EMIT_MIR tuple.main.DataflowConstProp.diff
+fn main() {
+ let mut a = (1, 2);
+ let b = a.0 + a.1 + 3;
+ a = (2, 3);
+ let c = a.0 + a.1 + b;
+}
diff --git a/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff
index 58dd788b6..61d24c3b5 100644
--- a/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff
+++ b/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff
@@ -6,17 +6,20 @@
debug y => _2; // in scope 0 at $DIR/cycle.rs:+0:22: +0:27
debug z => _3; // in scope 0 at $DIR/cycle.rs:+0:34: +0:39
let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:46: +0:46
- let mut _4: (); // in scope 0 at $DIR/cycle.rs:+0:1: +9:2
- let mut _5: bool; // in scope 0 at $DIR/cycle.rs:+3:11: +3:17
- let _6: i32; // in scope 0 at $DIR/cycle.rs:+4:13: +4:17
- let mut _7: i32; // in scope 0 at $DIR/cycle.rs:+5:13: +5:14
- let mut _8: i32; // in scope 0 at $DIR/cycle.rs:+6:13: +6:14
- let mut _9: i32; // in scope 0 at $DIR/cycle.rs:+7:13: +7:17
- let mut _10: !; // in scope 0 at $DIR/cycle.rs:+3:5: +8:6
- let _11: (); // in scope 0 at $DIR/cycle.rs:+3:5: +8:6
- let mut _12: !; // in scope 0 at $DIR/cycle.rs:+3:5: +8:6
+- let mut _4: (); // in scope 0 at $DIR/cycle.rs:+0:1: +9:2
+- let mut _5: bool; // in scope 0 at $DIR/cycle.rs:+3:11: +3:17
+- let _6: i32; // in scope 0 at $DIR/cycle.rs:+4:13: +4:17
+- let mut _7: i32; // in scope 0 at $DIR/cycle.rs:+5:13: +5:14
+- let mut _8: i32; // in scope 0 at $DIR/cycle.rs:+6:13: +6:14
+- let mut _9: i32; // in scope 0 at $DIR/cycle.rs:+7:13: +7:17
+- let mut _10: !; // in scope 0 at $DIR/cycle.rs:+3:5: +8:6
+- let _11: (); // in scope 0 at $DIR/cycle.rs:+3:5: +8:6
+- let mut _12: !; // in scope 0 at $DIR/cycle.rs:+3:5: +8:6
++ let mut _4: bool; // in scope 0 at $DIR/cycle.rs:+3:11: +3:17
++ let _5: i32; // in scope 0 at $DIR/cycle.rs:+4:13: +4:17
scope 1 {
- debug temp => _6; // in scope 1 at $DIR/cycle.rs:+4:13: +4:17
+- debug temp => _6; // in scope 1 at $DIR/cycle.rs:+4:13: +4:17
++ debug temp => _5; // in scope 1 at $DIR/cycle.rs:+4:13: +4:17
}
bb0: {
@@ -24,51 +27,57 @@
}
bb1: {
- StorageLive(_5); // scope 0 at $DIR/cycle.rs:+3:11: +3:17
- _5 = cond() -> bb2; // scope 0 at $DIR/cycle.rs:+3:11: +3:17
+- StorageLive(_5); // scope 0 at $DIR/cycle.rs:+3:11: +3:17
+- _5 = cond() -> bb2; // scope 0 at $DIR/cycle.rs:+3:11: +3:17
++ StorageLive(_4); // scope 0 at $DIR/cycle.rs:+3:11: +3:17
++ _4 = cond() -> bb2; // scope 0 at $DIR/cycle.rs:+3:11: +3:17
// mir::Constant
// + span: $DIR/cycle.rs:12:11: 12:15
// + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
}
bb2: {
- switchInt(move _5) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17
+- switchInt(move _5) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17
++ switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/cycle.rs:+3:11: +3:17
}
bb3: {
- StorageLive(_6); // scope 0 at $DIR/cycle.rs:+4:13: +4:17
+- StorageLive(_6); // scope 0 at $DIR/cycle.rs:+4:13: +4:17
- _6 = _3; // scope 0 at $DIR/cycle.rs:+4:20: +4:21
-+ nop; // scope 0 at $DIR/cycle.rs:+4:20: +4:21
- StorageLive(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14
+- StorageLive(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14
- _7 = _2; // scope 1 at $DIR/cycle.rs:+5:13: +5:14
- _3 = move _7; // scope 1 at $DIR/cycle.rs:+5:9: +5:14
-+ nop; // scope 1 at $DIR/cycle.rs:+5:13: +5:14
-+ nop; // scope 1 at $DIR/cycle.rs:+5:9: +5:14
- StorageDead(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14
- StorageLive(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14
+- StorageDead(_7); // scope 1 at $DIR/cycle.rs:+5:13: +5:14
+- StorageLive(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14
- _8 = _1; // scope 1 at $DIR/cycle.rs:+6:13: +6:14
- _2 = move _8; // scope 1 at $DIR/cycle.rs:+6:9: +6:14
-+ nop; // scope 1 at $DIR/cycle.rs:+6:13: +6:14
-+ nop; // scope 1 at $DIR/cycle.rs:+6:9: +6:14
- StorageDead(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14
- StorageLive(_9); // scope 1 at $DIR/cycle.rs:+7:13: +7:17
+- StorageDead(_8); // scope 1 at $DIR/cycle.rs:+6:13: +6:14
+- StorageLive(_9); // scope 1 at $DIR/cycle.rs:+7:13: +7:17
- _9 = _6; // scope 1 at $DIR/cycle.rs:+7:13: +7:17
- _1 = move _9; // scope 1 at $DIR/cycle.rs:+7:9: +7:17
+- StorageDead(_9); // scope 1 at $DIR/cycle.rs:+7:16: +7:17
+- _4 = const (); // scope 0 at $DIR/cycle.rs:+3:18: +8:6
+- StorageDead(_6); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
++ StorageLive(_5); // scope 0 at $DIR/cycle.rs:+4:13: +4:17
++ nop; // scope 0 at $DIR/cycle.rs:+4:20: +4:21
++ nop; // scope 1 at $DIR/cycle.rs:+5:13: +5:14
++ nop; // scope 1 at $DIR/cycle.rs:+5:9: +5:14
++ nop; // scope 1 at $DIR/cycle.rs:+6:13: +6:14
++ nop; // scope 1 at $DIR/cycle.rs:+6:9: +6:14
+ nop; // scope 1 at $DIR/cycle.rs:+7:13: +7:17
+ nop; // scope 1 at $DIR/cycle.rs:+7:9: +7:17
- StorageDead(_9); // scope 1 at $DIR/cycle.rs:+7:16: +7:17
-- _4 = const (); // scope 0 at $DIR/cycle.rs:+3:18: +8:6
+ nop; // scope 0 at $DIR/cycle.rs:+3:18: +8:6
- StorageDead(_6); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
++ StorageDead(_4); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
goto -> bb1; // scope 0 at $DIR/cycle.rs:+3:5: +8:6
}
bb4: {
- StorageLive(_11); // scope 0 at $DIR/cycle.rs:+3:5: +8:6
+- StorageLive(_11); // scope 0 at $DIR/cycle.rs:+3:5: +8:6
_0 = const (); // scope 0 at $DIR/cycle.rs:+3:5: +8:6
- StorageDead(_11); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
- StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
+- StorageDead(_11); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
+- StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
++ StorageDead(_4); // scope 0 at $DIR/cycle.rs:+8:5: +8:6
return; // scope 0 at $DIR/cycle.rs:+9:2: +9:2
}
}
diff --git a/src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir b/src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir
new file mode 100644
index 000000000..5b185082d
--- /dev/null
+++ b/src/test/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir
@@ -0,0 +1,74 @@
+// MIR for `foo` after PreCodegen
+
+fn foo(_1: Option<String>) -> i32 {
+ debug s => _1; // in scope 0 at $DIR/string.rs:+0:12: +0:13
+ let mut _0: i32; // return place in scope 0 at $DIR/string.rs:+0:34: +0:37
+ let mut _2: &std::string::String; // in scope 0 at $DIR/string.rs:+2:14: +2:17
+ let mut _3: &str; // in scope 0 at $DIR/string.rs:+2:14: +2:17
+ let mut _4: bool; // in scope 0 at $DIR/string.rs:+2:14: +2:17
+ let mut _5: isize; // in scope 0 at $DIR/string.rs:+2:9: +2:18
+ let _6: std::option::Option<std::string::String>; // in scope 0 at $DIR/string.rs:+3:9: +3:10
+ let mut _7: bool; // in scope 0 at $DIR/string.rs:+5:1: +5:2
+ scope 1 {
+ debug s => _6; // in scope 1 at $DIR/string.rs:+3:9: +3:10
+ }
+
+ bb0: {
+ _7 = const false; // scope 0 at $DIR/string.rs:+1:11: +1:12
+ _7 = const true; // scope 0 at $DIR/string.rs:+1:11: +1:12
+ _5 = discriminant(_1); // scope 0 at $DIR/string.rs:+1:11: +1:12
+ switchInt(move _5) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/string.rs:+1:5: +1:12
+ }
+
+ bb1: {
+ StorageLive(_6); // scope 0 at $DIR/string.rs:+3:9: +3:10
+ _7 = const false; // scope 0 at $DIR/string.rs:+3:9: +3:10
+ _6 = move _1; // scope 0 at $DIR/string.rs:+3:9: +3:10
+ _0 = const 4321_i32; // scope 1 at $DIR/string.rs:+3:14: +3:18
+ drop(_6) -> bb6; // scope 0 at $DIR/string.rs:+3:17: +3:18
+ }
+
+ bb2: {
+ _2 = &((_1 as Some).0: std::string::String); // scope 0 at $DIR/string.rs:+2:14: +2:17
+ _3 = <String as Deref>::deref(move _2) -> bb3; // scope 0 at $DIR/string.rs:+2:14: +2:17
+ // mir::Constant
+ // + span: $DIR/string.rs:9:14: 9:17
+ // + literal: Const { ty: for<'a> fn(&'a String) -> &'a <String as Deref>::Target {<String as Deref>::deref}, val: Value(<ZST>) }
+ }
+
+ bb3: {
+ _4 = <str as PartialEq>::eq(_3, const "a") -> bb4; // scope 0 at $DIR/string.rs:+2:14: +2:17
+ // mir::Constant
+ // + span: $DIR/string.rs:9:14: 9:17
+ // + literal: Const { ty: for<'a, 'b> fn(&'a str, &'b str) -> bool {<str as PartialEq>::eq}, val: Value(<ZST>) }
+ // mir::Constant
+ // + span: $DIR/string.rs:9:14: 9:17
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+ }
+
+ bb4: {
+ switchInt(move _4) -> [false: bb1, otherwise: bb5]; // scope 0 at $DIR/string.rs:+2:14: +2:17
+ }
+
+ bb5: {
+ _0 = const 1234_i32; // scope 0 at $DIR/string.rs:+2:22: +2:26
+ goto -> bb9; // scope 0 at $DIR/string.rs:+2:22: +2:26
+ }
+
+ bb6: {
+ StorageDead(_6); // scope 0 at $DIR/string.rs:+3:17: +3:18
+ goto -> bb9; // scope 0 at $DIR/string.rs:+3:17: +3:18
+ }
+
+ bb7: {
+ return; // scope 0 at $DIR/string.rs:+5:2: +5:2
+ }
+
+ bb8: {
+ drop(_1) -> bb7; // scope 0 at $DIR/string.rs:+5:1: +5:2
+ }
+
+ bb9: {
+ switchInt(_7) -> [false: bb7, otherwise: bb8]; // scope 0 at $DIR/string.rs:+5:1: +5:2
+ }
+}
diff --git a/src/test/mir-opt/deref-patterns/string.rs b/src/test/mir-opt/deref-patterns/string.rs
new file mode 100644
index 000000000..3a99c44aa
--- /dev/null
+++ b/src/test/mir-opt/deref-patterns/string.rs
@@ -0,0 +1,12 @@
+// compile-flags: -Z mir-opt-level=0 -C panic=abort
+
+#![feature(string_deref_patterns)]
+#![crate_type = "lib"]
+
+// EMIT_MIR string.foo.PreCodegen.after.mir
+pub fn foo(s: Option<String>) -> i32 {
+ match s {
+ Some("a") => 1234,
+ s => 4321,
+ }
+}
diff --git a/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff
index 8929f2cc7..5fa7013d5 100644
--- a/src/test/mir-opt/dest-prop/branch.main.DestinationPropagation.diff
+++ b/src/test/mir-opt/dest-prop/branch.foo.DestinationPropagation.diff
@@ -1,29 +1,34 @@
-- // MIR for `main` before DestinationPropagation
-+ // MIR for `main` after DestinationPropagation
+- // MIR for `foo` before DestinationPropagation
++ // MIR for `foo` after DestinationPropagation
- fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/branch.rs:+0:11: +0:11
+ fn foo() -> i32 {
+ let mut _0: i32; // return place in scope 0 at $DIR/branch.rs:+0:13: +0:16
let _1: i32; // in scope 0 at $DIR/branch.rs:+1:9: +1:10
let mut _3: bool; // in scope 0 at $DIR/branch.rs:+3:16: +3:22
let _4: i32; // in scope 0 at $DIR/branch.rs:+6:9: +6:14
scope 1 {
- debug x => _1; // in scope 1 at $DIR/branch.rs:+1:9: +1:10
+- debug x => _1; // in scope 1 at $DIR/branch.rs:+1:9: +1:10
++ debug x => _0; // in scope 1 at $DIR/branch.rs:+1:9: +1:10
let _2: i32; // in scope 1 at $DIR/branch.rs:+3:9: +3:10
scope 2 {
- debug y => _2; // in scope 2 at $DIR/branch.rs:+3:9: +3:10
+- debug y => _2; // in scope 2 at $DIR/branch.rs:+3:9: +3:10
++ debug y => _0; // in scope 2 at $DIR/branch.rs:+3:9: +3:10
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/branch.rs:+1:9: +1:10
- _1 = val() -> bb1; // scope 0 at $DIR/branch.rs:+1:13: +1:18
+- StorageLive(_1); // scope 0 at $DIR/branch.rs:+1:9: +1:10
+- _1 = val() -> bb1; // scope 0 at $DIR/branch.rs:+1:13: +1:18
++ nop; // scope 0 at $DIR/branch.rs:+1:9: +1:10
++ _0 = val() -> bb1; // scope 0 at $DIR/branch.rs:+1:13: +1:18
// mir::Constant
// + span: $DIR/branch.rs:13:13: 13:16
// + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
}
bb1: {
- StorageLive(_2); // scope 1 at $DIR/branch.rs:+3:9: +3:10
+- StorageLive(_2); // scope 1 at $DIR/branch.rs:+3:9: +3:10
++ nop; // scope 1 at $DIR/branch.rs:+3:9: +3:10
StorageLive(_3); // scope 1 at $DIR/branch.rs:+3:16: +3:22
_3 = cond() -> bb2; // scope 1 at $DIR/branch.rs:+3:16: +3:22
// mir::Constant
@@ -36,7 +41,8 @@
}
bb3: {
- nop; // scope 1 at $DIR/branch.rs:+4:9: +4:10
+- _2 = _1; // scope 1 at $DIR/branch.rs:+4:9: +4:10
++ nop; // scope 1 at $DIR/branch.rs:+4:9: +4:10
goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6
}
@@ -50,16 +56,20 @@
bb5: {
StorageDead(_4); // scope 1 at $DIR/branch.rs:+6:14: +6:15
- nop; // scope 1 at $DIR/branch.rs:+7:9: +7:10
+- _2 = _1; // scope 1 at $DIR/branch.rs:+7:9: +7:10
++ nop; // scope 1 at $DIR/branch.rs:+7:9: +7:10
goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6
}
bb6: {
StorageDead(_3); // scope 1 at $DIR/branch.rs:+8:5: +8:6
- nop; // scope 0 at $DIR/branch.rs:+0:11: +9:2
- StorageDead(_2); // scope 1 at $DIR/branch.rs:+9:1: +9:2
- StorageDead(_1); // scope 0 at $DIR/branch.rs:+9:1: +9:2
- return; // scope 0 at $DIR/branch.rs:+9:2: +9:2
+- _0 = _2; // scope 2 at $DIR/branch.rs:+10:5: +10:6
+- StorageDead(_2); // scope 1 at $DIR/branch.rs:+11:1: +11:2
+- StorageDead(_1); // scope 0 at $DIR/branch.rs:+11:1: +11:2
++ nop; // scope 2 at $DIR/branch.rs:+10:5: +10:6
++ nop; // scope 1 at $DIR/branch.rs:+11:1: +11:2
++ nop; // scope 0 at $DIR/branch.rs:+11:1: +11:2
+ return; // scope 0 at $DIR/branch.rs:+11:2: +11:2
}
}
diff --git a/src/test/mir-opt/dest-prop/branch.rs b/src/test/mir-opt/dest-prop/branch.rs
index fffcf82b3..898c908b1 100644
--- a/src/test/mir-opt/dest-prop/branch.rs
+++ b/src/test/mir-opt/dest-prop/branch.rs
@@ -1,5 +1,5 @@
//! Tests that assignment in both branches of an `if` are eliminated.
-// compile-flags: -Zunsound-mir-opts
+// unit-test: DestinationPropagation
fn val() -> i32 {
1
}
@@ -8,8 +8,8 @@ fn cond() -> bool {
true
}
-// EMIT_MIR branch.main.DestinationPropagation.diff
-fn main() {
+// EMIT_MIR branch.foo.DestinationPropagation.diff
+fn foo() -> i32 {
let x = val();
let y = if cond() {
@@ -18,4 +18,10 @@ fn main() {
val();
x
};
+
+ y
+}
+
+fn main() {
+ foo();
}
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff
index f28bc72df..4343a5935 100644
--- a/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff
@@ -2,7 +2,7 @@
+ // MIR for `arg_src` after DestinationPropagation
fn arg_src(_1: i32) -> i32 {
- debug x => const 123_i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:12: +0:17
+ debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:12: +0:17
let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30
let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
scope 1 {
@@ -15,7 +15,7 @@
- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
+ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
+ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
- nop; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12
+ _1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12
- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2
+ nop; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff
index a8a7e9ab6..298991b5a 100644
--- a/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff
@@ -2,26 +2,30 @@
+ // MIR for `bar` after DestinationPropagation
fn bar(_1: u8) -> () {
- debug x => const 5_u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
+ debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19
let _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
bb0: {
StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
- StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
- _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
- _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
+- StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+- _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
+- _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
++ _2 = dummy(move _1) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
// mir::Constant
// + span: $DIR/copy_propagation_arg.rs:16:5: 16:10
// + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13
+- StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13
StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
- nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
- nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
+ _1 = const 5_u8; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
+ _0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff
index ce9be4c27..bc88787e6 100644
--- a/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff
@@ -1,18 +1,22 @@
- // MIR for `baz` before DestinationPropagation
+ // MIR for `baz` after DestinationPropagation
- fn baz(_1: i32) -> () {
+ fn baz(_1: i32) -> i32 {
debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
- let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:20: +0:20
+ let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:23: +0:26
let mut _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
bb0: {
- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
- nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
- nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
- nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:20: +3:2
- return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
+- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+- _1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
+- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
+ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
+ return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2
}
}
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff
index d7a0b950f..d37a9f71d 100644
--- a/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff
@@ -8,10 +8,12 @@
let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
bb0: {
- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
_3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
- _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
+- _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
++ _1 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
// mir::Constant
// + span: $DIR/copy_propagation_arg.rs:11:9: 11:14
// + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) }
@@ -19,9 +21,11 @@
bb1: {
StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
- nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17
- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
- nop; // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
+- _1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17
+- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17
++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
+ _0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.rs b/src/test/mir-opt/dest-prop/copy_propagation_arg.rs
index a5fb0f640..31be6c931 100644
--- a/src/test/mir-opt/dest-prop/copy_propagation_arg.rs
+++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.rs
@@ -1,6 +1,6 @@
// Check that DestinationPropagation does not propagate an assignment to a function argument
// (doing so can break usages of the original argument value)
-// compile-flags: -Zunsound-mir-opts
+// unit-test: DestinationPropagation
fn dummy(x: u8) -> u8 {
x
}
@@ -18,9 +18,10 @@ fn bar(mut x: u8) {
}
// EMIT_MIR copy_propagation_arg.baz.DestinationPropagation.diff
-fn baz(mut x: i32) {
+fn baz(mut x: i32) -> i32 {
// self-assignment to a function argument should be eliminated
x = x;
+ x
}
// EMIT_MIR copy_propagation_arg.arg_src.DestinationPropagation.diff
diff --git a/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff
index 8eeb0d354..cfc203c5f 100644
--- a/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff
+++ b/src/test/mir-opt/dest-prop/cycle.main.DestinationPropagation.diff
@@ -8,45 +8,69 @@
let _5: (); // in scope 0 at $DIR/cycle.rs:+6:5: +6:12
let mut _6: i32; // in scope 0 at $DIR/cycle.rs:+6:10: +6:11
scope 1 {
- debug x => _1; // in scope 1 at $DIR/cycle.rs:+1:9: +1:14
+- debug x => _1; // in scope 1 at $DIR/cycle.rs:+1:9: +1:14
++ debug x => _6; // in scope 1 at $DIR/cycle.rs:+1:9: +1:14
let _2: i32; // in scope 1 at $DIR/cycle.rs:+2:9: +2:10
scope 2 {
- debug y => _2; // in scope 2 at $DIR/cycle.rs:+2:9: +2:10
+- debug y => _2; // in scope 2 at $DIR/cycle.rs:+2:9: +2:10
++ debug y => _6; // in scope 2 at $DIR/cycle.rs:+2:9: +2:10
let _3: i32; // in scope 2 at $DIR/cycle.rs:+3:9: +3:10
scope 3 {
- debug z => _3; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10
- scope 4 (inlined std::mem::drop::<i32>) { // at $DIR/cycle.rs:14:5: 14:12
- debug _x => _6; // in scope 4 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
- }
+- debug z => _3; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10
++ debug z => _6; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10
}
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:14
- _1 = val() -> bb1; // scope 0 at $DIR/cycle.rs:+1:17: +1:22
+- StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:14
+- _1 = val() -> bb1; // scope 0 at $DIR/cycle.rs:+1:17: +1:22
++ nop; // scope 0 at $DIR/cycle.rs:+1:9: +1:14
++ _6 = val() -> bb1; // scope 0 at $DIR/cycle.rs:+1:17: +1:22
// mir::Constant
// + span: $DIR/cycle.rs:9:17: 9:20
// + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
}
bb1: {
- StorageLive(_2); // scope 1 at $DIR/cycle.rs:+2:9: +2:10
- nop; // scope 1 at $DIR/cycle.rs:+2:13: +2:14
- StorageLive(_3); // scope 2 at $DIR/cycle.rs:+3:9: +3:10
- nop; // scope 2 at $DIR/cycle.rs:+3:13: +3:14
- StorageLive(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
- nop; // scope 3 at $DIR/cycle.rs:+4:9: +4:10
- nop; // scope 3 at $DIR/cycle.rs:+4:5: +4:10
- StorageDead(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+- StorageLive(_2); // scope 1 at $DIR/cycle.rs:+2:9: +2:10
+- _2 = _1; // scope 1 at $DIR/cycle.rs:+2:13: +2:14
+- StorageLive(_3); // scope 2 at $DIR/cycle.rs:+3:9: +3:10
+- _3 = _2; // scope 2 at $DIR/cycle.rs:+3:13: +3:14
+- StorageLive(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+- _4 = _3; // scope 3 at $DIR/cycle.rs:+4:9: +4:10
+- _1 = move _4; // scope 3 at $DIR/cycle.rs:+4:5: +4:10
+- StorageDead(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
++ nop; // scope 1 at $DIR/cycle.rs:+2:9: +2:10
++ nop; // scope 1 at $DIR/cycle.rs:+2:13: +2:14
++ nop; // scope 2 at $DIR/cycle.rs:+3:9: +3:10
++ nop; // scope 2 at $DIR/cycle.rs:+3:13: +3:14
++ nop; // scope 3 at $DIR/cycle.rs:+4:9: +4:10
++ nop; // scope 3 at $DIR/cycle.rs:+4:9: +4:10
++ nop; // scope 3 at $DIR/cycle.rs:+4:5: +4:10
++ nop; // scope 3 at $DIR/cycle.rs:+4:9: +4:10
StorageLive(_5); // scope 3 at $DIR/cycle.rs:+6:5: +6:12
- StorageLive(_6); // scope 3 at $DIR/cycle.rs:+6:10: +6:11
- nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11
- StorageDead(_6); // scope 3 at $DIR/cycle.rs:+6:11: +6:12
+- StorageLive(_6); // scope 3 at $DIR/cycle.rs:+6:10: +6:11
+- _6 = _1; // scope 3 at $DIR/cycle.rs:+6:10: +6:11
++ nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11
++ nop; // scope 3 at $DIR/cycle.rs:+6:10: +6:11
+ _5 = std::mem::drop::<i32>(move _6) -> bb2; // scope 3 at $DIR/cycle.rs:+6:5: +6:12
+ // mir::Constant
+ // + span: $DIR/cycle.rs:14:5: 14:9
+ // + literal: Const { ty: fn(i32) {std::mem::drop::<i32>}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+- StorageDead(_6); // scope 3 at $DIR/cycle.rs:+6:11: +6:12
++ nop; // scope 3 at $DIR/cycle.rs:+6:11: +6:12
StorageDead(_5); // scope 3 at $DIR/cycle.rs:+6:12: +6:13
- StorageDead(_3); // scope 2 at $DIR/cycle.rs:+7:1: +7:2
- StorageDead(_2); // scope 1 at $DIR/cycle.rs:+7:1: +7:2
- StorageDead(_1); // scope 0 at $DIR/cycle.rs:+7:1: +7:2
+ _0 = const (); // scope 0 at $DIR/cycle.rs:+0:11: +7:2
+- StorageDead(_3); // scope 2 at $DIR/cycle.rs:+7:1: +7:2
+- StorageDead(_2); // scope 1 at $DIR/cycle.rs:+7:1: +7:2
+- StorageDead(_1); // scope 0 at $DIR/cycle.rs:+7:1: +7:2
++ nop; // scope 2 at $DIR/cycle.rs:+7:1: +7:2
++ nop; // scope 1 at $DIR/cycle.rs:+7:1: +7:2
++ nop; // scope 0 at $DIR/cycle.rs:+7:1: +7:2
return; // scope 0 at $DIR/cycle.rs:+7:2: +7:2
}
}
diff --git a/src/test/mir-opt/dest-prop/cycle.rs b/src/test/mir-opt/dest-prop/cycle.rs
index c9187d408..6182878f3 100644
--- a/src/test/mir-opt/dest-prop/cycle.rs
+++ b/src/test/mir-opt/dest-prop/cycle.rs
@@ -1,5 +1,5 @@
//! Tests that cyclic assignments don't hang DestinationPropagation, and result in reasonable code.
-// compile-flags: -Zunsound-mir-opts
+// unit-test: DestinationPropagation
fn val() -> i32 {
1
}
diff --git a/src/test/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir b/src/test/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir
new file mode 100644
index 000000000..63cac133b
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/dead_stores_79191.f.DestinationPropagation.after.mir
@@ -0,0 +1,34 @@
+// MIR for `f` after DestinationPropagation
+
+fn f(_1: usize) -> usize {
+ debug a => _1; // in scope 0 at $DIR/dead_stores_79191.rs:+0:6: +0:11
+ let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_79191.rs:+0:23: +0:28
+ let _2: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10
+ let mut _3: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+3:9: +3:10
+ let mut _4: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+4:8: +4:9
+ scope 1 {
+ debug b => _3; // in scope 1 at $DIR/dead_stores_79191.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ nop; // scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10
+ _3 = _1; // scope 0 at $DIR/dead_stores_79191.rs:+1:13: +1:14
+ _1 = const 5_usize; // scope 1 at $DIR/dead_stores_79191.rs:+2:5: +2:10
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10
+ _1 = move _3; // scope 1 at $DIR/dead_stores_79191.rs:+3:5: +3:10
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+3:9: +3:10
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9
+ _0 = id::<usize>(move _1) -> bb1; // scope 1 at $DIR/dead_stores_79191.rs:+4:5: +4:10
+ // mir::Constant
+ // + span: $DIR/dead_stores_79191.rs:12:5: 12:7
+ // + literal: Const { ty: fn(usize) -> usize {id::<usize>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ nop; // scope 1 at $DIR/dead_stores_79191.rs:+4:9: +4:10
+ nop; // scope 0 at $DIR/dead_stores_79191.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/dead_stores_79191.rs:+5:2: +5:2
+ }
+}
diff --git a/src/test/mir-opt/dest-prop/dead_stores_79191.rs b/src/test/mir-opt/dest-prop/dead_stores_79191.rs
new file mode 100644
index 000000000..43e0bf664
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/dead_stores_79191.rs
@@ -0,0 +1,17 @@
+// unit-test: DestinationPropagation
+
+fn id<T>(x: T) -> T {
+ x
+}
+
+// EMIT_MIR dead_stores_79191.f.DestinationPropagation.after.mir
+fn f(mut a: usize) -> usize {
+ let b = a;
+ a = 5;
+ a = b;
+ id(a)
+}
+
+fn main() {
+ f(0);
+}
diff --git a/src/test/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir b/src/test/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir
new file mode 100644
index 000000000..ba7f76d28
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir
@@ -0,0 +1,34 @@
+// MIR for `f` after DestinationPropagation
+
+fn f(_1: usize) -> usize {
+ debug a => _1; // in scope 0 at $DIR/dead_stores_better.rs:+0:10: +0:15
+ let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_better.rs:+0:27: +0:32
+ let _2: usize; // in scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10
+ let mut _3: usize; // in scope 0 at $DIR/dead_stores_better.rs:+3:9: +3:10
+ let mut _4: usize; // in scope 0 at $DIR/dead_stores_better.rs:+4:8: +4:9
+ scope 1 {
+ debug b => _1; // in scope 1 at $DIR/dead_stores_better.rs:+1:9: +1:10
+ }
+
+ bb0: {
+ nop; // scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10
+ nop; // scope 0 at $DIR/dead_stores_better.rs:+1:13: +1:14
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+2:5: +2:10
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+3:5: +3:10
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9
+ _0 = id::<usize>(move _1) -> bb1; // scope 1 at $DIR/dead_stores_better.rs:+4:5: +4:10
+ // mir::Constant
+ // + span: $DIR/dead_stores_better.rs:16:5: 16:7
+ // + literal: Const { ty: fn(usize) -> usize {id::<usize>}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ nop; // scope 1 at $DIR/dead_stores_better.rs:+4:9: +4:10
+ nop; // scope 0 at $DIR/dead_stores_better.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/dead_stores_better.rs:+5:2: +5:2
+ }
+}
diff --git a/src/test/mir-opt/dest-prop/dead_stores_better.rs b/src/test/mir-opt/dest-prop/dead_stores_better.rs
new file mode 100644
index 000000000..003ad57d8
--- /dev/null
+++ b/src/test/mir-opt/dest-prop/dead_stores_better.rs
@@ -0,0 +1,21 @@
+// This is a copy of the `dead_stores_79191` test, except that we turn on DSE. This demonstrates
+// that that pass enables this one to do more optimizations.
+
+// unit-test: DestinationPropagation
+// compile-flags: -Zmir-enable-passes=+DeadStoreElimination
+
+fn id<T>(x: T) -> T {
+ x
+}
+
+// EMIT_MIR dead_stores_better.f.DestinationPropagation.after.mir
+pub fn f(mut a: usize) -> usize {
+ let b = a;
+ a = 5;
+ a = b;
+ id(a)
+}
+
+fn main() {
+ f(0);
+}
diff --git a/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff
index 80b09ed5f..c2a3a0025 100644
--- a/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff
+++ b/src/test/mir-opt/dest-prop/simple.nrvo.DestinationPropagation.diff
@@ -17,18 +17,22 @@
StorageLive(_2); // scope 0 at $DIR/simple.rs:+1:9: +1:16
_2 = [const 0_u8; 1024]; // scope 0 at $DIR/simple.rs:+1:19: +1:28
StorageLive(_3); // scope 1 at $DIR/simple.rs:+2:5: +2:19
- StorageLive(_4); // scope 1 at $DIR/simple.rs:+2:5: +2:9
- _4 = _1; // scope 1 at $DIR/simple.rs:+2:5: +2:9
+- StorageLive(_4); // scope 1 at $DIR/simple.rs:+2:5: +2:9
+- _4 = _1; // scope 1 at $DIR/simple.rs:+2:5: +2:9
++ nop; // scope 1 at $DIR/simple.rs:+2:5: +2:9
++ nop; // scope 1 at $DIR/simple.rs:+2:5: +2:9
StorageLive(_5); // scope 1 at $DIR/simple.rs:+2:10: +2:18
StorageLive(_6); // scope 1 at $DIR/simple.rs:+2:10: +2:18
_6 = &mut _2; // scope 1 at $DIR/simple.rs:+2:10: +2:18
_5 = &mut (*_6); // scope 1 at $DIR/simple.rs:+2:10: +2:18
- _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/simple.rs:+2:5: +2:19
+- _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/simple.rs:+2:5: +2:19
++ _3 = move _1(move _5) -> bb1; // scope 1 at $DIR/simple.rs:+2:5: +2:19
}
bb1: {
StorageDead(_5); // scope 1 at $DIR/simple.rs:+2:18: +2:19
- StorageDead(_4); // scope 1 at $DIR/simple.rs:+2:18: +2:19
+- StorageDead(_4); // scope 1 at $DIR/simple.rs:+2:18: +2:19
++ nop; // scope 1 at $DIR/simple.rs:+2:18: +2:19
StorageDead(_6); // scope 1 at $DIR/simple.rs:+2:19: +2:20
StorageDead(_3); // scope 1 at $DIR/simple.rs:+2:19: +2:20
_0 = _2; // scope 1 at $DIR/simple.rs:+3:5: +3:8
diff --git a/src/test/mir-opt/dest-prop/simple.rs b/src/test/mir-opt/dest-prop/simple.rs
index 3627d479a..d4c27228f 100644
--- a/src/test/mir-opt/dest-prop/simple.rs
+++ b/src/test/mir-opt/dest-prop/simple.rs
@@ -1,5 +1,5 @@
//! Copy of `nrvo-simple.rs`, to ensure that full dest-prop handles it too.
-// compile-flags: -Zunsound-mir-opts
+// unit-test: DestinationPropagation
// EMIT_MIR simple.nrvo.DestinationPropagation.diff
fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] {
let mut buf = [0; 1024];
diff --git a/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff
index accdb0085..85d994bc8 100644
--- a/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff
+++ b/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff
@@ -5,14 +5,13 @@
let mut _0: (); // return place in scope 0 at $DIR/union.rs:+0:11: +0:11
let _1: main::Un; // in scope 0 at $DIR/union.rs:+5:9: +5:11
let mut _2: u32; // in scope 0 at $DIR/union.rs:+5:23: +5:28
- let _3: (); // in scope 0 at $DIR/union.rs:+7:5: +7:27
- let mut _4: u32; // in scope 0 at $DIR/union.rs:+7:10: +7:26
+ let mut _3: u32; // in scope 0 at $DIR/union.rs:+7:10: +7:26
scope 1 {
debug un => _1; // in scope 1 at $DIR/union.rs:+5:9: +5:11
scope 2 {
}
scope 3 (inlined std::mem::drop::<u32>) { // at $DIR/union.rs:15:5: 15:27
- debug _x => _4; // in scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ debug _x => _3; // in scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
}
}
@@ -29,11 +28,9 @@
nop; // scope 0 at $DIR/union.rs:+5:14: +5:30
nop; // scope 0 at $DIR/union.rs:+5:14: +5:30
StorageDead(_2); // scope 0 at $DIR/union.rs:+5:29: +5:30
- StorageLive(_3); // scope 1 at $DIR/union.rs:+7:5: +7:27
- StorageLive(_4); // scope 1 at $DIR/union.rs:+7:10: +7:26
+ StorageLive(_3); // scope 1 at $DIR/union.rs:+7:10: +7:26
nop; // scope 2 at $DIR/union.rs:+7:19: +7:24
- StorageDead(_4); // scope 1 at $DIR/union.rs:+7:26: +7:27
- StorageDead(_3); // scope 1 at $DIR/union.rs:+7:27: +7:28
+ StorageDead(_3); // scope 1 at $DIR/union.rs:+7:26: +7:27
StorageDead(_1); // scope 0 at $DIR/union.rs:+8:1: +8:2
return; // scope 0 at $DIR/union.rs:+8:2: +8:2
}
diff --git a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
index 96716a39a..08481777e 100644
--- a/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
@@ -1,83 +1,83 @@
// MIR for `match_tuple` after SimplifyCfg-initial
fn match_tuple(_1: (u32, bool, Option<i32>, u32)) -> u32 {
- debug x => _1; // in scope 0 at $DIR/exponential-or.rs:+0:16: +0:17
- let mut _0: u32; // return place in scope 0 at $DIR/exponential-or.rs:+0:53: +0:56
- let mut _2: isize; // in scope 0 at $DIR/exponential-or.rs:+2:37: +2:48
- let mut _3: bool; // in scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
- let mut _4: bool; // in scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
- let mut _5: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
- let mut _6: bool; // in scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
- let _7: u32; // in scope 0 at $DIR/exponential-or.rs:+2:10: +2:11
- let _8: u32; // in scope 0 at $DIR/exponential-or.rs:+2:57: +2:58
- let mut _9: u32; // in scope 0 at $DIR/exponential-or.rs:+2:83: +2:84
- let mut _10: u32; // in scope 0 at $DIR/exponential-or.rs:+2:87: +2:88
+ debug x => _1; // in scope 0 at $DIR/exponential_or.rs:+0:16: +0:17
+ let mut _0: u32; // return place in scope 0 at $DIR/exponential_or.rs:+0:53: +0:56
+ let mut _2: isize; // in scope 0 at $DIR/exponential_or.rs:+2:37: +2:48
+ let mut _3: bool; // in scope 0 at $DIR/exponential_or.rs:+2:70: +2:77
+ let mut _4: bool; // in scope 0 at $DIR/exponential_or.rs:+2:70: +2:77
+ let mut _5: bool; // in scope 0 at $DIR/exponential_or.rs:+2:62: +2:67
+ let mut _6: bool; // in scope 0 at $DIR/exponential_or.rs:+2:62: +2:67
+ let _7: u32; // in scope 0 at $DIR/exponential_or.rs:+2:10: +2:11
+ let _8: u32; // in scope 0 at $DIR/exponential_or.rs:+2:57: +2:58
+ let mut _9: u32; // in scope 0 at $DIR/exponential_or.rs:+2:83: +2:84
+ let mut _10: u32; // in scope 0 at $DIR/exponential_or.rs:+2:87: +2:88
scope 1 {
- debug y => _7; // in scope 1 at $DIR/exponential-or.rs:+2:10: +2:11
- debug z => _8; // in scope 1 at $DIR/exponential-or.rs:+2:57: +2:58
+ debug y => _7; // in scope 1 at $DIR/exponential_or.rs:+2:10: +2:11
+ debug z => _8; // in scope 1 at $DIR/exponential_or.rs:+2:57: +2:58
}
bb0: {
- FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/exponential-or.rs:+1:11: +1:12
- switchInt((_1.0: u32)) -> [1_u32: bb2, 4_u32: bb2, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:15: +2:20
+ FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/exponential_or.rs:+1:11: +1:12
+ switchInt((_1.0: u32)) -> [1_u32: bb2, 4_u32: bb2, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:15: +2:20
}
bb1: {
- _0 = const 0_u32; // scope 0 at $DIR/exponential-or.rs:+3:14: +3:15
- goto -> bb10; // scope 0 at $DIR/exponential-or.rs:+3:14: +3:15
+ _0 = const 0_u32; // scope 0 at $DIR/exponential_or.rs:+3:14: +3:15
+ goto -> bb10; // scope 0 at $DIR/exponential_or.rs:+3:14: +3:15
}
bb2: {
- _2 = discriminant((_1.2: std::option::Option<i32>)); // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55
- switchInt(move _2) -> [0_isize: bb4, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55
+ _2 = discriminant((_1.2: std::option::Option<i32>)); // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55
+ switchInt(move _2) -> [0_isize: bb4, 1_isize: bb3, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55
}
bb3: {
- switchInt((((_1.2: std::option::Option<i32>) as Some).0: i32)) -> [1_i32: bb4, 8_i32: bb4, otherwise: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:37: +2:55
+ switchInt((((_1.2: std::option::Option<i32>) as Some).0: i32)) -> [1_i32: bb4, 8_i32: bb4, otherwise: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:37: +2:55
}
bb4: {
- _5 = Le(const 6_u32, (_1.3: u32)); // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
- switchInt(move _5) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
+ _5 = Le(const 6_u32, (_1.3: u32)); // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67
+ switchInt(move _5) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67
}
bb5: {
- _6 = Le((_1.3: u32), const 9_u32); // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
- switchInt(move _6) -> [false: bb6, otherwise: bb8]; // scope 0 at $DIR/exponential-or.rs:+2:62: +2:67
+ _6 = Le((_1.3: u32), const 9_u32); // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67
+ switchInt(move _6) -> [false: bb6, otherwise: bb8]; // scope 0 at $DIR/exponential_or.rs:+2:62: +2:67
}
bb6: {
- _3 = Le(const 13_u32, (_1.3: u32)); // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
- switchInt(move _3) -> [false: bb1, otherwise: bb7]; // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
+ _3 = Le(const 13_u32, (_1.3: u32)); // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77
+ switchInt(move _3) -> [false: bb1, otherwise: bb7]; // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77
}
bb7: {
- _4 = Le((_1.3: u32), const 16_u32); // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
- switchInt(move _4) -> [false: bb1, otherwise: bb8]; // scope 0 at $DIR/exponential-or.rs:+2:70: +2:77
+ _4 = Le((_1.3: u32), const 16_u32); // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77
+ switchInt(move _4) -> [false: bb1, otherwise: bb8]; // scope 0 at $DIR/exponential_or.rs:+2:70: +2:77
}
bb8: {
- falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/exponential-or.rs:+2:9: +2:79
+ falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/exponential_or.rs:+2:9: +2:79
}
bb9: {
- StorageLive(_7); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:11
- _7 = (_1.0: u32); // scope 0 at $DIR/exponential-or.rs:+2:10: +2:11
- StorageLive(_8); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:58
- _8 = (_1.3: u32); // scope 0 at $DIR/exponential-or.rs:+2:57: +2:58
- StorageLive(_9); // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84
- _9 = _7; // scope 1 at $DIR/exponential-or.rs:+2:83: +2:84
- StorageLive(_10); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88
- _10 = _8; // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88
- _0 = BitXor(move _9, move _10); // scope 1 at $DIR/exponential-or.rs:+2:83: +2:88
- StorageDead(_10); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88
- StorageDead(_9); // scope 1 at $DIR/exponential-or.rs:+2:87: +2:88
- StorageDead(_8); // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88
- StorageDead(_7); // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88
- goto -> bb10; // scope 0 at $DIR/exponential-or.rs:+2:87: +2:88
+ StorageLive(_7); // scope 0 at $DIR/exponential_or.rs:+2:10: +2:11
+ _7 = (_1.0: u32); // scope 0 at $DIR/exponential_or.rs:+2:10: +2:11
+ StorageLive(_8); // scope 0 at $DIR/exponential_or.rs:+2:57: +2:58
+ _8 = (_1.3: u32); // scope 0 at $DIR/exponential_or.rs:+2:57: +2:58
+ StorageLive(_9); // scope 1 at $DIR/exponential_or.rs:+2:83: +2:84
+ _9 = _7; // scope 1 at $DIR/exponential_or.rs:+2:83: +2:84
+ StorageLive(_10); // scope 1 at $DIR/exponential_or.rs:+2:87: +2:88
+ _10 = _8; // scope 1 at $DIR/exponential_or.rs:+2:87: +2:88
+ _0 = BitXor(move _9, move _10); // scope 1 at $DIR/exponential_or.rs:+2:83: +2:88
+ StorageDead(_10); // scope 1 at $DIR/exponential_or.rs:+2:87: +2:88
+ StorageDead(_9); // scope 1 at $DIR/exponential_or.rs:+2:87: +2:88
+ StorageDead(_8); // scope 0 at $DIR/exponential_or.rs:+2:87: +2:88
+ StorageDead(_7); // scope 0 at $DIR/exponential_or.rs:+2:87: +2:88
+ goto -> bb10; // scope 0 at $DIR/exponential_or.rs:+2:87: +2:88
}
bb10: {
- return; // scope 0 at $DIR/exponential-or.rs:+5:2: +5:2
+ return; // scope 0 at $DIR/exponential_or.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/exponential-or.rs b/src/test/mir-opt/exponential_or.rs
index 0b8be8385..0b8be8385 100644
--- a/src/test/mir-opt/exponential-or.rs
+++ b/src/test/mir-opt/exponential_or.rs
diff --git a/src/test/mir-opt/fn-ptr-shim.rs b/src/test/mir-opt/fn_ptr_shim.rs
index 64fbdc9de..64fbdc9de 100644
--- a/src/test/mir-opt/fn-ptr-shim.rs
+++ b/src/test/mir-opt/fn_ptr_shim.rs
diff --git a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
index c718138b6..c3b08bf06 100644
--- a/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
+++ b/src/test/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
@@ -14,71 +14,71 @@
},
} */
-fn main::{closure#0}(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 10:17]) -> () {
- let mut _0: (); // return place in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
- let mut _2: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
- let _3: std::string::String; // in scope 0 at $DIR/generator-drop-cleanup.rs:+1:13: +1:15
- let _4: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+2:9: +2:14
- let mut _5: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+2:9: +2:14
- let mut _6: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:18: +0:18
- let mut _7: (); // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
- let mut _8: u32; // in scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+fn main::{closure#0}(_1: *mut [generator@$DIR/generator_drop_cleanup.rs:10:15: 10:17]) -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ let mut _2: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ let _3: std::string::String; // in scope 0 at $DIR/generator_drop_cleanup.rs:+1:13: +1:15
+ let _4: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+2:9: +2:14
+ let mut _5: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+2:9: +2:14
+ let mut _6: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:18: +0:18
+ let mut _7: (); // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ let mut _8: u32; // in scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
scope 1 {
- debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator-drop-cleanup.rs:+1:13: +1:15
+ debug _s => (((*_1) as variant#3).0: std::string::String); // in scope 1 at $DIR/generator_drop_cleanup.rs:+1:13: +1:15
}
bb0: {
- _8 = discriminant((*_1)); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
- switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ _8 = discriminant((*_1)); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ switchInt(move _8) -> [0_u32: bb7, 3_u32: bb10, otherwise: bb11]; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
}
bb1: {
- StorageDead(_5); // scope 1 at $DIR/generator-drop-cleanup.rs:+2:13: +2:14
- StorageDead(_4); // scope 1 at $DIR/generator-drop-cleanup.rs:+2:14: +2:15
- drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
+ StorageDead(_5); // scope 1 at $DIR/generator_drop_cleanup.rs:+2:13: +2:14
+ StorageDead(_4); // scope 1 at $DIR/generator_drop_cleanup.rs:+2:14: +2:15
+ drop((((*_1) as variant#3).0: std::string::String)) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6
}
bb2: {
- nop; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
- goto -> bb8; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
+ nop; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6
+ goto -> bb8; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6
}
bb3: {
- return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
}
bb4 (cleanup): {
- resume; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ resume; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
}
bb5 (cleanup): {
- nop; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
- goto -> bb4; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
+ nop; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6
+ goto -> bb4; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6
}
bb6: {
- return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
}
bb7: {
- goto -> bb9; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ goto -> bb9; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
}
bb8: {
- goto -> bb3; // scope 0 at $DIR/generator-drop-cleanup.rs:+3:5: +3:6
+ goto -> bb3; // scope 0 at $DIR/generator_drop_cleanup.rs:+3:5: +3:6
}
bb9: {
- goto -> bb6; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ goto -> bb6; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
}
bb10: {
- StorageLive(_4); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
- StorageLive(_5); // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
- goto -> bb1; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ StorageLive(_4); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ StorageLive(_5); // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
+ goto -> bb1; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
}
bb11: {
- return; // scope 0 at $DIR/generator-drop-cleanup.rs:+0:15: +3:6
+ return; // scope 0 at $DIR/generator_drop_cleanup.rs:+0:15: +3:6
}
}
diff --git a/src/test/mir-opt/generator-drop-cleanup.rs b/src/test/mir-opt/generator_drop_cleanup.rs
index 82c1292cb..82c1292cb 100644
--- a/src/test/mir-opt/generator-drop-cleanup.rs
+++ b/src/test/mir-opt/generator_drop_cleanup.rs
diff --git a/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
index 3184343f2..cfbe0aaf2 100644
--- a/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
+++ b/src/test/mir-opt/generator_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir
@@ -1,124 +1,124 @@
// MIR for `main::{closure#0}` before StateTransform
-fn main::{closure#0}(_1: [generator@$DIR/generator-storage-dead-unwind.rs:22:16: 22:18], _2: ()) -> ()
+fn main::{closure#0}(_1: [generator@$DIR/generator_storage_dead_unwind.rs:22:16: 22:18], _2: ()) -> ()
yields ()
{
- let mut _0: (); // return place in scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:19: +0:19
- let _3: Foo; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14
- let _5: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
- let mut _6: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
- let _7: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16
- let mut _8: Foo; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15
- let _9: (); // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16
- let mut _10: Bar; // in scope 0 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15
+ let mut _0: (); // return place in scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:19: +0:19
+ let _3: Foo; // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+1:13: +1:14
+ let _5: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14
+ let mut _6: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14
+ let _7: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+4:9: +4:16
+ let mut _8: Foo; // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+4:14: +4:15
+ let _9: (); // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+5:9: +5:16
+ let mut _10: Bar; // in scope 0 at $DIR/generator_storage_dead_unwind.rs:+5:14: +5:15
scope 1 {
- debug a => _3; // in scope 1 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14
- let _4: Bar; // in scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14
+ debug a => _3; // in scope 1 at $DIR/generator_storage_dead_unwind.rs:+1:13: +1:14
+ let _4: Bar; // in scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:13: +2:14
scope 2 {
- debug b => _4; // in scope 2 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14
+ debug b => _4; // in scope 2 at $DIR/generator_storage_dead_unwind.rs:+2:13: +2:14
}
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:13: +1:14
- _3 = Foo(const 5_i32); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+1:17: +1:23
- StorageLive(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:13: +2:14
- _4 = Bar(const 6_i32); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+2:17: +2:23
- StorageLive(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
- StorageLive(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
- _6 = (); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
- _5 = yield(move _6) -> [resume: bb1, drop: bb6]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:9: +3:14
+ StorageLive(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+1:13: +1:14
+ _3 = Foo(const 5_i32); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+1:17: +1:23
+ StorageLive(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:13: +2:14
+ _4 = Bar(const 6_i32); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+2:17: +2:23
+ StorageLive(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14
+ StorageLive(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14
+ _6 = (); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14
+ _5 = yield(move _6) -> [resume: bb1, drop: bb6]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:9: +3:14
}
bb1: {
- StorageDead(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:13: +3:14
- StorageDead(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:14: +3:15
- StorageLive(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16
- StorageLive(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15
- _8 = move _3; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:14: +4:15
- _7 = take::<Foo>(move _8) -> [return: bb2, unwind: bb10]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:9: +4:16
+ StorageDead(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:13: +3:14
+ StorageDead(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:14: +3:15
+ StorageLive(_7); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:9: +4:16
+ StorageLive(_8); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:14: +4:15
+ _8 = move _3; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:14: +4:15
+ _7 = take::<Foo>(move _8) -> [return: bb2, unwind: bb10]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:9: +4:16
// mir::Constant
- // + span: $DIR/generator-storage-dead-unwind.rs:26:9: 26:13
+ // + span: $DIR/generator_storage_dead_unwind.rs:26:9: 26:13
// + literal: Const { ty: fn(Foo) {take::<Foo>}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16
- StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:16: +4:17
- StorageLive(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16
- StorageLive(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15
- _10 = move _4; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:14: +5:15
- _9 = take::<Bar>(move _10) -> [return: bb3, unwind: bb9]; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:9: +5:16
+ StorageDead(_8); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:15: +4:16
+ StorageDead(_7); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:16: +4:17
+ StorageLive(_9); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:9: +5:16
+ StorageLive(_10); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:14: +5:15
+ _10 = move _4; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:14: +5:15
+ _9 = take::<Bar>(move _10) -> [return: bb3, unwind: bb9]; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:9: +5:16
// mir::Constant
- // + span: $DIR/generator-storage-dead-unwind.rs:27:9: 27:13
+ // + span: $DIR/generator_storage_dead_unwind.rs:27:9: 27:13
// + literal: Const { ty: fn(Bar) {take::<Bar>}, val: Value(<ZST>) }
}
bb3: {
- StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:15: +5:16
- StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:16: +5:17
- _0 = const (); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:19: +6:6
- StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- goto -> bb4; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ StorageDead(_10); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:15: +5:16
+ StorageDead(_9); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:16: +5:17
+ _0 = const (); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:19: +6:6
+ StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ goto -> bb4; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
}
bb4: {
- StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- drop(_1) -> [return: bb5, unwind: bb14]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ drop(_1) -> [return: bb5, unwind: bb14]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
}
bb5: {
- return; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:6: +6:6
+ return; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:6: +6:6
}
bb6: {
- StorageDead(_6); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:13: +3:14
- StorageDead(_5); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+3:14: +3:15
- StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- drop(_3) -> [return: bb7, unwind: bb15]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ StorageDead(_6); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:13: +3:14
+ StorageDead(_5); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+3:14: +3:15
+ StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ drop(_3) -> [return: bb7, unwind: bb15]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
}
bb7: {
- StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- drop(_1) -> [return: bb8, unwind: bb14]; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ drop(_1) -> [return: bb8, unwind: bb14]; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
}
bb8: {
- generator_drop; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +6:6
+ generator_drop; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:16: +6:6
}
bb9 (cleanup): {
- StorageDead(_10); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:15: +5:16
- StorageDead(_9); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+5:16: +5:17
+ StorageDead(_10); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:15: +5:16
+ StorageDead(_9); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+5:16: +5:17
goto -> bb12; // scope 2 at no-location
}
bb10 (cleanup): {
- goto -> bb11; // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16
+ goto -> bb11; // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:15: +4:16
}
bb11 (cleanup): {
- StorageDead(_8); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:15: +4:16
- StorageDead(_7); // scope 2 at $DIR/generator-storage-dead-unwind.rs:+4:16: +4:17
+ StorageDead(_8); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:15: +4:16
+ StorageDead(_7); // scope 2 at $DIR/generator_storage_dead_unwind.rs:+4:16: +4:17
goto -> bb12; // scope 2 at no-location
}
bb12 (cleanup): {
- StorageDead(_4); // scope 1 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- goto -> bb13; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ StorageDead(_4); // scope 1 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ goto -> bb13; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
}
bb13 (cleanup): {
- StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- drop(_1) -> bb14; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ drop(_1) -> bb14; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
}
bb14 (cleanup): {
- resume; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+0:16: +6:6
+ resume; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+0:16: +6:6
}
bb15 (cleanup): {
- StorageDead(_3); // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
- drop(_1) -> bb14; // scope 0 at $DIR/generator-storage-dead-unwind.rs:+6:5: +6:6
+ StorageDead(_3); // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
+ drop(_1) -> bb14; // scope 0 at $DIR/generator_storage_dead_unwind.rs:+6:5: +6:6
}
}
diff --git a/src/test/mir-opt/generator-storage-dead-unwind.rs b/src/test/mir-opt/generator_storage_dead_unwind.rs
index b72170ade..b72170ade 100644
--- a/src/test/mir-opt/generator-storage-dead-unwind.rs
+++ b/src/test/mir-opt/generator_storage_dead_unwind.rs
diff --git a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
index 07aeeaae0..fee6da2c6 100644
--- a/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
+++ b/src/test/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
@@ -14,71 +14,71 @@
},
} */
-fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]>, _2: u8) -> GeneratorState<(), ()> {
- debug _x => _10; // in scope 0 at $DIR/generator-tiny.rs:+0:17: +0:19
- let mut _0: std::ops::GeneratorState<(), ()>; // return place in scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
- let _3: HasDrop; // in scope 0 at $DIR/generator-tiny.rs:+1:13: +1:15
- let mut _4: !; // in scope 0 at $DIR/generator-tiny.rs:+2:9: +5:10
- let mut _5: (); // in scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
- let _6: u8; // in scope 0 at $DIR/generator-tiny.rs:+3:13: +3:18
- let mut _7: (); // in scope 0 at $DIR/generator-tiny.rs:+3:13: +3:18
- let _8: (); // in scope 0 at $DIR/generator-tiny.rs:+4:13: +4:21
- let mut _9: (); // in scope 0 at $DIR/generator-tiny.rs:+0:25: +0:25
- let _10: u8; // in scope 0 at $DIR/generator-tiny.rs:+0:17: +0:19
- let mut _11: u32; // in scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
+fn main::{closure#0}(_1: Pin<&mut [generator@$DIR/generator_tiny.rs:19:16: 19:24]>, _2: u8) -> GeneratorState<(), ()> {
+ debug _x => _10; // in scope 0 at $DIR/generator_tiny.rs:+0:17: +0:19
+ let mut _0: std::ops::GeneratorState<(), ()>; // return place in scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ let _3: HasDrop; // in scope 0 at $DIR/generator_tiny.rs:+1:13: +1:15
+ let mut _4: !; // in scope 0 at $DIR/generator_tiny.rs:+2:9: +5:10
+ let mut _5: (); // in scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ let _6: u8; // in scope 0 at $DIR/generator_tiny.rs:+3:13: +3:18
+ let mut _7: (); // in scope 0 at $DIR/generator_tiny.rs:+3:13: +3:18
+ let _8: (); // in scope 0 at $DIR/generator_tiny.rs:+4:13: +4:21
+ let mut _9: (); // in scope 0 at $DIR/generator_tiny.rs:+0:25: +0:25
+ let _10: u8; // in scope 0 at $DIR/generator_tiny.rs:+0:17: +0:19
+ let mut _11: u32; // in scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
scope 1 {
- debug _d => (((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop); // in scope 1 at $DIR/generator-tiny.rs:+1:13: +1:15
+ debug _d => (((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop); // in scope 1 at $DIR/generator_tiny.rs:+1:13: +1:15
}
bb0: {
- _11 = discriminant((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]))); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
- switchInt(move _11) -> [0_u32: bb1, 3_u32: bb5, otherwise: bb6]; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
+ _11 = discriminant((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24]))); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ switchInt(move _11) -> [0_u32: bb1, 3_u32: bb5, otherwise: bb6]; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
}
bb1: {
- _10 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
- nop; // scope 0 at $DIR/generator-tiny.rs:+1:13: +1:15
- (((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop) = HasDrop; // scope 0 at $DIR/generator-tiny.rs:+1:18: +1:25
- StorageLive(_4); // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10
- goto -> bb2; // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10
+ _10 = move _2; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ nop; // scope 0 at $DIR/generator_tiny.rs:+1:13: +1:15
+ (((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24])) as variant#3).0: HasDrop) = HasDrop; // scope 0 at $DIR/generator_tiny.rs:+1:18: +1:25
+ StorageLive(_4); // scope 1 at $DIR/generator_tiny.rs:+2:9: +5:10
+ goto -> bb2; // scope 1 at $DIR/generator_tiny.rs:+2:9: +5:10
}
bb2: {
- StorageLive(_6); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
- StorageLive(_7); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
- _7 = (); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
- Deinit(_0); // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
- ((_0 as Yielded).0: ()) = move _7; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
- discriminant(_0) = 0; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
- discriminant((*(_1.0: &mut [generator@$DIR/generator-tiny.rs:19:16: 19:24]))) = 3; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
- return; // scope 1 at $DIR/generator-tiny.rs:+3:13: +3:18
+ StorageLive(_6); // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18
+ StorageLive(_7); // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18
+ _7 = (); // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18
+ Deinit(_0); // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18
+ ((_0 as Yielded).0: ()) = move _7; // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18
+ discriminant(_0) = 0; // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18
+ discriminant((*(_1.0: &mut [generator@$DIR/generator_tiny.rs:19:16: 19:24]))) = 3; // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18
+ return; // scope 1 at $DIR/generator_tiny.rs:+3:13: +3:18
}
bb3: {
- StorageDead(_7); // scope 1 at $DIR/generator-tiny.rs:+3:17: +3:18
- StorageDead(_6); // scope 1 at $DIR/generator-tiny.rs:+3:18: +3:19
- StorageLive(_8); // scope 1 at $DIR/generator-tiny.rs:+4:13: +4:21
- _8 = callee() -> bb4; // scope 1 at $DIR/generator-tiny.rs:+4:13: +4:21
+ StorageDead(_7); // scope 1 at $DIR/generator_tiny.rs:+3:17: +3:18
+ StorageDead(_6); // scope 1 at $DIR/generator_tiny.rs:+3:18: +3:19
+ StorageLive(_8); // scope 1 at $DIR/generator_tiny.rs:+4:13: +4:21
+ _8 = callee() -> bb4; // scope 1 at $DIR/generator_tiny.rs:+4:13: +4:21
// mir::Constant
- // + span: $DIR/generator-tiny.rs:23:13: 23:19
+ // + span: $DIR/generator_tiny.rs:23:13: 23:19
// + literal: Const { ty: fn() {callee}, val: Value(<ZST>) }
}
bb4: {
- StorageDead(_8); // scope 1 at $DIR/generator-tiny.rs:+4:21: +4:22
- _5 = const (); // scope 1 at $DIR/generator-tiny.rs:+2:14: +5:10
- goto -> bb2; // scope 1 at $DIR/generator-tiny.rs:+2:9: +5:10
+ StorageDead(_8); // scope 1 at $DIR/generator_tiny.rs:+4:21: +4:22
+ _5 = const (); // scope 1 at $DIR/generator_tiny.rs:+2:14: +5:10
+ goto -> bb2; // scope 1 at $DIR/generator_tiny.rs:+2:9: +5:10
}
bb5: {
- StorageLive(_4); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
- StorageLive(_6); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
- StorageLive(_7); // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
- _6 = move _2; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
- goto -> bb3; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
+ StorageLive(_4); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ StorageLive(_6); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ StorageLive(_7); // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ _6 = move _2; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
+ goto -> bb3; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
}
bb6: {
- unreachable; // scope 0 at $DIR/generator-tiny.rs:+0:16: +6:6
+ unreachable; // scope 0 at $DIR/generator_tiny.rs:+0:16: +6:6
}
}
diff --git a/src/test/mir-opt/generator-tiny.rs b/src/test/mir-opt/generator_tiny.rs
index 7dad63a61..7dad63a61 100644
--- a/src/test/mir-opt/generator-tiny.rs
+++ b/src/test/mir-opt/generator_tiny.rs
diff --git a/src/test/mir-opt/graphviz.main.mir_map.0.dot b/src/test/mir-opt/graphviz.main.built.after.dot
index 8d1da7f1b..8d1da7f1b 100644
--- a/src/test/mir-opt/graphviz.main.mir_map.0.dot
+++ b/src/test/mir-opt/graphviz.main.built.after.dot
diff --git a/src/test/mir-opt/graphviz.rs b/src/test/mir-opt/graphviz.rs
index 074dba2c3..6906b86c2 100644
--- a/src/test/mir-opt/graphviz.rs
+++ b/src/test/mir-opt/graphviz.rs
@@ -1,5 +1,5 @@
// Test graphviz output
// compile-flags: -Z dump-mir-graphviz
-// EMIT_MIR graphviz.main.mir_map.0.dot
+// EMIT_MIR graphviz.main.built.after.dot
fn main() {}
diff --git a/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff
index 19b5ab441..94180d203 100644
--- a/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff
+++ b/src/test/mir-opt/if_condition_int.dont_opt_bool.SimplifyComparisonIntegral.diff
@@ -2,29 +2,29 @@
+ // MIR for `dont_opt_bool` after SimplifyComparisonIntegral
fn dont_opt_bool(_1: bool) -> u32 {
- debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:18: +0:19
- let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:30: +0:33
- let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:18: +0:19
+ let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:30: +0:33
+ let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
bb0: {
- StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
- _2 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+ _2 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
}
bb1: {
- _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:12: +1:13
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:26
+ _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+1:12: +1:13
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:26
}
bb2: {
- _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:23: +1:24
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:26
+ _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+1:23: +1:24
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:26
}
bb3: {
- StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:25: +1:26
- return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:25: +1:26
+ return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
index 256af7b94..b22c7eac6 100644
--- a/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
+++ b/src/test/mir-opt/if_condition_int.dont_opt_floats.SimplifyComparisonIntegral.diff
@@ -2,33 +2,33 @@
+ // MIR for `dont_opt_floats` after SimplifyComparisonIntegral
fn dont_opt_floats(_1: f32) -> i32 {
- debug a => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:20: +0:21
- let mut _0: i32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:31: +0:34
- let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18
- let mut _3: f32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ debug a => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:20: +0:21
+ let mut _0: i32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:31: +0:34
+ let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18
+ let mut _3: f32; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
bb0: {
- StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18
- StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
- _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
- _2 = Eq(move _3, const -42f32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18
- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:17: +1:18
- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:18
+ StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18
+ StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+ _2 = Eq(move _3, const -42f32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18
+ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:17: +1:18
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:18
}
bb1: {
- _0 = const 0_i32; // scope 0 at $DIR/if-condition-int.rs:+1:21: +1:22
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:35
+ _0 = const 0_i32; // scope 0 at $DIR/if_condition_int.rs:+1:21: +1:22
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:35
}
bb2: {
- _0 = const 1_i32; // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:35
+ _0 = const 1_i32; // scope 0 at $DIR/if_condition_int.rs:+1:32: +1:33
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:35
}
bb3: {
- StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:34: +1:35
- return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:34: +1:35
+ return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
index ed53c9a95..cc0995f99 100644
--- a/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
+++ b/src/test/mir-opt/if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
@@ -2,57 +2,57 @@
+ // MIR for `dont_remove_comparison` after SimplifyComparisonIntegral
fn dont_remove_comparison(_1: i8) -> i32 {
- debug a => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:27: +0:28
- let mut _0: i32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:37: +0:40
- let _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:9: +1:10
- let mut _3: i8; // in scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14
- let mut _4: i32; // in scope 0 at $DIR/if-condition-int.rs:+3:23: +3:31
- let mut _5: bool; // in scope 0 at $DIR/if-condition-int.rs:+3:23: +3:24
- let mut _6: i32; // in scope 0 at $DIR/if-condition-int.rs:+4:23: +4:31
- let mut _7: bool; // in scope 0 at $DIR/if-condition-int.rs:+4:23: +4:24
+ debug a => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:27: +0:28
+ let mut _0: i32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:37: +0:40
+ let _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:9: +1:10
+ let mut _3: i8; // in scope 0 at $DIR/if_condition_int.rs:+1:13: +1:14
+ let mut _4: i32; // in scope 0 at $DIR/if_condition_int.rs:+3:23: +3:31
+ let mut _5: bool; // in scope 0 at $DIR/if_condition_int.rs:+3:23: +3:24
+ let mut _6: i32; // in scope 0 at $DIR/if_condition_int.rs:+4:23: +4:31
+ let mut _7: bool; // in scope 0 at $DIR/if_condition_int.rs:+4:23: +4:24
scope 1 {
- debug b => _2; // in scope 1 at $DIR/if-condition-int.rs:+1:9: +1:10
+ debug b => _2; // in scope 1 at $DIR/if_condition_int.rs:+1:9: +1:10
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:9: +1:10
- StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14
- _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:14
-- _2 = Eq(move _3, const 17_i8); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:20
-- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20
-- switchInt(_2) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12
-+ _2 = Eq(_3, const 17_i8); // scope 0 at $DIR/if-condition-int.rs:+1:13: +1:20
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20
-+ switchInt(move _3) -> [17_i8: bb1, otherwise: bb2]; // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12
+ StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:14
+ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:14
+- _2 = Eq(move _3, const 17_i8); // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:20
+- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:19: +1:20
+- switchInt(_2) -> [false: bb2, otherwise: bb1]; // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12
++ _2 = Eq(_3, const 17_i8); // scope 0 at $DIR/if_condition_int.rs:+1:13: +1:20
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:19: +1:20
++ switchInt(move _3) -> [17_i8: bb1, otherwise: bb2]; // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12
}
bb1: {
-+ StorageDead(_3); // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12
- StorageLive(_6); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:31
- StorageLive(_7); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:24
- _7 = _2; // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:24
- _6 = move _7 as i32 (IntToInt); // scope 1 at $DIR/if-condition-int.rs:+4:23: +4:31
- StorageDead(_7); // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31
- _0 = Add(const 100_i32, move _6); // scope 1 at $DIR/if-condition-int.rs:+4:17: +4:31
- StorageDead(_6); // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31
- goto -> bb3; // scope 1 at $DIR/if-condition-int.rs:+4:30: +4:31
++ StorageDead(_3); // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12
+ StorageLive(_6); // scope 1 at $DIR/if_condition_int.rs:+4:23: +4:31
+ StorageLive(_7); // scope 1 at $DIR/if_condition_int.rs:+4:23: +4:24
+ _7 = _2; // scope 1 at $DIR/if_condition_int.rs:+4:23: +4:24
+ _6 = move _7 as i32 (IntToInt); // scope 1 at $DIR/if_condition_int.rs:+4:23: +4:31
+ StorageDead(_7); // scope 1 at $DIR/if_condition_int.rs:+4:30: +4:31
+ _0 = Add(const 100_i32, move _6); // scope 1 at $DIR/if_condition_int.rs:+4:17: +4:31
+ StorageDead(_6); // scope 1 at $DIR/if_condition_int.rs:+4:30: +4:31
+ goto -> bb3; // scope 1 at $DIR/if_condition_int.rs:+4:30: +4:31
}
bb2: {
-+ StorageDead(_3); // scope 1 at $DIR/if-condition-int.rs:+2:5: +2:12
- StorageLive(_4); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:31
- StorageLive(_5); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:24
- _5 = _2; // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:24
- _4 = move _5 as i32 (IntToInt); // scope 1 at $DIR/if-condition-int.rs:+3:23: +3:31
- StorageDead(_5); // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31
- _0 = Add(const 10_i32, move _4); // scope 1 at $DIR/if-condition-int.rs:+3:18: +3:31
- StorageDead(_4); // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31
- goto -> bb3; // scope 1 at $DIR/if-condition-int.rs:+3:30: +3:31
++ StorageDead(_3); // scope 1 at $DIR/if_condition_int.rs:+2:5: +2:12
+ StorageLive(_4); // scope 1 at $DIR/if_condition_int.rs:+3:23: +3:31
+ StorageLive(_5); // scope 1 at $DIR/if_condition_int.rs:+3:23: +3:24
+ _5 = _2; // scope 1 at $DIR/if_condition_int.rs:+3:23: +3:24
+ _4 = move _5 as i32 (IntToInt); // scope 1 at $DIR/if_condition_int.rs:+3:23: +3:31
+ StorageDead(_5); // scope 1 at $DIR/if_condition_int.rs:+3:30: +3:31
+ _0 = Add(const 10_i32, move _4); // scope 1 at $DIR/if_condition_int.rs:+3:18: +3:31
+ StorageDead(_4); // scope 1 at $DIR/if_condition_int.rs:+3:30: +3:31
+ goto -> bb3; // scope 1 at $DIR/if_condition_int.rs:+3:30: +3:31
}
bb3: {
- StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+6:1: +6:2
- return; // scope 0 at $DIR/if-condition-int.rs:+6:2: +6:2
+ StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/if_condition_int.rs:+6:2: +6:2
}
}
diff --git a/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
index 9b64c379f..801ea0402 100644
--- a/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
+++ b/src/test/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff
@@ -2,38 +2,38 @@
+ // MIR for `opt_char` after SimplifyComparisonIntegral
fn opt_char(_1: char) -> u32 {
- debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:13: +0:14
- let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:25: +0:28
- let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
- let mut _3: char; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:13: +0:14
+ let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:25: +0:28
+ let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
+ let mut _3: char; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
bb0: {
- StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
- StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
- _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
-- _2 = Eq(move _3, const 'x'); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
-- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16
-- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16
-+ switchInt(move _3) -> ['x': bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
+ StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+- _2 = Eq(move _3, const 'x'); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
+- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16
++ switchInt(move _3) -> ['x': bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
}
bb1: {
-+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
- _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33
++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
+ _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+1:19: +1:20
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:33
}
bb2: {
-+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
- _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:30: +1:31
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33
++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
+ _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+1:30: +1:31
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:33
}
bb3: {
- StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33
- return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:32: +1:33
+ return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
index 8042d63bb..4297f4d64 100644
--- a/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
+++ b/src/test/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff
@@ -2,38 +2,38 @@
+ // MIR for `opt_i8` after SimplifyComparisonIntegral
fn opt_i8(_1: i8) -> u32 {
- debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:11: +0:12
- let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:21: +0:24
- let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- let mut _3: i8; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:11: +0:12
+ let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:21: +0:24
+ let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ let mut _3: i8; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
bb0: {
- StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
- _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
-- _2 = Eq(move _3, const 42_i8); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
-- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
-- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
-+ switchInt(move _3) -> [42_i8: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+- _2 = Eq(move _3, const 42_i8); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15
++ switchInt(move _3) -> [42_i8: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
}
bb1: {
-+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:18: +1:19
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32
++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+1:18: +1:19
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:32
}
bb2: {
-+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:29: +1:30
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32
++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+1:29: +1:30
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:32
}
bb3: {
- StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:31: +1:32
- return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:31: +1:32
+ return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
index a408de1ef..8fb794abb 100644
--- a/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
+++ b/src/test/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff
@@ -2,64 +2,64 @@
+ // MIR for `opt_multiple_ifs` after SimplifyComparisonIntegral
fn opt_multiple_ifs(_1: u32) -> u32 {
- debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:21: +0:22
- let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:32: +0:35
- let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- let mut _3: u32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
- let mut _4: bool; // in scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
- let mut _5: u32; // in scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16
+ debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:21: +0:22
+ let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:32: +0:35
+ let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ let mut _3: u32; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+ let mut _4: bool; // in scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22
+ let mut _5: u32; // in scope 0 at $DIR/if_condition_int.rs:+3:15: +3:16
bb0: {
- StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
- _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
-- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
-- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
-- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
-+ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15
++ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
}
bb1: {
-+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+2:9: +2:10
- goto -> bb6; // scope 0 at $DIR/if-condition-int.rs:+1:5: +7:6
++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+2:9: +2:10
+ goto -> bb6; // scope 0 at $DIR/if_condition_int.rs:+1:5: +7:6
}
bb2: {
-+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- StorageLive(_4); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
- StorageLive(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16
- _5 = _1; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:16
-- _4 = Ne(move _5, const 21_u32); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
-- StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:21: +3:22
-- switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+3:21: +3:22
-+ switchInt(move _5) -> [21_u32: bb4, otherwise: bb3]; // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ StorageLive(_4); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22
+ StorageLive(_5); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:16
+ _5 = _1; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:16
+- _4 = Ne(move _5, const 21_u32); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22
+- StorageDead(_5); // scope 0 at $DIR/if_condition_int.rs:+3:21: +3:22
+- switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22
++ nop; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22
++ nop; // scope 0 at $DIR/if_condition_int.rs:+3:21: +3:22
++ switchInt(move _5) -> [21_u32: bb4, otherwise: bb3]; // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22
}
bb3: {
-+ StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
- _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+4:9: +4:10
- goto -> bb5; // scope 0 at $DIR/if-condition-int.rs:+3:12: +7:6
++ StorageDead(_5); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22
+ _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+4:9: +4:10
+ goto -> bb5; // scope 0 at $DIR/if_condition_int.rs:+3:12: +7:6
}
bb4: {
-+ StorageDead(_5); // scope 0 at $DIR/if-condition-int.rs:+3:15: +3:22
- _0 = const 2_u32; // scope 0 at $DIR/if-condition-int.rs:+6:9: +6:10
- goto -> bb5; // scope 0 at $DIR/if-condition-int.rs:+3:12: +7:6
++ StorageDead(_5); // scope 0 at $DIR/if_condition_int.rs:+3:15: +3:22
+ _0 = const 2_u32; // scope 0 at $DIR/if_condition_int.rs:+6:9: +6:10
+ goto -> bb5; // scope 0 at $DIR/if_condition_int.rs:+3:12: +7:6
}
bb5: {
- StorageDead(_4); // scope 0 at $DIR/if-condition-int.rs:+7:5: +7:6
- goto -> bb6; // scope 0 at $DIR/if-condition-int.rs:+1:5: +7:6
+ StorageDead(_4); // scope 0 at $DIR/if_condition_int.rs:+7:5: +7:6
+ goto -> bb6; // scope 0 at $DIR/if_condition_int.rs:+1:5: +7:6
}
bb6: {
- StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+7:5: +7:6
- return; // scope 0 at $DIR/if-condition-int.rs:+8:2: +8:2
+ StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+7:5: +7:6
+ return; // scope 0 at $DIR/if_condition_int.rs:+8:2: +8:2
}
}
diff --git a/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
index 6802f89d9..992253ea7 100644
--- a/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
+++ b/src/test/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
@@ -2,38 +2,38 @@
+ // MIR for `opt_negative` after SimplifyComparisonIntegral
fn opt_negative(_1: i32) -> u32 {
- debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:17: +0:18
- let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:28: +0:31
- let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
- let mut _3: i32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:17: +0:18
+ let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:28: +0:31
+ let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
+ let mut _3: i32; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
bb0: {
- StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
- StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
- _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
-- _2 = Eq(move _3, const -42_i32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
-- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16
-- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:15: +1:16
-+ switchInt(move _3) -> [-42_i32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
+ StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
+ StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+- _2 = Eq(move _3, const -42_i32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
+- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:15: +1:16
++ switchInt(move _3) -> [-42_i32: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
}
bb1: {
-+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
- _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:19: +1:20
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33
++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
+ _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+1:19: +1:20
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:33
}
bb2: {
-+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:16
- _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:30: +1:31
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:33
++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:16
+ _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+1:30: +1:31
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:33
}
bb3: {
- StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:32: +1:33
- return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:32: +1:33
+ return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff b/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
index 96387771d..7cea9472d 100644
--- a/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
+++ b/src/test/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
@@ -2,38 +2,38 @@
+ // MIR for `opt_u32` after SimplifyComparisonIntegral
fn opt_u32(_1: u32) -> u32 {
- debug x => _1; // in scope 0 at $DIR/if-condition-int.rs:+0:12: +0:13
- let mut _0: u32; // return place in scope 0 at $DIR/if-condition-int.rs:+0:23: +0:26
- let mut _2: bool; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- let mut _3: u32; // in scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
+ debug x => _1; // in scope 0 at $DIR/if_condition_int.rs:+0:12: +0:13
+ let mut _0: u32; // return place in scope 0 at $DIR/if_condition_int.rs:+0:23: +0:26
+ let mut _2: bool; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ let mut _3: u32; // in scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
bb0: {
- StorageLive(_2); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- StorageLive(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
- _3 = _1; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:9
-- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
-- StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
-- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
-+ nop; // scope 0 at $DIR/if-condition-int.rs:+1:14: +1:15
-+ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
+ StorageLive(_2); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ StorageLive(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:9
+- _2 = Eq(move _3, const 42_u32); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+- StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15
+- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
++ nop; // scope 0 at $DIR/if_condition_int.rs:+1:14: +1:15
++ switchInt(move _3) -> [42_u32: bb1, otherwise: bb2]; // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
}
bb1: {
-+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- _0 = const 0_u32; // scope 0 at $DIR/if-condition-int.rs:+1:18: +1:19
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32
++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ _0 = const 0_u32; // scope 0 at $DIR/if_condition_int.rs:+1:18: +1:19
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:32
}
bb2: {
-+ StorageDead(_3); // scope 0 at $DIR/if-condition-int.rs:+1:8: +1:15
- _0 = const 1_u32; // scope 0 at $DIR/if-condition-int.rs:+1:29: +1:30
- goto -> bb3; // scope 0 at $DIR/if-condition-int.rs:+1:5: +1:32
++ StorageDead(_3); // scope 0 at $DIR/if_condition_int.rs:+1:8: +1:15
+ _0 = const 1_u32; // scope 0 at $DIR/if_condition_int.rs:+1:29: +1:30
+ goto -> bb3; // scope 0 at $DIR/if_condition_int.rs:+1:5: +1:32
}
bb3: {
- StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:+1:31: +1:32
- return; // scope 0 at $DIR/if-condition-int.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/if_condition_int.rs:+1:31: +1:32
+ return; // scope 0 at $DIR/if_condition_int.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/if-condition-int.rs b/src/test/mir-opt/if_condition_int.rs
index 398311e6b..398311e6b 100644
--- a/src/test/mir-opt/if-condition-int.rs
+++ b/src/test/mir-opt/if_condition_int.rs
diff --git a/src/test/mir-opt/inline/asm_unwind.main.Inline.diff b/src/test/mir-opt/inline/asm_unwind.main.Inline.diff
index 57072fc0a..f1b62ac38 100644
--- a/src/test/mir-opt/inline/asm_unwind.main.Inline.diff
+++ b/src/test/mir-opt/inline/asm_unwind.main.Inline.diff
@@ -2,44 +2,44 @@
+ // MIR for `main` after Inline
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/asm-unwind.rs:+0:15: +0:15
- let _1: (); // in scope 0 at $DIR/asm-unwind.rs:+1:5: +1:10
-+ scope 1 (inlined foo) { // at $DIR/asm-unwind.rs:21:5: 21:10
-+ let _2: D; // in scope 1 at $DIR/asm-unwind.rs:15:9: 15:11
+ let mut _0: (); // return place in scope 0 at $DIR/asm_unwind.rs:+0:15: +0:15
+ let _1: (); // in scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10
++ scope 1 (inlined foo) { // at $DIR/asm_unwind.rs:21:5: 21:10
++ let _2: D; // in scope 1 at $DIR/asm_unwind.rs:15:9: 15:11
+ scope 2 {
-+ debug _d => _2; // in scope 2 at $DIR/asm-unwind.rs:15:9: 15:11
++ debug _d => _2; // in scope 2 at $DIR/asm_unwind.rs:15:9: 15:11
+ scope 3 {
+ }
+ }
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/asm-unwind.rs:+1:5: +1:10
-- _1 = foo() -> bb1; // scope 0 at $DIR/asm-unwind.rs:+1:5: +1:10
+ StorageLive(_1); // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10
+- _1 = foo() -> bb1; // scope 0 at $DIR/asm_unwind.rs:+1:5: +1:10
- // mir::Constant
-- // + span: $DIR/asm-unwind.rs:21:5: 21:8
+- // + span: $DIR/asm_unwind.rs:21:5: 21:8
- // + literal: Const { ty: fn() {foo}, val: Value(<ZST>) }
-+ StorageLive(_2); // scope 1 at $DIR/asm-unwind.rs:15:9: 15:11
-+ asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind: bb3]; // scope 3 at $DIR/asm-unwind.rs:16:14: 16:54
++ StorageLive(_2); // scope 1 at $DIR/asm_unwind.rs:15:9: 15:11
++ asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind: bb3]; // scope 3 at $DIR/asm_unwind.rs:16:14: 16:54
}
bb1: {
-+ drop(_2) -> bb2; // scope 1 at $DIR/asm-unwind.rs:17:1: 17:2
++ drop(_2) -> bb2; // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2
+ }
+
+ bb2: {
-+ StorageDead(_2); // scope 1 at $DIR/asm-unwind.rs:17:1: 17:2
- StorageDead(_1); // scope 0 at $DIR/asm-unwind.rs:+1:10: +1:11
- _0 = const (); // scope 0 at $DIR/asm-unwind.rs:+0:15: +2:2
- return; // scope 0 at $DIR/asm-unwind.rs:+2:2: +2:2
++ StorageDead(_2); // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2
+ StorageDead(_1); // scope 0 at $DIR/asm_unwind.rs:+1:10: +1:11
+ _0 = const (); // scope 0 at $DIR/asm_unwind.rs:+0:15: +2:2
+ return; // scope 0 at $DIR/asm_unwind.rs:+2:2: +2:2
+ }
+
+ bb3 (cleanup): {
-+ drop(_2) -> bb4; // scope 1 at $DIR/asm-unwind.rs:17:1: 17:2
++ drop(_2) -> bb4; // scope 1 at $DIR/asm_unwind.rs:17:1: 17:2
+ }
+
+ bb4 (cleanup): {
-+ resume; // scope 1 at $DIR/asm-unwind.rs:14:1: 17:2
++ resume; // scope 1 at $DIR/asm_unwind.rs:14:1: 17:2
}
}
diff --git a/src/test/mir-opt/inline/asm-unwind.rs b/src/test/mir-opt/inline/asm_unwind.rs
index c03feb433..c03feb433 100644
--- a/src/test/mir-opt/inline/asm-unwind.rs
+++ b/src/test/mir-opt/inline/asm_unwind.rs
diff --git a/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff b/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff
index d7deb9c66..8b0300678 100644
--- a/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff
+++ b/src/test/mir-opt/inline/caller_with_trivial_bound.foo.Inline.diff
@@ -2,32 +2,32 @@
+ // MIR for `foo` after Inline
fn foo() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/caller-with-trivial-bound.rs:+1:1: +1:1
- let mut _1: <IntFactory as Factory<T>>::Item; // in scope 0 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14
+ let mut _0: (); // return place in scope 0 at $DIR/caller_with_trivial_bound.rs:+1:1: +1:1
+ let mut _1: <IntFactory as Factory<T>>::Item; // in scope 0 at $DIR/caller_with_trivial_bound.rs:+4:9: +4:14
scope 1 {
- debug x => _1; // in scope 1 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14
+ debug x => _1; // in scope 1 at $DIR/caller_with_trivial_bound.rs:+4:9: +4:14
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/caller-with-trivial-bound.rs:+4:9: +4:14
- _1 = bar::<T>() -> bb1; // scope 0 at $DIR/caller-with-trivial-bound.rs:+4:51: +4:61
+ StorageLive(_1); // scope 0 at $DIR/caller_with_trivial_bound.rs:+4:9: +4:14
+ _1 = bar::<T>() -> bb1; // scope 0 at $DIR/caller_with_trivial_bound.rs:+4:51: +4:61
// mir::Constant
- // + span: $DIR/caller-with-trivial-bound.rs:20:51: 20:59
+ // + span: $DIR/caller_with_trivial_bound.rs:20:51: 20:59
// + literal: Const { ty: fn() -> <IntFactory as Factory<T>>::Item {bar::<T>}, val: Value(<ZST>) }
}
bb1: {
- _0 = const (); // scope 0 at $DIR/caller-with-trivial-bound.rs:+3:1: +5:2
- drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:1: +5:2
+ _0 = const (); // scope 0 at $DIR/caller_with_trivial_bound.rs:+3:1: +5:2
+ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/caller_with_trivial_bound.rs:+5:1: +5:2
}
bb2: {
- StorageDead(_1); // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:1: +5:2
- return; // scope 0 at $DIR/caller-with-trivial-bound.rs:+5:2: +5:2
+ StorageDead(_1); // scope 0 at $DIR/caller_with_trivial_bound.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/caller_with_trivial_bound.rs:+5:2: +5:2
}
bb3 (cleanup): {
- resume; // scope 0 at $DIR/caller-with-trivial-bound.rs:+0:1: +5:2
+ resume; // scope 0 at $DIR/caller_with_trivial_bound.rs:+0:1: +5:2
}
}
diff --git a/src/test/mir-opt/inline/caller-with-trivial-bound.rs b/src/test/mir-opt/inline/caller_with_trivial_bound.rs
index 8545db894..8545db894 100644
--- a/src/test/mir-opt/inline/caller-with-trivial-bound.rs
+++ b/src/test/mir-opt/inline/caller_with_trivial_bound.rs
diff --git a/src/test/mir-opt/inline/cycle.g.Inline.diff b/src/test/mir-opt/inline/cycle.g.Inline.diff
index 5f3ee467c..afe157ccd 100644
--- a/src/test/mir-opt/inline/cycle.g.Inline.diff
+++ b/src/test/mir-opt/inline/cycle.g.Inline.diff
@@ -10,8 +10,6 @@
+ let _3: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
+ let mut _4: &fn() {main}; // in scope 1 at $DIR/cycle.rs:6:5: 6:6
+ let mut _5: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
-+ scope 2 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8
-+ }
+ }
bb0: {
@@ -29,7 +27,10 @@
+ StorageLive(_4); // scope 1 at $DIR/cycle.rs:6:5: 6:6
+ _4 = &_2; // scope 1 at $DIR/cycle.rs:6:5: 6:6
+ StorageLive(_5); // scope 1 at $DIR/cycle.rs:6:5: 6:8
-+ _3 = move (*_4)() -> [return: bb4, unwind: bb2]; // scope 2 at $SRC_DIR/core/src/ops/function.rs:LL:COL
++ _3 = <fn() {main} as Fn<()>>::call(move _4, move _5) -> [return: bb2, unwind: bb3]; // scope 1 at $DIR/cycle.rs:6:5: 6:8
++ // mir::Constant
++ // + span: $DIR/cycle.rs:6:5: 6:6
++ // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() {main}, ()) -> <fn() {main} as FnOnce<()>>::Output {<fn() {main} as Fn<()>>::call}, val: Value(<ZST>) }
}
bb1: {
@@ -39,19 +40,19 @@
return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2
+ }
+
-+ bb2 (cleanup): {
-+ drop(_2) -> bb3; // scope 1 at $DIR/cycle.rs:7:1: 7:2
++ bb2: {
++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:8: 6:9
++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:7:1: 7:2
+ }
+
+ bb3 (cleanup): {
-+ resume; // scope 1 at $DIR/cycle.rs:5:1: 7:2
++ drop(_2) -> bb4; // scope 1 at $DIR/cycle.rs:7:1: 7:2
+ }
+
-+ bb4: {
-+ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:7: 6:8
-+ StorageDead(_4); // scope 1 at $DIR/cycle.rs:6:7: 6:8
-+ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:8: 6:9
-+ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:7:1: 7:2
++ bb4 (cleanup): {
++ resume; // scope 1 at $DIR/cycle.rs:5:1: 7:2
}
}
diff --git a/src/test/mir-opt/inline/cycle.main.Inline.diff b/src/test/mir-opt/inline/cycle.main.Inline.diff
index 8b4099b9d..bd89e09ec 100644
--- a/src/test/mir-opt/inline/cycle.main.Inline.diff
+++ b/src/test/mir-opt/inline/cycle.main.Inline.diff
@@ -10,18 +10,6 @@
+ let _3: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
+ let mut _4: &fn() {g}; // in scope 1 at $DIR/cycle.rs:6:5: 6:6
+ let mut _5: (); // in scope 1 at $DIR/cycle.rs:6:5: 6:8
-+ scope 2 (inlined <fn() {g} as Fn<()>>::call - shim(fn() {g})) { // at $DIR/cycle.rs:6:5: 6:8
-+ scope 3 (inlined g) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
-+ let mut _6: fn() {main}; // in scope 3 at $DIR/cycle.rs:12:5: 12:12
-+ scope 4 (inlined f::<fn() {main}>) { // at $DIR/cycle.rs:12:5: 12:12
-+ debug g => _6; // in scope 4 at $DIR/cycle.rs:5:6: 5:7
-+ let _7: (); // in scope 4 at $DIR/cycle.rs:6:5: 6:8
-+ let mut _8: &fn() {main}; // in scope 4 at $DIR/cycle.rs:6:5: 6:6
-+ scope 5 (inlined <fn() {main} as Fn<()>>::call - shim(fn() {main})) { // at $DIR/cycle.rs:6:5: 6:8
-+ }
-+ }
-+ }
-+ }
+ }
bb0: {
@@ -39,11 +27,10 @@
+ StorageLive(_4); // scope 1 at $DIR/cycle.rs:6:5: 6:6
+ _4 = &_2; // scope 1 at $DIR/cycle.rs:6:5: 6:6
+ StorageLive(_5); // scope 1 at $DIR/cycle.rs:6:5: 6:8
-+ StorageLive(_6); // scope 3 at $DIR/cycle.rs:12:5: 12:12
-+ StorageLive(_7); // scope 4 at $DIR/cycle.rs:6:5: 6:8
-+ StorageLive(_8); // scope 4 at $DIR/cycle.rs:6:5: 6:6
-+ _8 = &_6; // scope 4 at $DIR/cycle.rs:6:5: 6:6
-+ _7 = move (*_8)() -> [return: bb4, unwind: bb2]; // scope 5 at $SRC_DIR/core/src/ops/function.rs:LL:COL
++ _3 = <fn() {g} as Fn<()>>::call(move _4, move _5) -> [return: bb2, unwind: bb3]; // scope 1 at $DIR/cycle.rs:6:5: 6:8
++ // mir::Constant
++ // + span: $DIR/cycle.rs:6:5: 6:6
++ // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() {g}, ()) -> <fn() {g} as FnOnce<()>>::Output {<fn() {g} as Fn<()>>::call}, val: Value(<ZST>) }
}
bb1: {
@@ -53,22 +40,19 @@
return; // scope 0 at $DIR/cycle.rs:+2:2: +2:2
+ }
+
-+ bb2 (cleanup): {
-+ drop(_2) -> bb3; // scope 1 at $DIR/cycle.rs:7:1: 7:2
++ bb2: {
++ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_4); // scope 1 at $DIR/cycle.rs:6:7: 6:8
++ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:8: 6:9
++ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:7:1: 7:2
+ }
+
+ bb3 (cleanup): {
-+ resume; // scope 1 at $DIR/cycle.rs:5:1: 7:2
++ drop(_2) -> bb4; // scope 1 at $DIR/cycle.rs:7:1: 7:2
+ }
+
-+ bb4: {
-+ StorageDead(_8); // scope 4 at $DIR/cycle.rs:6:7: 6:8
-+ StorageDead(_7); // scope 4 at $DIR/cycle.rs:6:8: 6:9
-+ StorageDead(_6); // scope 3 at $DIR/cycle.rs:12:5: 12:12
-+ StorageDead(_5); // scope 1 at $DIR/cycle.rs:6:7: 6:8
-+ StorageDead(_4); // scope 1 at $DIR/cycle.rs:6:7: 6:8
-+ StorageDead(_3); // scope 1 at $DIR/cycle.rs:6:8: 6:9
-+ drop(_2) -> bb1; // scope 1 at $DIR/cycle.rs:7:1: 7:2
++ bb4 (cleanup): {
++ resume; // scope 1 at $DIR/cycle.rs:5:1: 7:2
}
}
diff --git a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff
index 1e95b5b29..8ea1a0757 100644
--- a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff
+++ b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff
@@ -2,61 +2,53 @@
+ // MIR for `get_query` after Inline
fn get_query(_1: &T) -> () {
- debug t => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:31: +0:32
- let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:38: +0:38
- let _2: &<Q as Query>::C; // in scope 0 at $DIR/dyn-trait.rs:+1:9: +1:10
- let mut _3: &T; // in scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23
- let mut _4: &<Q as Query>::C; // in scope 0 at $DIR/dyn-trait.rs:+2:23: +2:24
+ debug t => _1; // in scope 0 at $DIR/dyn_trait.rs:+0:31: +0:32
+ let mut _0: (); // return place in scope 0 at $DIR/dyn_trait.rs:+0:38: +0:38
+ let _2: &<Q as Query>::C; // in scope 0 at $DIR/dyn_trait.rs:+1:9: +1:10
+ let mut _3: &T; // in scope 0 at $DIR/dyn_trait.rs:+1:22: +1:23
+ let mut _4: &<Q as Query>::C; // in scope 0 at $DIR/dyn_trait.rs:+2:23: +2:24
scope 1 {
- debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:+1:9: +1:10
-+ scope 2 (inlined try_execute_query::<<Q as Query>::C>) { // at $DIR/dyn-trait.rs:34:5: 34:25
-+ debug c => _4; // in scope 2 at $DIR/dyn-trait.rs:26:36: 26:37
-+ let mut _5: &dyn Cache<V = <Q as Query>::V>; // in scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
-+ let mut _6: &<Q as Query>::C; // in scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
-+ scope 3 (inlined mk_cycle::<<Q as Query>::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16
-+ debug c => _5; // in scope 3 at $DIR/dyn-trait.rs:20:27: 20:28
-+ let mut _7: &dyn Cache<V = <Q as Query>::V>; // in scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
+ debug c => _2; // in scope 1 at $DIR/dyn_trait.rs:+1:9: +1:10
++ scope 2 (inlined try_execute_query::<<Q as Query>::C>) { // at $DIR/dyn_trait.rs:34:5: 34:25
++ debug c => _4; // in scope 2 at $DIR/dyn_trait.rs:26:36: 26:37
++ let mut _5: &dyn Cache<V = <Q as Query>::V>; // in scope 2 at $DIR/dyn_trait.rs:27:14: 27:15
++ scope 3 (inlined mk_cycle::<<Q as Query>::V>) { // at $DIR/dyn_trait.rs:27:5: 27:16
++ debug c => _5; // in scope 3 at $DIR/dyn_trait.rs:20:27: 20:28
+ }
+ }
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:9: +1:10
- StorageLive(_3); // scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23
- _3 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:22: +1:23
- _2 = <Q as Query>::cache::<T>(move _3) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:13: +1:24
+ StorageLive(_2); // scope 0 at $DIR/dyn_trait.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/dyn_trait.rs:+1:22: +1:23
+ _3 = &(*_1); // scope 0 at $DIR/dyn_trait.rs:+1:22: +1:23
+ _2 = <Q as Query>::cache::<T>(move _3) -> bb1; // scope 0 at $DIR/dyn_trait.rs:+1:13: +1:24
// mir::Constant
- // + span: $DIR/dyn-trait.rs:33:13: 33:21
+ // + span: $DIR/dyn_trait.rs:33:13: 33:21
// + user_ty: UserType(0)
// + literal: Const { ty: for<'a> fn(&'a T) -> &'a <Q as Query>::C {<Q as Query>::cache::<T>}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 0 at $DIR/dyn-trait.rs:+1:23: +1:24
- StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:+2:23: +2:24
- _4 = &(*_2); // scope 1 at $DIR/dyn-trait.rs:+2:23: +2:24
-- _0 = try_execute_query::<<Q as Query>::C>(move _4) -> bb2; // scope 1 at $DIR/dyn-trait.rs:+2:5: +2:25
-+ StorageLive(_5); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
-+ StorageLive(_6); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
-+ _6 = _4; // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
-+ _5 = move _6 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
-+ StorageDead(_6); // scope 2 at $DIR/dyn-trait.rs:27:14: 27:15
-+ StorageLive(_7); // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
-+ _7 = _5; // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
-+ _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _7) -> bb2; // scope 3 at $DIR/dyn-trait.rs:21:5: 21:22
+ StorageDead(_3); // scope 0 at $DIR/dyn_trait.rs:+1:23: +1:24
+ StorageLive(_4); // scope 1 at $DIR/dyn_trait.rs:+2:23: +2:24
+ _4 = &(*_2); // scope 1 at $DIR/dyn_trait.rs:+2:23: +2:24
+- _0 = try_execute_query::<<Q as Query>::C>(move _4) -> bb2; // scope 1 at $DIR/dyn_trait.rs:+2:5: +2:25
++ StorageLive(_5); // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15
++ _5 = move _4 as &dyn Cache<V = <Q as Query>::V> (Pointer(Unsize)); // scope 2 at $DIR/dyn_trait.rs:27:14: 27:15
++ _0 = <dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache(move _5) -> bb2; // scope 3 at $DIR/dyn_trait.rs:21:5: 21:22
// mir::Constant
-- // + span: $DIR/dyn-trait.rs:34:5: 34:22
+- // + span: $DIR/dyn_trait.rs:34:5: 34:22
- // + literal: Const { ty: for<'a> fn(&'a <Q as Query>::C) {try_execute_query::<<Q as Query>::C>}, val: Value(<ZST>) }
-+ // + span: $DIR/dyn-trait.rs:21:7: 21:20
++ // + span: $DIR/dyn_trait.rs:21:7: 21:20
+ // + literal: Const { ty: for<'a> fn(&'a dyn Cache<V = <Q as Query>::V>) {<dyn Cache<V = <Q as Query>::V> as Cache>::store_nocache}, val: Value(<ZST>) }
}
bb2: {
-+ StorageDead(_7); // scope 3 at $DIR/dyn-trait.rs:21:21: 21:22
-+ StorageDead(_5); // scope 2 at $DIR/dyn-trait.rs:27:15: 27:16
- StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:+2:24: +2:25
- StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+3:1: +3:2
- return; // scope 0 at $DIR/dyn-trait.rs:+3:2: +3:2
++ StorageDead(_5); // scope 2 at $DIR/dyn_trait.rs:27:15: 27:16
+ StorageDead(_4); // scope 1 at $DIR/dyn_trait.rs:+2:24: +2:25
+ StorageDead(_2); // scope 0 at $DIR/dyn_trait.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/dyn_trait.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff b/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff
index 7421db4d0..7653a5ded 100644
--- a/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff
+++ b/src/test/mir-opt/inline/dyn_trait.mk_cycle.Inline.diff
@@ -2,22 +2,22 @@
+ // MIR for `mk_cycle` after Inline
fn mk_cycle(_1: &dyn Cache<V = V>) -> () {
- debug c => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:27: +0:28
- let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:49: +0:49
- let mut _2: &dyn Cache<V = V>; // in scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22
+ debug c => _1; // in scope 0 at $DIR/dyn_trait.rs:+0:27: +0:28
+ let mut _0: (); // return place in scope 0 at $DIR/dyn_trait.rs:+0:49: +0:49
+ let mut _2: &dyn Cache<V = V>; // in scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22
bb0: {
- StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22
- _2 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22
- _0 = <dyn Cache<V = V> as Cache>::store_nocache(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:22
+ StorageLive(_2); // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22
+ _2 = &(*_1); // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22
+ _0 = <dyn Cache<V = V> as Cache>::store_nocache(move _2) -> bb1; // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:22
// mir::Constant
- // + span: $DIR/dyn-trait.rs:21:7: 21:20
+ // + span: $DIR/dyn_trait.rs:21:7: 21:20
// + literal: Const { ty: for<'a> fn(&'a dyn Cache<V = V>) {<dyn Cache<V = V> as Cache>::store_nocache}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+1:21: +1:22
- return; // scope 0 at $DIR/dyn-trait.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/dyn_trait.rs:+1:21: +1:22
+ return; // scope 0 at $DIR/dyn_trait.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/dyn-trait.rs b/src/test/mir-opt/inline/dyn_trait.rs
index 6a46e1e07..6a46e1e07 100644
--- a/src/test/mir-opt/inline/dyn-trait.rs
+++ b/src/test/mir-opt/inline/dyn_trait.rs
diff --git a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
index e6e783744..a71d73b74 100644
--- a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
+++ b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff
@@ -2,36 +2,32 @@
+ // MIR for `try_execute_query` after Inline
fn try_execute_query(_1: &C) -> () {
- debug c => _1; // in scope 0 at $DIR/dyn-trait.rs:+0:36: +0:37
- let mut _0: (); // return place in scope 0 at $DIR/dyn-trait.rs:+0:43: +0:43
- let mut _2: &dyn Cache<V = <C as Cache>::V>; // in scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
- let mut _3: &C; // in scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
-+ scope 1 (inlined mk_cycle::<<C as Cache>::V>) { // at $DIR/dyn-trait.rs:27:5: 27:16
-+ debug c => _2; // in scope 1 at $DIR/dyn-trait.rs:20:27: 20:28
-+ let mut _4: &dyn Cache<V = <C as Cache>::V>; // in scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
+ debug c => _1; // in scope 0 at $DIR/dyn_trait.rs:+0:36: +0:37
+ let mut _0: (); // return place in scope 0 at $DIR/dyn_trait.rs:+0:43: +0:43
+ let mut _2: &dyn Cache<V = <C as Cache>::V>; // in scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15
+ let mut _3: &C; // in scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15
++ scope 1 (inlined mk_cycle::<<C as Cache>::V>) { // at $DIR/dyn_trait.rs:27:5: 27:16
++ debug c => _2; // in scope 1 at $DIR/dyn_trait.rs:20:27: 20:28
+ }
bb0: {
- StorageLive(_2); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
- StorageLive(_3); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
- _3 = &(*_1); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
- _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (Pointer(Unsize)); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
- StorageDead(_3); // scope 0 at $DIR/dyn-trait.rs:+1:14: +1:15
-- _0 = mk_cycle::<<C as Cache>::V>(move _2) -> bb1; // scope 0 at $DIR/dyn-trait.rs:+1:5: +1:16
-+ StorageLive(_4); // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
-+ _4 = _2; // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
-+ _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _4) -> bb1; // scope 1 at $DIR/dyn-trait.rs:21:5: 21:22
+ StorageLive(_2); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15
+ StorageLive(_3); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15
+ _3 = &(*_1); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15
+ _2 = move _3 as &dyn Cache<V = <C as Cache>::V> (Pointer(Unsize)); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15
+ StorageDead(_3); // scope 0 at $DIR/dyn_trait.rs:+1:14: +1:15
+- _0 = mk_cycle::<<C as Cache>::V>(move _2) -> bb1; // scope 0 at $DIR/dyn_trait.rs:+1:5: +1:16
++ _0 = <dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache(move _2) -> bb1; // scope 1 at $DIR/dyn_trait.rs:21:5: 21:22
// mir::Constant
-- // + span: $DIR/dyn-trait.rs:27:5: 27:13
+- // + span: $DIR/dyn_trait.rs:27:5: 27:13
- // + literal: Const { ty: for<'a> fn(&'a (dyn Cache<V = <C as Cache>::V> + 'a)) {mk_cycle::<<C as Cache>::V>}, val: Value(<ZST>) }
-+ // + span: $DIR/dyn-trait.rs:21:7: 21:20
++ // + span: $DIR/dyn_trait.rs:21:7: 21:20
+ // + literal: Const { ty: for<'a> fn(&'a dyn Cache<V = <C as Cache>::V>) {<dyn Cache<V = <C as Cache>::V> as Cache>::store_nocache}, val: Value(<ZST>) }
}
bb1: {
-+ StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:21:21: 21:22
- StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:+1:15: +1:16
- return; // scope 0 at $DIR/dyn-trait.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/dyn_trait.rs:+1:15: +1:16
+ return; // scope 0 at $DIR/dyn_trait.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/exponential_runtime.main.Inline.diff b/src/test/mir-opt/inline/exponential_runtime.main.Inline.diff
new file mode 100644
index 000000000..d9fd7b324
--- /dev/null
+++ b/src/test/mir-opt/inline/exponential_runtime.main.Inline.diff
@@ -0,0 +1,50 @@
+- // MIR for `main` before Inline
++ // MIR for `main` after Inline
+
+ fn main() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/exponential_runtime.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22
++ scope 1 (inlined <() as G>::call) { // at $DIR/exponential_runtime.rs:86:5: 86:22
++ let _2: (); // in scope 1 at $DIR/exponential_runtime.rs:73:9: 73:25
++ let _3: (); // in scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25
++ let _4: (); // in scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25
++ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22
+- _1 = <() as G>::call() -> bb1; // scope 0 at $DIR/exponential_runtime.rs:+1:5: +1:22
++ StorageLive(_2); // scope 1 at $DIR/exponential_runtime.rs:73:9: 73:25
++ _2 = <() as F>::call() -> bb1; // scope 1 at $DIR/exponential_runtime.rs:73:9: 73:25
+ // mir::Constant
+- // + span: $DIR/exponential_runtime.rs:86:5: 86:20
+- // + literal: Const { ty: fn() {<() as G>::call}, val: Value(<ZST>) }
++ // + span: $DIR/exponential_runtime.rs:73:9: 73:23
++ // + literal: Const { ty: fn() {<() as F>::call}, val: Value(<ZST>) }
+ }
+
+ bb1: {
++ StorageDead(_2); // scope 1 at $DIR/exponential_runtime.rs:73:25: 73:26
++ StorageLive(_3); // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25
++ _3 = <() as F>::call() -> bb2; // scope 1 at $DIR/exponential_runtime.rs:74:9: 74:25
++ // mir::Constant
++ // + span: $DIR/exponential_runtime.rs:74:9: 74:23
++ // + literal: Const { ty: fn() {<() as F>::call}, val: Value(<ZST>) }
++ }
++
++ bb2: {
++ StorageDead(_3); // scope 1 at $DIR/exponential_runtime.rs:74:25: 74:26
++ StorageLive(_4); // scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25
++ _4 = <() as F>::call() -> bb3; // scope 1 at $DIR/exponential_runtime.rs:75:9: 75:25
++ // mir::Constant
++ // + span: $DIR/exponential_runtime.rs:75:9: 75:23
++ // + literal: Const { ty: fn() {<() as F>::call}, val: Value(<ZST>) }
++ }
++
++ bb3: {
++ StorageDead(_4); // scope 1 at $DIR/exponential_runtime.rs:75:25: 75:26
+ StorageDead(_1); // scope 0 at $DIR/exponential_runtime.rs:+1:22: +1:23
+ _0 = const (); // scope 0 at $DIR/exponential_runtime.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/exponential_runtime.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/inline/exponential_runtime.rs b/src/test/mir-opt/inline/exponential_runtime.rs
new file mode 100644
index 000000000..d9219d76a
--- /dev/null
+++ b/src/test/mir-opt/inline/exponential_runtime.rs
@@ -0,0 +1,87 @@
+// Checks that code with exponential runtime does not have exponential behavior in inlining.
+
+trait A {
+ fn call();
+}
+
+trait B {
+ fn call();
+}
+impl<T: A> B for T {
+ #[inline]
+ fn call() {
+ <T as A>::call();
+ <T as A>::call();
+ <T as A>::call();
+ }
+}
+
+trait C {
+ fn call();
+}
+impl<T: B> C for T {
+ #[inline]
+ fn call() {
+ <T as B>::call();
+ <T as B>::call();
+ <T as B>::call();
+ }
+}
+
+trait D {
+ fn call();
+}
+impl<T: C> D for T {
+ #[inline]
+ fn call() {
+ <T as C>::call();
+ <T as C>::call();
+ <T as C>::call();
+ }
+}
+
+trait E {
+ fn call();
+}
+impl<T: D> E for T {
+ #[inline]
+ fn call() {
+ <T as D>::call();
+ <T as D>::call();
+ <T as D>::call();
+ }
+}
+
+trait F {
+ fn call();
+}
+impl<T: E> F for T {
+ #[inline]
+ fn call() {
+ <T as E>::call();
+ <T as E>::call();
+ <T as E>::call();
+ }
+}
+
+trait G {
+ fn call();
+}
+impl<T: F> G for T {
+ #[inline]
+ fn call() {
+ <T as F>::call();
+ <T as F>::call();
+ <T as F>::call();
+ }
+}
+
+impl A for () {
+ #[inline(never)]
+ fn call() {}
+}
+
+// EMIT_MIR exponential_runtime.main.Inline.diff
+fn main() {
+ <() as G>::call();
+}
diff --git a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
index b27425fb1..3502c2586 100644
--- a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir
@@ -1,44 +1,36 @@
// MIR for `bar` after Inline
fn bar() -> bool {
- let mut _0: bool; // return place in scope 0 at $DIR/inline-any-operand.rs:+0:13: +0:17
- let _1: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline-any-operand.rs:+1:9: +1:10
- let mut _2: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:6
- let mut _3: i32; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:13
- let mut _4: i32; // in scope 0 at $DIR/inline-any-operand.rs:+2:5: +2:13
+ let mut _0: bool; // return place in scope 0 at $DIR/inline_any_operand.rs:+0:13: +0:17
+ let _1: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline_any_operand.rs:+1:9: +1:10
+ let mut _2: fn(i32, i32) -> bool {foo}; // in scope 0 at $DIR/inline_any_operand.rs:+2:5: +2:6
+ let mut _3: i32; // in scope 0 at $DIR/inline_any_operand.rs:+2:5: +2:13
+ let mut _4: i32; // in scope 0 at $DIR/inline_any_operand.rs:+2:5: +2:13
scope 1 {
- debug f => _1; // in scope 1 at $DIR/inline-any-operand.rs:+1:9: +1:10
- scope 2 (inlined foo) { // at $DIR/inline-any-operand.rs:12:5: 12:13
- debug x => _3; // in scope 2 at $DIR/inline-any-operand.rs:16:8: 16:9
- debug y => _4; // in scope 2 at $DIR/inline-any-operand.rs:16:16: 16:17
- let mut _5: i32; // in scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6
- let mut _6: i32; // in scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11
+ debug f => _1; // in scope 1 at $DIR/inline_any_operand.rs:+1:9: +1:10
+ scope 2 (inlined foo) { // at $DIR/inline_any_operand.rs:12:5: 12:13
+ debug x => _3; // in scope 2 at $DIR/inline_any_operand.rs:16:8: 16:9
+ debug y => _4; // in scope 2 at $DIR/inline_any_operand.rs:16:16: 16:17
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-any-operand.rs:+1:9: +1:10
- _1 = foo; // scope 0 at $DIR/inline-any-operand.rs:+1:13: +1:16
+ StorageLive(_1); // scope 0 at $DIR/inline_any_operand.rs:+1:9: +1:10
+ _1 = foo; // scope 0 at $DIR/inline_any_operand.rs:+1:13: +1:16
// mir::Constant
- // + span: $DIR/inline-any-operand.rs:11:13: 11:16
+ // + span: $DIR/inline_any_operand.rs:11:13: 11:16
// + literal: Const { ty: fn(i32, i32) -> bool {foo}, val: Value(<ZST>) }
- StorageLive(_2); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:6
- _2 = _1; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:6
- StorageLive(_3); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
- _3 = const 1_i32; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
- StorageLive(_4); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
- _4 = const -1_i32; // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
- StorageLive(_5); // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6
- _5 = _3; // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:6
- StorageLive(_6); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11
- _6 = _4; // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11
- _0 = Eq(move _5, move _6); // scope 2 at $DIR/inline-any-operand.rs:17:5: 17:11
- StorageDead(_6); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11
- StorageDead(_5); // scope 2 at $DIR/inline-any-operand.rs:17:10: 17:11
- StorageDead(_4); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
- StorageDead(_3); // scope 1 at $DIR/inline-any-operand.rs:+2:5: +2:13
- StorageDead(_2); // scope 1 at $DIR/inline-any-operand.rs:+2:12: +2:13
- StorageDead(_1); // scope 0 at $DIR/inline-any-operand.rs:+3:1: +3:2
- return; // scope 0 at $DIR/inline-any-operand.rs:+3:2: +3:2
+ StorageLive(_2); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:6
+ _2 = _1; // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:6
+ StorageLive(_3); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
+ _3 = const 1_i32; // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
+ StorageLive(_4); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
+ _4 = const -1_i32; // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
+ _0 = Eq(move _3, move _4); // scope 2 at $DIR/inline_any_operand.rs:17:5: 17:11
+ StorageDead(_4); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
+ StorageDead(_3); // scope 1 at $DIR/inline_any_operand.rs:+2:5: +2:13
+ StorageDead(_2); // scope 1 at $DIR/inline_any_operand.rs:+2:12: +2:13
+ StorageDead(_1); // scope 0 at $DIR/inline_any_operand.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/inline_any_operand.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/inline/inline-any-operand.rs b/src/test/mir-opt/inline/inline_any_operand.rs
index fb0de020f..fb0de020f 100644
--- a/src/test/mir-opt/inline/inline-any-operand.rs
+++ b/src/test/mir-opt/inline/inline_any_operand.rs
diff --git a/src/test/mir-opt/inline/inline-async.rs b/src/test/mir-opt/inline/inline_async.rs
index 5c838159b..5c838159b 100644
--- a/src/test/mir-opt/inline/inline-async.rs
+++ b/src/test/mir-opt/inline/inline_async.rs
diff --git a/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir
index 1fadd2464..9eb3a01ee 100644
--- a/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir
@@ -1,49 +1,49 @@
// MIR for `foo` after Inline
fn foo(_1: T, _2: i32) -> i32 {
- debug _t => _1; // in scope 0 at $DIR/inline-closure.rs:+0:17: +0:19
- debug q => _2; // in scope 0 at $DIR/inline-closure.rs:+0:24: +0:25
- let mut _0: i32; // return place in scope 0 at $DIR/inline-closure.rs:+0:35: +0:38
- let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure.rs:+1:9: +1:10
- let mut _4: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:6
- let mut _5: (i32, i32); // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12
- let mut _6: i32; // in scope 0 at $DIR/inline-closure.rs:+2:7: +2:8
- let mut _7: i32; // in scope 0 at $DIR/inline-closure.rs:+2:10: +2:11
- let mut _8: i32; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12
- let mut _9: i32; // in scope 0 at $DIR/inline-closure.rs:+2:5: +2:12
+ debug _t => _1; // in scope 0 at $DIR/inline_closure.rs:+0:17: +0:19
+ debug q => _2; // in scope 0 at $DIR/inline_closure.rs:+0:24: +0:25
+ let mut _0: i32; // return place in scope 0 at $DIR/inline_closure.rs:+0:35: +0:38
+ let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline_closure.rs:+1:9: +1:10
+ let mut _4: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline_closure.rs:+2:5: +2:6
+ let mut _5: (i32, i32); // in scope 0 at $DIR/inline_closure.rs:+2:5: +2:12
+ let mut _6: i32; // in scope 0 at $DIR/inline_closure.rs:+2:7: +2:8
+ let mut _7: i32; // in scope 0 at $DIR/inline_closure.rs:+2:10: +2:11
+ let mut _8: i32; // in scope 0 at $DIR/inline_closure.rs:+2:5: +2:12
+ let mut _9: i32; // in scope 0 at $DIR/inline_closure.rs:+2:5: +2:12
scope 1 {
- debug x => _3; // in scope 1 at $DIR/inline-closure.rs:+1:9: +1:10
- scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline-closure.rs:12:5: 12:12
- debug _t => _8; // in scope 2 at $DIR/inline-closure.rs:+1:14: +1:16
- debug _q => _9; // in scope 2 at $DIR/inline-closure.rs:+1:18: +1:20
+ debug x => _3; // in scope 1 at $DIR/inline_closure.rs:+1:9: +1:10
+ scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline_closure.rs:12:5: 12:12
+ debug _t => _8; // in scope 2 at $DIR/inline_closure.rs:+1:14: +1:16
+ debug _q => _9; // in scope 2 at $DIR/inline_closure.rs:+1:18: +1:20
}
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/inline-closure.rs:+1:9: +1:10
- Deinit(_3); // scope 0 at $DIR/inline-closure.rs:+1:13: +1:24
- StorageLive(_4); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:6
- _4 = &_3; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:6
- StorageLive(_5); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
- StorageLive(_6); // scope 1 at $DIR/inline-closure.rs:+2:7: +2:8
- _6 = _2; // scope 1 at $DIR/inline-closure.rs:+2:7: +2:8
- StorageLive(_7); // scope 1 at $DIR/inline-closure.rs:+2:10: +2:11
- _7 = _2; // scope 1 at $DIR/inline-closure.rs:+2:10: +2:11
- Deinit(_5); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
- (_5.0: i32) = move _6; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
- (_5.1: i32) = move _7; // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
- StorageLive(_8); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
- _8 = move (_5.0: i32); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
- StorageLive(_9); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
- _9 = move (_5.1: i32); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
- _0 = _8; // scope 2 at $DIR/inline-closure.rs:+1:22: +1:24
- StorageDead(_9); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
- StorageDead(_8); // scope 1 at $DIR/inline-closure.rs:+2:5: +2:12
- StorageDead(_7); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12
- StorageDead(_6); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12
- StorageDead(_5); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12
- StorageDead(_4); // scope 1 at $DIR/inline-closure.rs:+2:11: +2:12
- StorageDead(_3); // scope 0 at $DIR/inline-closure.rs:+3:1: +3:2
- return; // scope 0 at $DIR/inline-closure.rs:+3:2: +3:2
+ StorageLive(_3); // scope 0 at $DIR/inline_closure.rs:+1:9: +1:10
+ Deinit(_3); // scope 0 at $DIR/inline_closure.rs:+1:13: +1:24
+ StorageLive(_4); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:6
+ _4 = &_3; // scope 1 at $DIR/inline_closure.rs:+2:5: +2:6
+ StorageLive(_5); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12
+ StorageLive(_6); // scope 1 at $DIR/inline_closure.rs:+2:7: +2:8
+ _6 = _2; // scope 1 at $DIR/inline_closure.rs:+2:7: +2:8
+ StorageLive(_7); // scope 1 at $DIR/inline_closure.rs:+2:10: +2:11
+ _7 = _2; // scope 1 at $DIR/inline_closure.rs:+2:10: +2:11
+ Deinit(_5); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12
+ (_5.0: i32) = move _6; // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12
+ (_5.1: i32) = move _7; // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12
+ StorageLive(_8); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12
+ _8 = move (_5.0: i32); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12
+ StorageLive(_9); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12
+ _9 = move (_5.1: i32); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12
+ _0 = _8; // scope 2 at $DIR/inline_closure.rs:+1:22: +1:24
+ StorageDead(_9); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12
+ StorageDead(_8); // scope 1 at $DIR/inline_closure.rs:+2:5: +2:12
+ StorageDead(_7); // scope 1 at $DIR/inline_closure.rs:+2:11: +2:12
+ StorageDead(_6); // scope 1 at $DIR/inline_closure.rs:+2:11: +2:12
+ StorageDead(_5); // scope 1 at $DIR/inline_closure.rs:+2:11: +2:12
+ StorageDead(_4); // scope 1 at $DIR/inline_closure.rs:+2:11: +2:12
+ StorageDead(_3); // scope 0 at $DIR/inline_closure.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/inline_closure.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/inline/inline-closure.rs b/src/test/mir-opt/inline/inline_closure.rs
index 715fd0138..715fd0138 100644
--- a/src/test/mir-opt/inline/inline-closure.rs
+++ b/src/test/mir-opt/inline/inline_closure.rs
diff --git a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir
index 4069e9f89..dd32eb2d8 100644
--- a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir
@@ -1,56 +1,52 @@
// MIR for `foo` after Inline
fn foo(_1: T, _2: &i32) -> i32 {
- debug _t => _1; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:17: +0:19
- debug q => _2; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:24: +0:25
- let mut _0: i32; // return place in scope 0 at $DIR/inline-closure-borrows-arg.rs:+0:36: +0:39
- let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10
- let mut _4: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6
- let mut _5: (&i32, &i32); // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- let mut _6: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8
- let mut _7: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11
- let mut _8: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- let mut _9: &i32; // in scope 0 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
+ debug _t => _1; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+0:17: +0:19
+ debug q => _2; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+0:24: +0:25
+ let mut _0: i32; // return place in scope 0 at $DIR/inline_closure_borrows_arg.rs:+0:36: +0:39
+ let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+1:9: +1:10
+ let mut _4: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:6
+ let mut _5: (&i32, &i32); // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ let mut _6: &i32; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:7: +5:8
+ let mut _7: &i32; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:10: +5:11
+ let mut _8: &i32; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ let mut _9: &i32; // in scope 0 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
scope 1 {
- debug x => _3; // in scope 1 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10
- scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12
- debug r => _8; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+1:14: +1:15
- debug _s => _9; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+1:23: +1:25
- let _10: &i32; // in scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21
+ debug x => _3; // in scope 1 at $DIR/inline_closure_borrows_arg.rs:+1:9: +1:10
+ scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline_closure_borrows_arg.rs:16:5: 16:12
+ debug r => _8; // in scope 2 at $DIR/inline_closure_borrows_arg.rs:+1:14: +1:15
+ debug _s => _9; // in scope 2 at $DIR/inline_closure_borrows_arg.rs:+1:23: +1:25
scope 3 {
- debug variable => _10; // in scope 3 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21
+ debug variable => _8; // in scope 3 at $DIR/inline_closure_borrows_arg.rs:+2:13: +2:21
}
}
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:9: +1:10
- Deinit(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+1:13: +4:6
- StorageLive(_4); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6
- _4 = &_3; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:6
- StorageLive(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- StorageLive(_6); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8
- _6 = &(*_2); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:7: +5:8
- StorageLive(_7); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11
- _7 = &(*_2); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:10: +5:11
- Deinit(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- (_5.0: &i32) = move _6; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- (_5.1: &i32) = move _7; // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- StorageLive(_8); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- _8 = move (_5.0: &i32); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- StorageLive(_9); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- _9 = move (_5.1: &i32); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- StorageLive(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:13: +2:21
- _10 = _8; // scope 2 at $DIR/inline-closure-borrows-arg.rs:+2:24: +2:27
- _0 = (*_10); // scope 3 at $DIR/inline-closure-borrows-arg.rs:+3:9: +3:18
- StorageDead(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:+4:5: +4:6
- StorageDead(_9); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- StorageDead(_8); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:5: +5:12
- StorageDead(_7); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12
- StorageDead(_6); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12
- StorageDead(_5); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12
- StorageDead(_4); // scope 1 at $DIR/inline-closure-borrows-arg.rs:+5:11: +5:12
- StorageDead(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:+6:1: +6:2
- return; // scope 0 at $DIR/inline-closure-borrows-arg.rs:+6:2: +6:2
+ StorageLive(_3); // scope 0 at $DIR/inline_closure_borrows_arg.rs:+1:9: +1:10
+ Deinit(_3); // scope 0 at $DIR/inline_closure_borrows_arg.rs:+1:13: +4:6
+ StorageLive(_4); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:6
+ _4 = &_3; // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:6
+ StorageLive(_5); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ StorageLive(_6); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:7: +5:8
+ _6 = &(*_2); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:7: +5:8
+ StorageLive(_7); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:10: +5:11
+ _7 = &(*_2); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:10: +5:11
+ Deinit(_5); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ (_5.0: &i32) = move _6; // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ (_5.1: &i32) = move _7; // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ StorageLive(_8); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ _8 = move (_5.0: &i32); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ StorageLive(_9); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ _9 = move (_5.1: &i32); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ _0 = (*_8); // scope 3 at $DIR/inline_closure_borrows_arg.rs:+3:9: +3:18
+ StorageDead(_9); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ StorageDead(_8); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:5: +5:12
+ StorageDead(_7); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:11: +5:12
+ StorageDead(_6); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:11: +5:12
+ StorageDead(_5); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:11: +5:12
+ StorageDead(_4); // scope 1 at $DIR/inline_closure_borrows_arg.rs:+5:11: +5:12
+ StorageDead(_3); // scope 0 at $DIR/inline_closure_borrows_arg.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/inline_closure_borrows_arg.rs:+6:2: +6:2
}
}
diff --git a/src/test/mir-opt/inline/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline/inline_closure_borrows_arg.rs
index d76bc33f5..d76bc33f5 100644
--- a/src/test/mir-opt/inline/inline-closure-borrows-arg.rs
+++ b/src/test/mir-opt/inline/inline_closure_borrows_arg.rs
diff --git a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
index a2234e7c1..fd19c2886 100644
--- a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
@@ -1,65 +1,65 @@
// MIR for `foo` after Inline
fn foo(_1: T, _2: i32) -> (i32, T) {
- debug t => _1; // in scope 0 at $DIR/inline-closure-captures.rs:+0:17: +0:18
- debug q => _2; // in scope 0 at $DIR/inline-closure-captures.rs:+0:23: +0:24
- let mut _0: (i32, T); // return place in scope 0 at $DIR/inline-closure-captures.rs:+0:34: +0:42
- let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:+1:9: +1:10
- let mut _4: &i32; // in scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
- let mut _5: &T; // in scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
- let mut _6: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:6
- let mut _7: (i32,); // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:9
- let mut _8: i32; // in scope 0 at $DIR/inline-closure-captures.rs:+2:7: +2:8
- let mut _9: i32; // in scope 0 at $DIR/inline-closure-captures.rs:+2:5: +2:9
+ debug t => _1; // in scope 0 at $DIR/inline_closure_captures.rs:+0:17: +0:18
+ debug q => _2; // in scope 0 at $DIR/inline_closure_captures.rs:+0:23: +0:24
+ let mut _0: (i32, T); // return place in scope 0 at $DIR/inline_closure_captures.rs:+0:34: +0:42
+ let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline_closure_captures.rs:+1:9: +1:10
+ let mut _4: &i32; // in scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ let mut _5: &T; // in scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ let mut _6: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline_closure_captures.rs:+2:5: +2:6
+ let mut _7: (i32,); // in scope 0 at $DIR/inline_closure_captures.rs:+2:5: +2:9
+ let mut _8: i32; // in scope 0 at $DIR/inline_closure_captures.rs:+2:7: +2:8
+ let mut _9: i32; // in scope 0 at $DIR/inline_closure_captures.rs:+2:5: +2:9
scope 1 {
- debug x => _3; // in scope 1 at $DIR/inline-closure-captures.rs:+1:9: +1:10
- scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline-closure-captures.rs:12:5: 12:9
- debug _q => _9; // in scope 2 at $DIR/inline-closure-captures.rs:+1:14: +1:16
- debug q => (*((*_6).0: &i32)); // in scope 2 at $DIR/inline-closure-captures.rs:+0:23: +0:24
- debug t => (*((*_6).1: &T)); // in scope 2 at $DIR/inline-closure-captures.rs:+0:17: +0:18
- let mut _10: i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
- let mut _11: T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
- let mut _12: &i32; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:24
- let mut _13: &T; // in scope 2 at $DIR/inline-closure-captures.rs:+1:13: +1:24
+ debug x => _3; // in scope 1 at $DIR/inline_closure_captures.rs:+1:9: +1:10
+ scope 2 (inlined foo::<T>::{closure#0}) { // at $DIR/inline_closure_captures.rs:12:5: 12:9
+ debug _q => _9; // in scope 2 at $DIR/inline_closure_captures.rs:+1:14: +1:16
+ debug q => (*((*_6).0: &i32)); // in scope 2 at $DIR/inline_closure_captures.rs:+0:23: +0:24
+ debug t => (*((*_6).1: &T)); // in scope 2 at $DIR/inline_closure_captures.rs:+0:17: +0:18
+ let mut _10: i32; // in scope 2 at $DIR/inline_closure_captures.rs:+1:19: +1:20
+ let mut _11: T; // in scope 2 at $DIR/inline_closure_captures.rs:+1:22: +1:23
+ let mut _12: &i32; // in scope 2 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ let mut _13: &T; // in scope 2 at $DIR/inline_closure_captures.rs:+1:13: +1:24
}
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/inline-closure-captures.rs:+1:9: +1:10
- StorageLive(_4); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
- _4 = &_2; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
- StorageLive(_5); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
- _5 = &_1; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
- Deinit(_3); // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
- (_3.0: &i32) = move _4; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
- (_3.1: &T) = move _5; // scope 0 at $DIR/inline-closure-captures.rs:+1:13: +1:24
- StorageDead(_5); // scope 0 at $DIR/inline-closure-captures.rs:+1:16: +1:17
- StorageDead(_4); // scope 0 at $DIR/inline-closure-captures.rs:+1:16: +1:17
- StorageLive(_6); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:6
- _6 = &_3; // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:6
- StorageLive(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
- StorageLive(_8); // scope 1 at $DIR/inline-closure-captures.rs:+2:7: +2:8
- _8 = _2; // scope 1 at $DIR/inline-closure-captures.rs:+2:7: +2:8
- Deinit(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
- (_7.0: i32) = move _8; // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
- StorageLive(_9); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
- _9 = move (_7.0: i32); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
- StorageLive(_10); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
- _12 = deref_copy ((*_6).0: &i32); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
- _10 = (*_12); // scope 2 at $DIR/inline-closure-captures.rs:+1:19: +1:20
- StorageLive(_11); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
- _13 = deref_copy ((*_6).1: &T); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
- _11 = (*_13); // scope 2 at $DIR/inline-closure-captures.rs:+1:22: +1:23
- Deinit(_0); // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
- (_0.0: i32) = move _10; // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
- (_0.1: T) = move _11; // scope 2 at $DIR/inline-closure-captures.rs:+1:18: +1:24
- StorageDead(_11); // scope 2 at $DIR/inline-closure-captures.rs:+1:23: +1:24
- StorageDead(_10); // scope 2 at $DIR/inline-closure-captures.rs:+1:23: +1:24
- StorageDead(_9); // scope 1 at $DIR/inline-closure-captures.rs:+2:5: +2:9
- StorageDead(_8); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9
- StorageDead(_7); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9
- StorageDead(_6); // scope 1 at $DIR/inline-closure-captures.rs:+2:8: +2:9
- StorageDead(_3); // scope 0 at $DIR/inline-closure-captures.rs:+3:1: +3:2
- return; // scope 0 at $DIR/inline-closure-captures.rs:+3:2: +3:2
+ StorageLive(_3); // scope 0 at $DIR/inline_closure_captures.rs:+1:9: +1:10
+ StorageLive(_4); // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ _4 = &_2; // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ StorageLive(_5); // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ _5 = &_1; // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ Deinit(_3); // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ (_3.0: &i32) = move _4; // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ (_3.1: &T) = move _5; // scope 0 at $DIR/inline_closure_captures.rs:+1:13: +1:24
+ StorageDead(_5); // scope 0 at $DIR/inline_closure_captures.rs:+1:16: +1:17
+ StorageDead(_4); // scope 0 at $DIR/inline_closure_captures.rs:+1:16: +1:17
+ StorageLive(_6); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:6
+ _6 = &_3; // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:6
+ StorageLive(_7); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9
+ StorageLive(_8); // scope 1 at $DIR/inline_closure_captures.rs:+2:7: +2:8
+ _8 = _2; // scope 1 at $DIR/inline_closure_captures.rs:+2:7: +2:8
+ Deinit(_7); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9
+ (_7.0: i32) = move _8; // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9
+ StorageLive(_9); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9
+ _9 = move (_7.0: i32); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9
+ StorageLive(_10); // scope 2 at $DIR/inline_closure_captures.rs:+1:19: +1:20
+ _12 = deref_copy ((*_6).0: &i32); // scope 2 at $DIR/inline_closure_captures.rs:+1:19: +1:20
+ _10 = (*_12); // scope 2 at $DIR/inline_closure_captures.rs:+1:19: +1:20
+ StorageLive(_11); // scope 2 at $DIR/inline_closure_captures.rs:+1:22: +1:23
+ _13 = deref_copy ((*_6).1: &T); // scope 2 at $DIR/inline_closure_captures.rs:+1:22: +1:23
+ _11 = (*_13); // scope 2 at $DIR/inline_closure_captures.rs:+1:22: +1:23
+ Deinit(_0); // scope 2 at $DIR/inline_closure_captures.rs:+1:18: +1:24
+ (_0.0: i32) = move _10; // scope 2 at $DIR/inline_closure_captures.rs:+1:18: +1:24
+ (_0.1: T) = move _11; // scope 2 at $DIR/inline_closure_captures.rs:+1:18: +1:24
+ StorageDead(_11); // scope 2 at $DIR/inline_closure_captures.rs:+1:23: +1:24
+ StorageDead(_10); // scope 2 at $DIR/inline_closure_captures.rs:+1:23: +1:24
+ StorageDead(_9); // scope 1 at $DIR/inline_closure_captures.rs:+2:5: +2:9
+ StorageDead(_8); // scope 1 at $DIR/inline_closure_captures.rs:+2:8: +2:9
+ StorageDead(_7); // scope 1 at $DIR/inline_closure_captures.rs:+2:8: +2:9
+ StorageDead(_6); // scope 1 at $DIR/inline_closure_captures.rs:+2:8: +2:9
+ StorageDead(_3); // scope 0 at $DIR/inline_closure_captures.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/inline_closure_captures.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/inline/inline-closure-captures.rs b/src/test/mir-opt/inline/inline_closure_captures.rs
index 52b6817e4..52b6817e4 100644
--- a/src/test/mir-opt/inline/inline-closure-captures.rs
+++ b/src/test/mir-opt/inline/inline_closure_captures.rs
diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff
index cf800ba11..e30a5e116 100644
--- a/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff
+++ b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff
@@ -2,23 +2,23 @@
+ // MIR for `inlined_no_sanitize` after Inline
fn inlined_no_sanitize() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:37: +0:37
- let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
-+ scope 1 (inlined no_sanitize) { // at $DIR/inline-compatibility.rs:24:5: 24:18
+ let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:37: +0:37
+ let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18
++ scope 1 (inlined no_sanitize) { // at $DIR/inline_compatibility.rs:24:5: 24:18
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
-- _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
+ StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18
+- _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18
- // mir::Constant
-- // + span: $DIR/inline-compatibility.rs:24:5: 24:16
+- // + span: $DIR/inline_compatibility.rs:24:5: 24:16
- // + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value(<ZST>) }
- }
-
- bb1: {
- StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:18: +1:19
- _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:37: +2:2
- return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:18: +1:19
+ _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:37: +2:2
+ return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff
index a45f95902..c2b3c46a3 100644
--- a/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff
+++ b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff
@@ -2,23 +2,23 @@
+ // MIR for `inlined_target_feature` after Inline
fn inlined_target_feature() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:40: +0:40
- let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
-+ scope 1 (inlined target_feature) { // at $DIR/inline-compatibility.rs:13:5: 13:21
+ let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:40: +0:40
+ let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21
++ scope 1 (inlined target_feature) { // at $DIR/inline_compatibility.rs:13:5: 13:21
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
-- _1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
+ StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21
+- _1 = target_feature() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21
- // mir::Constant
-- // + span: $DIR/inline-compatibility.rs:13:5: 13:19
+- // + span: $DIR/inline_compatibility.rs:13:5: 13:19
- // + literal: Const { ty: unsafe fn() {target_feature}, val: Value(<ZST>) }
- }
-
- bb1: {
- StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:21: +1:22
- _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:40: +2:2
- return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:21: +1:22
+ _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:40: +2:2
+ return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff
index 49aea431e..0ca5a5f70 100644
--- a/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff
+++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_c_variadic.Inline.diff
@@ -2,24 +2,24 @@
+ // MIR for `not_inlined_c_variadic` after Inline
fn not_inlined_c_variadic() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:40: +0:40
- let _1: u32; // in scope 0 at $DIR/inline-compatibility.rs:+1:9: +1:10
+ let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:40: +0:40
+ let _1: u32; // in scope 0 at $DIR/inline_compatibility.rs:+1:9: +1:10
scope 1 {
- debug s => _1; // in scope 1 at $DIR/inline-compatibility.rs:+1:9: +1:10
+ debug s => _1; // in scope 1 at $DIR/inline_compatibility.rs:+1:9: +1:10
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:9: +1:10
- _1 = sum(const 4_u32, const 4_u32, const 30_u32, const 200_u32, const 1000_u32) -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:13: +1:52
+ StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:9: +1:10
+ _1 = sum(const 4_u32, const 4_u32, const 30_u32, const 200_u32, const 1000_u32) -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:13: +1:52
// mir::Constant
- // + span: $DIR/inline-compatibility.rs:42:13: 42:16
+ // + span: $DIR/inline_compatibility.rs:42:13: 42:16
// + literal: Const { ty: unsafe extern "C" fn(u32, ...) -> u32 {sum}, val: Value(<ZST>) }
}
bb1: {
- _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:40: +2:2
- StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+2:1: +2:2
- return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2
+ _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:40: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff
index 94ce574a9..00d405c77 100644
--- a/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff
+++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_no_sanitize.Inline.diff
@@ -2,21 +2,21 @@
+ // MIR for `not_inlined_no_sanitize` after Inline
fn not_inlined_no_sanitize() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:41: +0:41
- let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
+ let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:41: +0:41
+ let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
- _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:18
+ StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18
+ _1 = no_sanitize() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:18
// mir::Constant
- // + span: $DIR/inline-compatibility.rs:29:5: 29:16
+ // + span: $DIR/inline_compatibility.rs:29:5: 29:16
// + literal: Const { ty: unsafe fn() {no_sanitize}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:18: +1:19
- _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:41: +2:2
- return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:18: +1:19
+ _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:41: +2:2
+ return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff
index 8506e257b..8b9c86f55 100644
--- a/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff
+++ b/src/test/mir-opt/inline/inline_compatibility.not_inlined_target_feature.Inline.diff
@@ -2,21 +2,21 @@
+ // MIR for `not_inlined_target_feature` after Inline
fn not_inlined_target_feature() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-compatibility.rs:+0:44: +0:44
- let _1: (); // in scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
+ let mut _0: (); // return place in scope 0 at $DIR/inline_compatibility.rs:+0:44: +0:44
+ let _1: (); // in scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
- _1 = target_feature() -> bb1; // scope 0 at $DIR/inline-compatibility.rs:+1:5: +1:21
+ StorageLive(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21
+ _1 = target_feature() -> bb1; // scope 0 at $DIR/inline_compatibility.rs:+1:5: +1:21
// mir::Constant
- // + span: $DIR/inline-compatibility.rs:18:5: 18:19
+ // + span: $DIR/inline_compatibility.rs:18:5: 18:19
// + literal: Const { ty: unsafe fn() {target_feature}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:+1:21: +1:22
- _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:+0:44: +2:2
- return; // scope 0 at $DIR/inline-compatibility.rs:+2:2: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_compatibility.rs:+1:21: +1:22
+ _0 = const (); // scope 0 at $DIR/inline_compatibility.rs:+0:44: +2:2
+ return; // scope 0 at $DIR/inline_compatibility.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline-compatibility.rs b/src/test/mir-opt/inline/inline_compatibility.rs
index 30aff0a64..30aff0a64 100644
--- a/src/test/mir-opt/inline/inline-compatibility.rs
+++ b/src/test/mir-opt/inline/inline_compatibility.rs
diff --git a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff
index a4d706de0..f54a1a747 100644
--- a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff
+++ b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff
@@ -2,29 +2,26 @@
+ // MIR for `one` after Inline
fn one() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-cycle.rs:+0:10: +0:10
- let _1: (); // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24
-+ scope 1 (inlined <C as Call>::call) { // at $DIR/inline-cycle.rs:14:5: 14:24
-+ scope 2 (inlined <A<C> as Call>::call) { // at $DIR/inline-cycle.rs:43:9: 43:23
-+ scope 3 (inlined <B<C> as Call>::call) { // at $DIR/inline-cycle.rs:28:9: 28:31
-+ }
-+ }
+ let mut _0: (); // return place in scope 0 at $DIR/inline_cycle.rs:+0:10: +0:10
+ let _1: (); // in scope 0 at $DIR/inline_cycle.rs:+1:5: +1:24
++ scope 1 (inlined <C as Call>::call) { // at $DIR/inline_cycle.rs:14:5: 14:24
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24
-- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:24
-+ _1 = <C as Call>::call() -> bb1; // scope 3 at $DIR/inline-cycle.rs:36:9: 36:28
+ StorageLive(_1); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:24
+- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:24
++ _1 = <A<C> as Call>::call() -> bb1; // scope 1 at $DIR/inline_cycle.rs:43:9: 43:23
// mir::Constant
-- // + span: $DIR/inline-cycle.rs:14:5: 14:22
-+ // + span: $DIR/inline-cycle.rs:36:9: 36:26
- // + literal: Const { ty: fn() {<C as Call>::call}, val: Value(<ZST>) }
+- // + span: $DIR/inline_cycle.rs:14:5: 14:22
+- // + literal: Const { ty: fn() {<C as Call>::call}, val: Value(<ZST>) }
++ // + span: $DIR/inline_cycle.rs:43:9: 43:21
++ // + literal: Const { ty: fn() {<A<C> as Call>::call}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:+1:24: +1:25
- _0 = const (); // scope 0 at $DIR/inline-cycle.rs:+0:10: +2:2
- return; // scope 0 at $DIR/inline-cycle.rs:+2:2: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_cycle.rs:+1:24: +1:25
+ _0 = const (); // scope 0 at $DIR/inline_cycle.rs:+0:10: +2:2
+ return; // scope 0 at $DIR/inline_cycle.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline-cycle.rs b/src/test/mir-opt/inline/inline_cycle.rs
index 63ad57de1..63ad57de1 100644
--- a/src/test/mir-opt/inline/inline-cycle.rs
+++ b/src/test/mir-opt/inline/inline_cycle.rs
diff --git a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff
index b1a5b62ef..a940848c2 100644
--- a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff
+++ b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff
@@ -2,54 +2,41 @@
+ // MIR for `two` after Inline
fn two() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-cycle.rs:+0:10: +0:10
- let _1: (); // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
-+ let mut _2: fn() {f}; // in scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
-+ scope 1 (inlined call::<fn() {f}>) { // at $DIR/inline-cycle.rs:49:5: 49:12
-+ debug f => _2; // in scope 1 at $DIR/inline-cycle.rs:53:22: 53:23
-+ let _3: (); // in scope 1 at $DIR/inline-cycle.rs:54:5: 54:8
-+ let mut _4: fn() {f}; // in scope 1 at $DIR/inline-cycle.rs:54:5: 54:6
-+ let mut _5: (); // in scope 1 at $DIR/inline-cycle.rs:54:5: 54:8
-+ scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) { // at $DIR/inline-cycle.rs:54:5: 54:8
-+ scope 3 (inlined f) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
-+ let _6: (); // in scope 3 at $DIR/inline-cycle.rs:59:5: 59:12
-+ }
-+ }
+ let mut _0: (); // return place in scope 0 at $DIR/inline_cycle.rs:+0:10: +0:10
+ let _1: (); // in scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12
++ let mut _2: fn() {f}; // in scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12
++ scope 1 (inlined call::<fn() {f}>) { // at $DIR/inline_cycle.rs:49:5: 49:12
++ debug f => _2; // in scope 1 at $DIR/inline_cycle.rs:53:22: 53:23
++ let _3: (); // in scope 1 at $DIR/inline_cycle.rs:54:5: 54:8
++ let mut _4: (); // in scope 1 at $DIR/inline_cycle.rs:54:5: 54:8
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
-- _1 = call::<fn() {f}>(f) -> bb1; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
-+ StorageLive(_2); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
-+ _2 = f; // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
+ StorageLive(_1); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12
+- _1 = call::<fn() {f}>(f) -> bb1; // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12
++ StorageLive(_2); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12
++ _2 = f; // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12
// mir::Constant
-- // + span: $DIR/inline-cycle.rs:49:5: 49:9
-+ // + span: $DIR/inline-cycle.rs:49:10: 49:11
-+ // + literal: Const { ty: fn() {f}, val: Value(<ZST>) }
-+ StorageLive(_3); // scope 1 at $DIR/inline-cycle.rs:54:5: 54:8
-+ StorageLive(_4); // scope 1 at $DIR/inline-cycle.rs:54:5: 54:6
-+ _4 = move _2; // scope 1 at $DIR/inline-cycle.rs:54:5: 54:6
-+ StorageLive(_5); // scope 1 at $DIR/inline-cycle.rs:54:5: 54:8
-+ StorageLive(_6); // scope 3 at $DIR/inline-cycle.rs:59:5: 59:12
-+ _6 = call::<fn() {f}>(f) -> bb1; // scope 3 at $DIR/inline-cycle.rs:59:5: 59:12
-+ // mir::Constant
-+ // + span: $DIR/inline-cycle.rs:59:5: 59:9
- // + literal: Const { ty: fn(fn() {f}) {call::<fn() {f}>}, val: Value(<ZST>) }
- // mir::Constant
-- // + span: $DIR/inline-cycle.rs:49:10: 49:11
-+ // + span: $DIR/inline-cycle.rs:59:10: 59:11
+- // + span: $DIR/inline_cycle.rs:49:5: 49:9
+- // + literal: Const { ty: fn(fn() {f}) {call::<fn() {f}>}, val: Value(<ZST>) }
+- // mir::Constant
+ // + span: $DIR/inline_cycle.rs:49:10: 49:11
// + literal: Const { ty: fn() {f}, val: Value(<ZST>) }
++ StorageLive(_3); // scope 1 at $DIR/inline_cycle.rs:54:5: 54:8
++ StorageLive(_4); // scope 1 at $DIR/inline_cycle.rs:54:5: 54:8
++ _3 = <fn() {f} as FnOnce<()>>::call_once(move _2, move _4) -> bb1; // scope 1 at $DIR/inline_cycle.rs:54:5: 54:8
++ // mir::Constant
++ // + span: $DIR/inline_cycle.rs:54:5: 54:6
++ // + literal: Const { ty: extern "rust-call" fn(fn() {f}, ()) -> <fn() {f} as FnOnce<()>>::Output {<fn() {f} as FnOnce<()>>::call_once}, val: Value(<ZST>) }
}
bb1: {
-+ StorageDead(_6); // scope 3 at $DIR/inline-cycle.rs:59:12: 59:13
-+ StorageDead(_5); // scope 1 at $DIR/inline-cycle.rs:54:7: 54:8
-+ StorageDead(_4); // scope 1 at $DIR/inline-cycle.rs:54:7: 54:8
-+ StorageDead(_3); // scope 1 at $DIR/inline-cycle.rs:54:8: 54:9
-+ StorageDead(_2); // scope 0 at $DIR/inline-cycle.rs:+1:5: +1:12
- StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:+1:12: +1:13
- _0 = const (); // scope 0 at $DIR/inline-cycle.rs:+0:10: +2:2
- return; // scope 0 at $DIR/inline-cycle.rs:+2:2: +2:2
++ StorageDead(_4); // scope 1 at $DIR/inline_cycle.rs:54:7: 54:8
++ StorageDead(_3); // scope 1 at $DIR/inline_cycle.rs:54:8: 54:9
++ StorageDead(_2); // scope 0 at $DIR/inline_cycle.rs:+1:5: +1:12
+ StorageDead(_1); // scope 0 at $DIR/inline_cycle.rs:+1:12: +1:13
+ _0 = const (); // scope 0 at $DIR/inline_cycle.rs:+0:10: +2:2
+ return; // scope 0 at $DIR/inline_cycle.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff
index fc5d57ce8..04de3e61e 100644
--- a/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline_cycle_generic.main.Inline.diff
@@ -2,31 +2,28 @@
+ // MIR for `main` after Inline
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-cycle-generic.rs:+0:11: +0:11
- let _1: (); // in scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24
-+ scope 1 (inlined <C as Call>::call) { // at $DIR/inline-cycle-generic.rs:9:5: 9:24
-+ scope 2 (inlined <B<A> as Call>::call) { // at $DIR/inline-cycle-generic.rs:38:9: 38:31
-+ scope 3 (inlined <A as Call>::call) { // at $DIR/inline-cycle-generic.rs:31:9: 31:28
-+ scope 4 (inlined <B<C> as Call>::call) { // at $DIR/inline-cycle-generic.rs:23:9: 23:31
-+ }
-+ }
+ let mut _0: (); // return place in scope 0 at $DIR/inline_cycle_generic.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/inline_cycle_generic.rs:+1:5: +1:24
++ scope 1 (inlined <C as Call>::call) { // at $DIR/inline_cycle_generic.rs:9:5: 9:24
++ scope 2 (inlined <B<A> as Call>::call) { // at $DIR/inline_cycle_generic.rs:38:9: 38:31
+ }
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24
-- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline-cycle-generic.rs:+1:5: +1:24
-+ _1 = <C as Call>::call() -> bb1; // scope 4 at $DIR/inline-cycle-generic.rs:31:9: 31:28
+ StorageLive(_1); // scope 0 at $DIR/inline_cycle_generic.rs:+1:5: +1:24
+- _1 = <C as Call>::call() -> bb1; // scope 0 at $DIR/inline_cycle_generic.rs:+1:5: +1:24
++ _1 = <A as Call>::call() -> bb1; // scope 2 at $DIR/inline_cycle_generic.rs:31:9: 31:28
// mir::Constant
-- // + span: $DIR/inline-cycle-generic.rs:9:5: 9:22
-+ // + span: $DIR/inline-cycle-generic.rs:31:9: 31:26
- // + literal: Const { ty: fn() {<C as Call>::call}, val: Value(<ZST>) }
+- // + span: $DIR/inline_cycle_generic.rs:9:5: 9:22
+- // + literal: Const { ty: fn() {<C as Call>::call}, val: Value(<ZST>) }
++ // + span: $DIR/inline_cycle_generic.rs:31:9: 31:26
++ // + literal: Const { ty: fn() {<A as Call>::call}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_1); // scope 0 at $DIR/inline-cycle-generic.rs:+1:24: +1:25
- _0 = const (); // scope 0 at $DIR/inline-cycle-generic.rs:+0:11: +2:2
- return; // scope 0 at $DIR/inline-cycle-generic.rs:+2:2: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_cycle_generic.rs:+1:24: +1:25
+ _0 = const (); // scope 0 at $DIR/inline_cycle_generic.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/inline_cycle_generic.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline-cycle-generic.rs b/src/test/mir-opt/inline/inline_cycle_generic.rs
index 24b4f3793..24b4f3793 100644
--- a/src/test/mir-opt/inline/inline-cycle-generic.rs
+++ b/src/test/mir-opt/inline/inline_cycle_generic.rs
diff --git a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff
index cef4cfc67..b49191f49 100644
--- a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff
+++ b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff
@@ -2,23 +2,23 @@
+ // MIR for `f` after Inline
fn f() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:+0:12: +0:12
- let mut _1: !; // in scope 0 at $DIR/inline-diverging.rs:+0:12: +2:2
- let _2: !; // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12
-+ scope 1 (inlined sleep) { // at $DIR/inline-diverging.rs:8:5: 8:12
+ let mut _0: (); // return place in scope 0 at $DIR/inline_diverging.rs:+0:12: +0:12
+ let mut _1: !; // in scope 0 at $DIR/inline_diverging.rs:+0:12: +2:2
+ let _2: !; // in scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12
++ scope 1 (inlined sleep) { // at $DIR/inline_diverging.rs:8:5: 8:12
+ }
bb0: {
- StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12
-- _2 = sleep(); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12
+ StorageLive(_2); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12
+- _2 = sleep(); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12
- // mir::Constant
-- // + span: $DIR/inline-diverging.rs:8:5: 8:10
+- // + span: $DIR/inline_diverging.rs:8:5: 8:10
- // + literal: Const { ty: fn() -> ! {sleep}, val: Value(<ZST>) }
-+ goto -> bb1; // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:12
++ goto -> bb1; // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:12
+ }
+
+ bb1: {
-+ goto -> bb1; // scope 1 at $DIR/inline-diverging.rs:39:5: 39:12
++ goto -> bb1; // scope 1 at $DIR/inline_diverging.rs:39:5: 39:12
}
}
diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff
index a71baad3e..1e703a8fd 100644
--- a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff
+++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff
@@ -2,42 +2,42 @@
+ // MIR for `g` after Inline
fn g(_1: i32) -> u32 {
- debug i => _1; // in scope 0 at $DIR/inline-diverging.rs:+0:10: +0:11
- let mut _0: u32; // return place in scope 0 at $DIR/inline-diverging.rs:+0:21: +0:24
- let mut _2: bool; // in scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13
- let mut _3: i32; // in scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9
- let mut _4: i32; // in scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10
- let mut _5: !; // in scope 0 at $DIR/inline-diverging.rs:+3:12: +5:6
- let _6: !; // in scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16
-+ scope 1 (inlined panic) { // at $DIR/inline-diverging.rs:16:9: 16:16
+ debug i => _1; // in scope 0 at $DIR/inline_diverging.rs:+0:10: +0:11
+ let mut _0: u32; // return place in scope 0 at $DIR/inline_diverging.rs:+0:21: +0:24
+ let mut _2: bool; // in scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13
+ let mut _3: i32; // in scope 0 at $DIR/inline_diverging.rs:+1:8: +1:9
+ let mut _4: i32; // in scope 0 at $DIR/inline_diverging.rs:+2:9: +2:10
+ let mut _5: !; // in scope 0 at $DIR/inline_diverging.rs:+3:12: +5:6
+ let _6: !; // in scope 0 at $DIR/inline_diverging.rs:+4:9: +4:16
++ scope 1 (inlined panic) { // at $DIR/inline_diverging.rs:16:9: 16:16
+ let mut _7: !; // in scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ }
bb0: {
- StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13
- StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9
- _3 = _1; // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:9
- _2 = Gt(move _3, const 0_i32); // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13
- StorageDead(_3); // scope 0 at $DIR/inline-diverging.rs:+1:12: +1:13
- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/inline-diverging.rs:+1:8: +1:13
+ StorageLive(_2); // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13
+ StorageLive(_3); // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:9
+ _3 = _1; // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:9
+ _2 = Gt(move _3, const 0_i32); // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13
+ StorageDead(_3); // scope 0 at $DIR/inline_diverging.rs:+1:12: +1:13
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/inline_diverging.rs:+1:8: +1:13
}
bb1: {
- StorageLive(_4); // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10
- _4 = _1; // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:10
- _0 = move _4 as u32 (IntToInt); // scope 0 at $DIR/inline-diverging.rs:+2:9: +2:17
- StorageDead(_4); // scope 0 at $DIR/inline-diverging.rs:+2:16: +2:17
- StorageDead(_2); // scope 0 at $DIR/inline-diverging.rs:+5:5: +5:6
- return; // scope 0 at $DIR/inline-diverging.rs:+6:2: +6:2
+ StorageLive(_4); // scope 0 at $DIR/inline_diverging.rs:+2:9: +2:10
+ _4 = _1; // scope 0 at $DIR/inline_diverging.rs:+2:9: +2:10
+ _0 = move _4 as u32 (IntToInt); // scope 0 at $DIR/inline_diverging.rs:+2:9: +2:17
+ StorageDead(_4); // scope 0 at $DIR/inline_diverging.rs:+2:16: +2:17
+ StorageDead(_2); // scope 0 at $DIR/inline_diverging.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/inline_diverging.rs:+6:2: +6:2
}
bb2: {
- StorageLive(_6); // scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16
-- _6 = panic(); // scope 0 at $DIR/inline-diverging.rs:+4:9: +4:16
+ StorageLive(_6); // scope 0 at $DIR/inline_diverging.rs:+4:9: +4:16
+- _6 = panic(); // scope 0 at $DIR/inline_diverging.rs:+4:9: +4:16
+ StorageLive(_7); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
+ _7 = begin_panic::<&str>(const "explicit panic"); // scope 1 at $SRC_DIR/std/src/panic.rs:LL:COL
// mir::Constant
-- // + span: $DIR/inline-diverging.rs:16:9: 16:14
+- // + span: $DIR/inline_diverging.rs:16:9: 16:14
- // + literal: Const { ty: fn() -> ! {panic}, val: Value(<ZST>) }
+ // + span: $SRC_DIR/std/src/panic.rs:LL:COL
+ // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(<ZST>) }
diff --git a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
index 6569ab24c..a01bcf164 100644
--- a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
+++ b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
@@ -2,55 +2,87 @@
+ // MIR for `h` after Inline
fn h() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:+0:12: +0:12
- let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
-+ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
-+ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22
-+ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:26:36: 26:37
-+ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:27:9: 27:10
-+ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
-+ let mut _5: (); // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:16
-+ let mut _7: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:14
-+ let mut _8: (); // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:16
-+ let mut _9: !; // in scope 1 at $DIR/inline-diverging.rs:29:6: 29:7
-+ let mut _10: !; // in scope 1 at $DIR/inline-diverging.rs:29:9: 29:10
+ let mut _0: (); // return place in scope 0 at $DIR/inline_diverging.rs:+0:12: +0:12
+ let _1: (!, !); // in scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22
++ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22
++ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { // at $DIR/inline_diverging.rs:22:5: 22:22
++ debug f => _2; // in scope 1 at $DIR/inline_diverging.rs:26:36: 26:37
++ let _3: !; // in scope 1 at $DIR/inline_diverging.rs:27:9: 27:10
++ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline_diverging.rs:27:13: 27:14
++ let mut _5: (); // in scope 1 at $DIR/inline_diverging.rs:27:13: 27:16
++ let mut _6: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline_diverging.rs:28:13: 28:14
++ let mut _7: (); // in scope 1 at $DIR/inline_diverging.rs:28:13: 28:16
++ let mut _8: !; // in scope 1 at $DIR/inline_diverging.rs:29:6: 29:7
++ let mut _9: !; // in scope 1 at $DIR/inline_diverging.rs:29:9: 29:10
+ scope 2 {
-+ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:27:9: 27:10
-+ let _6: !; // in scope 2 at $DIR/inline-diverging.rs:28:9: 28:10
++ debug a => _3; // in scope 2 at $DIR/inline_diverging.rs:27:9: 27:10
+ scope 3 {
-+ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:28:9: 28:10
-+ }
-+ scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:28:13: 28:16
-+ scope 7 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
-+ }
-+ }
-+ }
-+ scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:27:13: 27:16
-+ scope 5 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
++ debug b => _9; // in scope 3 at $DIR/inline_diverging.rs:28:9: 28:10
+ }
+ }
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
-- _1 = call_twice::<!, fn() -> ! {sleep}>(sleep); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
-+ StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
-+ _2 = sleep; // scope 0 at $DIR/inline-diverging.rs:+1:5: +1:22
+ StorageLive(_1); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22
+- _1 = call_twice::<!, fn() -> ! {sleep}>(sleep); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22
++ StorageLive(_2); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22
++ _2 = sleep; // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22
// mir::Constant
-- // + span: $DIR/inline-diverging.rs:22:5: 22:15
+- // + span: $DIR/inline_diverging.rs:22:5: 22:15
- // + literal: Const { ty: fn(fn() -> ! {sleep}) -> (!, !) {call_twice::<!, fn() -> ! {sleep}>}, val: Value(<ZST>) }
- // mir::Constant
- // + span: $DIR/inline-diverging.rs:22:16: 22:21
+ // + span: $DIR/inline_diverging.rs:22:16: 22:21
// + literal: Const { ty: fn() -> ! {sleep}, val: Value(<ZST>) }
-+ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:27:9: 27:10
-+ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
-+ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
-+ StorageLive(_5); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16
-+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12
++ StorageLive(_9); // scope 0 at $DIR/inline_diverging.rs:+1:5: +1:22
++ StorageLive(_3); // scope 1 at $DIR/inline_diverging.rs:27:9: 27:10
++ StorageLive(_4); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:14
++ _4 = &_2; // scope 1 at $DIR/inline_diverging.rs:27:13: 27:14
++ StorageLive(_5); // scope 1 at $DIR/inline_diverging.rs:27:13: 27:16
++ _3 = <fn() -> ! {sleep} as Fn<()>>::call(move _4, move _5) -> [return: bb1, unwind: bb5]; // scope 1 at $DIR/inline_diverging.rs:27:13: 27:16
++ // mir::Constant
++ // + span: $DIR/inline_diverging.rs:27:13: 27:14
++ // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() -> ! {sleep}, ()) -> <fn() -> ! {sleep} as FnOnce<()>>::Output {<fn() -> ! {sleep} as Fn<()>>::call}, val: Value(<ZST>) }
+ }
+
+ bb1: {
-+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12
++ StorageDead(_5); // scope 1 at $DIR/inline_diverging.rs:27:15: 27:16
++ StorageDead(_4); // scope 1 at $DIR/inline_diverging.rs:27:15: 27:16
++ StorageLive(_6); // scope 2 at $DIR/inline_diverging.rs:28:13: 28:14
++ _6 = &_2; // scope 2 at $DIR/inline_diverging.rs:28:13: 28:14
++ StorageLive(_7); // scope 2 at $DIR/inline_diverging.rs:28:13: 28:16
++ _9 = <fn() -> ! {sleep} as Fn<()>>::call(move _6, move _7) -> [return: bb2, unwind: bb4]; // scope 2 at $DIR/inline_diverging.rs:28:13: 28:16
++ // mir::Constant
++ // + span: $DIR/inline_diverging.rs:28:13: 28:14
++ // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() -> ! {sleep}, ()) -> <fn() -> ! {sleep} as FnOnce<()>>::Output {<fn() -> ! {sleep} as Fn<()>>::call}, val: Value(<ZST>) }
++ }
++
++ bb2: {
++ StorageDead(_7); // scope 2 at $DIR/inline_diverging.rs:28:15: 28:16
++ StorageDead(_6); // scope 2 at $DIR/inline_diverging.rs:28:15: 28:16
++ StorageLive(_8); // scope 3 at $DIR/inline_diverging.rs:29:6: 29:7
++ _8 = move _3; // scope 3 at $DIR/inline_diverging.rs:29:6: 29:7
++ Deinit(_1); // scope 3 at $DIR/inline_diverging.rs:29:5: 29:11
++ (_1.0: !) = move _8; // scope 3 at $DIR/inline_diverging.rs:29:5: 29:11
++ (_1.1: !) = move _9; // scope 3 at $DIR/inline_diverging.rs:29:5: 29:11
++ StorageDead(_8); // scope 3 at $DIR/inline_diverging.rs:29:10: 29:11
++ StorageDead(_3); // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2
++ drop(_2) -> bb3; // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2
++ }
++
++ bb3: {
++ unreachable; // scope 0 at $DIR/inline_diverging.rs:30:2: 30:2
++ }
++
++ bb4 (cleanup): {
++ drop(_3) -> bb5; // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2
++ }
++
++ bb5 (cleanup): {
++ drop(_2) -> bb6; // scope 1 at $DIR/inline_diverging.rs:30:1: 30:2
++ }
++
++ bb6 (cleanup): {
++ resume; // scope 1 at $DIR/inline_diverging.rs:26:1: 30:2
}
}
diff --git a/src/test/mir-opt/inline/inline-diverging.rs b/src/test/mir-opt/inline/inline_diverging.rs
index ae6f814c2..ae6f814c2 100644
--- a/src/test/mir-opt/inline/inline-diverging.rs
+++ b/src/test/mir-opt/inline/inline_diverging.rs
diff --git a/src/test/mir-opt/inline/inline_generator.main.Inline.diff b/src/test/mir-opt/inline/inline_generator.main.Inline.diff
index 3fd8aad72..91bff3d32 100644
--- a/src/test/mir-opt/inline/inline_generator.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline_generator.main.Inline.diff
@@ -2,59 +2,56 @@
+ // MIR for `main` after Inline
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-generator.rs:+0:11: +0:11
- let _1: std::ops::GeneratorState<i32, bool>; // in scope 0 at $DIR/inline-generator.rs:+1:9: +1:11
- let mut _2: std::pin::Pin<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>; // in scope 0 at $DIR/inline-generator.rs:+1:14: +1:32
- let mut _3: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline-generator.rs:+1:23: +1:31
- let mut _4: [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline-generator.rs:+1:28: +1:31
-+ let mut _7: bool; // in scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
+ let mut _0: (); // return place in scope 0 at $DIR/inline_generator.rs:+0:11: +0:11
+ let _1: std::ops::GeneratorState<i32, bool>; // in scope 0 at $DIR/inline_generator.rs:+1:9: +1:11
+ let mut _2: std::pin::Pin<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>; // in scope 0 at $DIR/inline_generator.rs:+1:14: +1:32
+ let mut _3: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline_generator.rs:+1:23: +1:31
+ let mut _4: [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline_generator.rs:+1:28: +1:31
++ let mut _7: bool; // in scope 0 at $DIR/inline_generator.rs:+1:14: +1:46
scope 1 {
- debug _r => _1; // in scope 1 at $DIR/inline-generator.rs:+1:9: +1:11
+ debug _r => _1; // in scope 1 at $DIR/inline_generator.rs:+1:9: +1:11
}
-+ scope 2 (inlined g) { // at $DIR/inline-generator.rs:9:28: 9:31
++ scope 2 (inlined g) { // at $DIR/inline_generator.rs:9:28: 9:31
+ }
-+ scope 3 (inlined Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new) { // at $DIR/inline-generator.rs:9:14: 9:32
++ scope 3 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new) { // at $DIR/inline_generator.rs:9:14: 9:32
+ debug pointer => _3; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL
-+ let mut _5: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL
++ let mut _5: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL
+ scope 4 {
-+ scope 5 (inlined Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new_unchecked) { // at $SRC_DIR/core/src/pin.rs:LL:COL
++ scope 5 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new_unchecked) { // at $SRC_DIR/core/src/pin.rs:LL:COL
+ debug pointer => _5; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
-+ let mut _6: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
++ let mut _6: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
+ }
+ }
+ }
-+ scope 6 (inlined g::{closure#0}) { // at $DIR/inline-generator.rs:9:14: 9:46
-+ debug a => _11; // in scope 6 at $DIR/inline-generator.rs:15:6: 15:7
-+ let mut _8: i32; // in scope 6 at $DIR/inline-generator.rs:15:17: 15:39
-+ let mut _9: bool; // in scope 6 at $DIR/inline-generator.rs:15:20: 15:21
-+ let mut _10: bool; // in scope 6 at $DIR/inline-generator.rs:15:9: 15:9
-+ let _11: bool; // in scope 6 at $DIR/inline-generator.rs:15:6: 15:7
-+ let mut _12: u32; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
-+ let mut _13: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
-+ let mut _14: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
-+ let mut _15: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ scope 6 (inlined g::{closure#0}) { // at $DIR/inline_generator.rs:9:14: 9:46
++ debug a => _7; // in scope 6 at $DIR/inline_generator.rs:15:6: 15:7
++ let mut _8: i32; // in scope 6 at $DIR/inline_generator.rs:15:17: 15:39
++ let mut _9: u32; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ let mut _10: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ let mut _11: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ let mut _12: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-generator.rs:+1:9: +1:11
- StorageLive(_2); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32
- StorageLive(_3); // scope 0 at $DIR/inline-generator.rs:+1:23: +1:31
- StorageLive(_4); // scope 0 at $DIR/inline-generator.rs:+1:28: +1:31
-- _4 = g() -> bb1; // scope 0 at $DIR/inline-generator.rs:+1:28: +1:31
+ StorageLive(_1); // scope 0 at $DIR/inline_generator.rs:+1:9: +1:11
+ StorageLive(_2); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:32
+ StorageLive(_3); // scope 0 at $DIR/inline_generator.rs:+1:23: +1:31
+ StorageLive(_4); // scope 0 at $DIR/inline_generator.rs:+1:28: +1:31
+- _4 = g() -> bb1; // scope 0 at $DIR/inline_generator.rs:+1:28: +1:31
- // mir::Constant
-- // + span: $DIR/inline-generator.rs:9:28: 9:29
+- // + span: $DIR/inline_generator.rs:9:28: 9:29
- // + literal: Const { ty: fn() -> impl Generator<bool> {g}, val: Value(<ZST>) }
- }
-
- bb1: {
-+ Deinit(_4); // scope 2 at $DIR/inline-generator.rs:15:5: 15:41
-+ discriminant(_4) = 0; // scope 2 at $DIR/inline-generator.rs:15:5: 15:41
- _3 = &mut _4; // scope 0 at $DIR/inline-generator.rs:+1:23: +1:31
-- _2 = Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32
++ Deinit(_4); // scope 2 at $DIR/inline_generator.rs:15:5: 15:41
++ discriminant(_4) = 0; // scope 2 at $DIR/inline_generator.rs:15:5: 15:41
+ _3 = &mut _4; // scope 0 at $DIR/inline_generator.rs:+1:23: +1:31
+- _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:32
- // mir::Constant
-- // + span: $DIR/inline-generator.rs:9:14: 9:22
+- // + span: $DIR/inline_generator.rs:9:14: 9:22
- // + user_ty: UserType(0)
-- // + literal: Const { ty: fn(&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]) -> Pin<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]> {Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new}, val: Value(<ZST>) }
+- // + literal: Const { ty: fn(&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]) -> Pin<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]> {Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new}, val: Value(<ZST>) }
- }
-
- bb2: {
@@ -63,86 +60,77 @@
+ StorageLive(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
+ _6 = move _5; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
+ Deinit(_2); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
-+ (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]) = move _6; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
++ (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]) = move _6; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
+ StorageDead(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
+ StorageDead(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL
- StorageDead(_3); // scope 0 at $DIR/inline-generator.rs:+1:31: +1:32
-- _1 = <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
+ StorageDead(_3); // scope 0 at $DIR/inline_generator.rs:+1:31: +1:32
+- _1 = <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46
- // mir::Constant
-- // + span: $DIR/inline-generator.rs:9:33: 9:39
-- // + literal: Const { ty: for<'a> fn(Pin<&'a mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>, bool) -> GeneratorState<<[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::Yield, <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::Return> {<[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator<bool>>::resume}, val: Value(<ZST>) }
-+ StorageLive(_7); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
-+ _7 = const false; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
-+ StorageLive(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
-+ StorageLive(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
-+ _13 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
-+ _12 = discriminant((*_13)); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
-+ switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
+- // + span: $DIR/inline_generator.rs:9:33: 9:39
+- // + literal: Const { ty: for<'a> fn(Pin<&'a mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>, bool) -> GeneratorState<<[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator<bool>>::Yield, <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator<bool>>::Return> {<[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator<bool>>::resume}, val: Value(<ZST>) }
++ StorageLive(_7); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46
++ _7 = const false; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46
++ _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ _9 = discriminant((*_10)); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ switchInt(move _9) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
}
- bb3: {
+ bb1: {
-+ StorageDead(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
-+ StorageDead(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
-+ StorageDead(_7); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46
- StorageDead(_2); // scope 0 at $DIR/inline-generator.rs:+1:45: +1:46
- StorageDead(_4); // scope 0 at $DIR/inline-generator.rs:+1:46: +1:47
- _0 = const (); // scope 0 at $DIR/inline-generator.rs:+0:11: +2:2
- StorageDead(_1); // scope 0 at $DIR/inline-generator.rs:+2:1: +2:2
- return; // scope 0 at $DIR/inline-generator.rs:+2:2: +2:2
++ StorageDead(_7); // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46
+ StorageDead(_2); // scope 0 at $DIR/inline_generator.rs:+1:45: +1:46
+ StorageDead(_4); // scope 0 at $DIR/inline_generator.rs:+1:46: +1:47
+ _0 = const (); // scope 0 at $DIR/inline_generator.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_generator.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/inline_generator.rs:+2:2: +2:2
}
- bb4 (cleanup): {
+ bb2 (cleanup): {
- resume; // scope 0 at $DIR/inline-generator.rs:+0:1: +2:2
+ resume; // scope 0 at $DIR/inline_generator.rs:+0:1: +2:2
+ }
+
+ bb3: {
-+ _11 = move _7; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
-+ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:15:17: 15:39
-+ StorageLive(_9); // scope 6 at $DIR/inline-generator.rs:15:20: 15:21
-+ _9 = _11; // scope 6 at $DIR/inline-generator.rs:15:20: 15:21
-+ switchInt(move _9) -> [false: bb5, otherwise: bb4]; // scope 6 at $DIR/inline-generator.rs:15:20: 15:21
++ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
++ switchInt(move _7) -> [false: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21
+ }
+
+ bb4: {
-+ _8 = const 7_i32; // scope 6 at $DIR/inline-generator.rs:15:24: 15:25
-+ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:15:17: 15:39
++ _8 = const 7_i32; // scope 6 at $DIR/inline_generator.rs:15:24: 15:25
++ goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
+ }
+
+ bb5: {
-+ _8 = const 13_i32; // scope 6 at $DIR/inline-generator.rs:15:35: 15:37
-+ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:15:17: 15:39
++ _8 = const 13_i32; // scope 6 at $DIR/inline_generator.rs:15:35: 15:37
++ goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
+ }
+
+ bb6: {
-+ StorageDead(_9); // scope 6 at $DIR/inline-generator.rs:15:38: 15:39
-+ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
-+ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
-+ discriminant(_1) = 0; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
-+ _14 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
-+ discriminant((*_14)) = 3; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39
-+ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:11: 15:39
++ Deinit(_1); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
++ ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
++ discriminant(_1) = 0; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
++ _11 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
++ discriminant((*_11)) = 3; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
++ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:11: 15:39
+ }
+
+ bb7: {
-+ StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
-+ _10 = move _7; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
-+ StorageDead(_8); // scope 6 at $DIR/inline-generator.rs:15:38: 15:39
-+ Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
-+ ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
-+ discriminant(_1) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
-+ _15 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
-+ discriminant((*_15)) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41
-+ goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:41: 15:41
++ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
++ StorageDead(_8); // scope 6 at $DIR/inline_generator.rs:15:38: 15:39
++ Deinit(_1); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++ ((_1 as Complete).0: bool) = move _7; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++ discriminant(_1) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++ _12 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++ discriminant((*_12)) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
++ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:41: 15:41
+ }
+
+ bb8: {
-+ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
+ }
+
+ bb9: {
-+ unreachable; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41
++ unreachable; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
}
}
diff --git a/src/test/mir-opt/inline/inline-generator.rs b/src/test/mir-opt/inline/inline_generator.rs
index d11b3e548..d11b3e548 100644
--- a/src/test/mir-opt/inline/inline-generator.rs
+++ b/src/test/mir-opt/inline/inline_generator.rs
diff --git a/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff b/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff
index 076509df3..f1988ea4b 100644
--- a/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff
+++ b/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff
@@ -2,43 +2,59 @@
+ // MIR for `default` after Inline
fn default() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-instruction-set.rs:+0:18: +0:18
- let _1: (); // in scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
- let _2: (); // in scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
- let _3: (); // in scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30
-+ scope 1 (inlined instruction_set_default) { // at $DIR/inline-instruction-set.rs:53:5: 53:30
+ let mut _0: (); // return place in scope 0 at $DIR/inline_instruction_set.rs:+0:18: +0:18
+ let _1: (); // in scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26
+ let _2: (); // in scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26
+ let _3: (); // in scope 0 at $DIR/inline_instruction_set.rs:+3:5: +3:30
+ let _4: (); // in scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
++ scope 1 (inlined instruction_set_default) { // at $DIR/inline_instruction_set.rs:59:5: 59:30
++ }
++ scope 2 (inlined inline_always_and_using_inline_asm) { // at $DIR/inline_instruction_set.rs:60:5: 60:41
++ scope 3 {
++ }
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
- _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
+ StorageLive(_1); // scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26
+ _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26
// mir::Constant
- // + span: $DIR/inline-instruction-set.rs:51:5: 51:24
+ // + span: $DIR/inline_instruction_set.rs:57:5: 57:24
// + literal: Const { ty: fn() {instruction_set_a32}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:26: +1:27
- StorageLive(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
- _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
+ StorageDead(_1); // scope 0 at $DIR/inline_instruction_set.rs:+1:26: +1:27
+ StorageLive(_2); // scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26
+ _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26
// mir::Constant
- // + span: $DIR/inline-instruction-set.rs:52:5: 52:24
+ // + span: $DIR/inline_instruction_set.rs:58:5: 58:24
// + literal: Const { ty: fn() {instruction_set_t32}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:26: +2:27
- StorageLive(_3); // scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30
-- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline-instruction-set.rs:+3:5: +3:30
+ StorageDead(_2); // scope 0 at $DIR/inline_instruction_set.rs:+2:26: +2:27
+ StorageLive(_3); // scope 0 at $DIR/inline_instruction_set.rs:+3:5: +3:30
+- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline_instruction_set.rs:+3:5: +3:30
- // mir::Constant
-- // + span: $DIR/inline-instruction-set.rs:53:5: 53:28
+- // + span: $DIR/inline_instruction_set.rs:59:5: 59:28
- // + literal: Const { ty: fn() {instruction_set_default}, val: Value(<ZST>) }
- }
-
- bb3: {
- StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:+3:30: +3:31
- _0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:+0:18: +4:2
- return; // scope 0 at $DIR/inline-instruction-set.rs:+4:2: +4:2
+ StorageDead(_3); // scope 0 at $DIR/inline_instruction_set.rs:+3:30: +3:31
+ StorageLive(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
+- _4 = inline_always_and_using_inline_asm() -> bb4; // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
+- // mir::Constant
+- // + span: $DIR/inline_instruction_set.rs:60:5: 60:39
+- // + literal: Const { ty: fn() {inline_always_and_using_inline_asm}, val: Value(<ZST>) }
++ asm!("/* do nothing */", options((empty))) -> bb3; // scope 3 at $DIR/inline_instruction_set.rs:43:14: 43:38
+ }
+
+- bb4: {
++ bb3: {
+ StorageDead(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:41: +4:42
+ _0 = const (); // scope 0 at $DIR/inline_instruction_set.rs:+0:18: +5:2
+ return; // scope 0 at $DIR/inline_instruction_set.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/inline/inline-instruction-set.rs b/src/test/mir-opt/inline/inline_instruction_set.rs
index be36ff50c..5dfb04943 100644
--- a/src/test/mir-opt/inline/inline-instruction-set.rs
+++ b/src/test/mir-opt/inline/inline_instruction_set.rs
@@ -1,5 +1,7 @@
// Checks that only functions with the compatible instruction_set attributes are inlined.
//
+// A function is "compatible" when the *callee* has the same attribute or no attribute.
+//
// compile-flags: --target thumbv4t-none-eabi
// needs-llvm-components: arm
@@ -36,14 +38,18 @@ fn instruction_set_t32() {}
#[inline]
fn instruction_set_default() {}
+#[inline(always)]
+fn inline_always_and_using_inline_asm() {
+ unsafe { asm!("/* do nothing */") };
+}
+
// EMIT_MIR inline_instruction_set.t32.Inline.diff
#[instruction_set(arm::t32)]
pub fn t32() {
instruction_set_a32();
instruction_set_t32();
- // The default instruction set is currently
- // conservatively assumed to be incompatible.
instruction_set_default();
+ inline_always_and_using_inline_asm();
}
// EMIT_MIR inline_instruction_set.default.Inline.diff
@@ -51,4 +57,5 @@ pub fn default() {
instruction_set_a32();
instruction_set_t32();
instruction_set_default();
+ inline_always_and_using_inline_asm();
}
diff --git a/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff b/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff
index b275d08e0..e777b2cc2 100644
--- a/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff
+++ b/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff
@@ -2,45 +2,57 @@
+ // MIR for `t32` after Inline
fn t32() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-instruction-set.rs:+0:14: +0:14
- let _1: (); // in scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
- let _2: (); // in scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
- let _3: (); // in scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30
-+ scope 1 (inlined instruction_set_t32) { // at $DIR/inline-instruction-set.rs:43:5: 43:26
+ let mut _0: (); // return place in scope 0 at $DIR/inline_instruction_set.rs:+0:14: +0:14
+ let _1: (); // in scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26
+ let _2: (); // in scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26
+ let _3: (); // in scope 0 at $DIR/inline_instruction_set.rs:+3:5: +3:30
+ let _4: (); // in scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
++ scope 1 (inlined instruction_set_t32) { // at $DIR/inline_instruction_set.rs:50:5: 50:26
++ }
++ scope 2 (inlined instruction_set_default) { // at $DIR/inline_instruction_set.rs:51:5: 51:30
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
- _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline-instruction-set.rs:+1:5: +1:26
+ StorageLive(_1); // scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26
+ _1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline_instruction_set.rs:+1:5: +1:26
// mir::Constant
- // + span: $DIR/inline-instruction-set.rs:42:5: 42:24
+ // + span: $DIR/inline_instruction_set.rs:49:5: 49:24
// + literal: Const { ty: fn() {instruction_set_a32}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_1); // scope 0 at $DIR/inline-instruction-set.rs:+1:26: +1:27
- StorageLive(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
-- _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+2:5: +2:26
+ StorageDead(_1); // scope 0 at $DIR/inline_instruction_set.rs:+1:26: +1:27
+ StorageLive(_2); // scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26
+- _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline_instruction_set.rs:+2:5: +2:26
- // mir::Constant
-- // + span: $DIR/inline-instruction-set.rs:43:5: 43:24
+- // + span: $DIR/inline_instruction_set.rs:50:5: 50:24
- // + literal: Const { ty: fn() {instruction_set_t32}, val: Value(<ZST>) }
- }
-
- bb2: {
- StorageDead(_2); // scope 0 at $DIR/inline-instruction-set.rs:+2:26: +2:27
- StorageLive(_3); // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30
-- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30
-+ _3 = instruction_set_default() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:+5:5: +5:30
+ StorageDead(_2); // scope 0 at $DIR/inline_instruction_set.rs:+2:26: +2:27
+ StorageLive(_3); // scope 0 at $DIR/inline_instruction_set.rs:+3:5: +3:30
+- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline_instruction_set.rs:+3:5: +3:30
+- // mir::Constant
+- // + span: $DIR/inline_instruction_set.rs:51:5: 51:28
+- // + literal: Const { ty: fn() {instruction_set_default}, val: Value(<ZST>) }
+- }
+-
+- bb3: {
+ StorageDead(_3); // scope 0 at $DIR/inline_instruction_set.rs:+3:30: +3:31
+ StorageLive(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
+- _4 = inline_always_and_using_inline_asm() -> bb4; // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
++ _4 = inline_always_and_using_inline_asm() -> bb2; // scope 0 at $DIR/inline_instruction_set.rs:+4:5: +4:41
// mir::Constant
- // + span: $DIR/inline-instruction-set.rs:46:5: 46:28
- // + literal: Const { ty: fn() {instruction_set_default}, val: Value(<ZST>) }
+ // + span: $DIR/inline_instruction_set.rs:52:5: 52:39
+ // + literal: Const { ty: fn() {inline_always_and_using_inline_asm}, val: Value(<ZST>) }
}
-- bb3: {
+- bb4: {
+ bb2: {
- StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:+5:30: +5:31
- _0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:+0:14: +6:2
- return; // scope 0 at $DIR/inline-instruction-set.rs:+6:2: +6:2
+ StorageDead(_4); // scope 0 at $DIR/inline_instruction_set.rs:+4:41: +4:42
+ _0 = const (); // scope 0 at $DIR/inline_instruction_set.rs:+0:14: +5:2
+ return; // scope 0 at $DIR/inline_instruction_set.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff
index 7e017373b..2a4dc9e3e 100644
--- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.diff
@@ -2,45 +2,45 @@
+ // MIR for `main` after Inline
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-into-box-place.rs:+0:11: +0:11
- let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11
- let mut _2: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- let mut _3: usize; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- let mut _4: *mut u8; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- let mut _6: (); // in scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
- let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
-+ let mut _8: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ let mut _0: (); // return place in scope 0 at $DIR/inline_into_box_place.rs:+0:11: +0:11
+ let _1: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline_into_box_place.rs:+1:9: +1:11
+ let mut _2: usize; // in scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43
+ let mut _3: usize; // in scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43
+ let mut _4: *mut u8; // in scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43
+ let mut _5: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43
+ let mut _6: (); // in scope 0 at $DIR/inline_into_box_place.rs:+1:42: +1:43
+ let mut _7: *const std::vec::Vec<u32>; // in scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43
++ let mut _8: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
scope 1 {
- debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:+1:9: +1:11
+ debug _x => _1; // in scope 1 at $DIR/inline_into_box_place.rs:+1:9: +1:11
}
scope 2 {
}
-+ scope 3 (inlined Vec::<u32>::new) { // at $DIR/inline-into-box-place.rs:8:33: 8:43
++ scope 3 (inlined Vec::<u32>::new) { // at $DIR/inline_into_box_place.rs:8:33: 8:43
+ let mut _9: alloc::raw_vec::RawVec<u32>; // in scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-into-box-place.rs:+1:9: +1:11
- _2 = SizeOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- _3 = AlignOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline-into-box-place.rs:+1:29: +1:43
+ StorageLive(_1); // scope 0 at $DIR/inline_into_box_place.rs:+1:9: +1:11
+ _2 = SizeOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline_into_box_place.rs:+1:29: +1:43
+ _3 = AlignOf(std::vec::Vec<u32>); // scope 2 at $DIR/inline_into_box_place.rs:+1:29: +1:43
+ _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 2 at $DIR/inline_into_box_place.rs:+1:29: +1:43
// mir::Constant
- // + span: $DIR/inline-into-box-place.rs:8:29: 8:43
+ // + span: $DIR/inline_into_box_place.rs:8:29: 8:43
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
}
bb1: {
- StorageLive(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- _7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-+ StorageLive(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
-+ _8 = &mut (*_7); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
+ StorageLive(_5); // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43
+ _5 = ShallowInitBox(move _4, std::vec::Vec<u32>); // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43
+ _7 = (((_5.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
+- (*_7) = Vec::<u32>::new() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
++ StorageLive(_8); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
++ _8 = &mut (*_7); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
+ StorageLive(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ _9 = const _; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
// mir::Constant
-- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41
+- // + span: $DIR/inline_into_box_place.rs:8:33: 8:41
- // + user_ty: UserType(1)
- // + literal: Const { ty: fn() -> Vec<u32> {Vec::<u32>::new}, val: Value(<ZST>) }
- }
@@ -53,29 +53,29 @@
+ ((*_8).0: alloc::raw_vec::RawVec<u32>) = move _9; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ ((*_8).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ StorageDead(_9); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-+ StorageDead(_8); // scope 0 at $DIR/inline-into-box-place.rs:+1:33: +1:43
- _1 = move _5; // scope 0 at $DIR/inline-into-box-place.rs:+1:29: +1:43
- StorageDead(_5); // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
- _0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:+0:11: +2:2
-- drop(_1) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
-+ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
++ StorageDead(_8); // scope 0 at $DIR/inline_into_box_place.rs:+1:33: +1:43
+ _1 = move _5; // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:43
+ StorageDead(_5); // scope 0 at $DIR/inline_into_box_place.rs:+1:42: +1:43
+ _0 = const (); // scope 0 at $DIR/inline_into_box_place.rs:+0:11: +2:2
+- drop(_1) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2
++ drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2
}
- bb3: {
+ bb2: {
- StorageDead(_1); // scope 0 at $DIR/inline-into-box-place.rs:+2:1: +2:2
- return; // scope 0 at $DIR/inline-into-box-place.rs:+2:2: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/inline_into_box_place.rs:+2:2: +2:2
}
- bb4 (cleanup): {
+ bb3 (cleanup): {
- resume; // scope 0 at $DIR/inline-into-box-place.rs:+0:1: +2:2
+ resume; // scope 0 at $DIR/inline_into_box_place.rs:+0:1: +2:2
- }
-
- bb5 (cleanup): {
-- _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline-into-box-place.rs:+1:42: +1:43
+- _6 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_5.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_5.1: std::alloc::Global)) -> bb4; // scope 0 at $DIR/inline_into_box_place.rs:+1:42: +1:43
- // mir::Constant
-- // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
+- // + span: $DIR/inline_into_box_place.rs:8:42: 8:43
- // + literal: Const { ty: unsafe fn(Unique<Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>}, val: Value(<ZST>) }
}
}
diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline_into_box_place.rs
index 232bcc7b2..232bcc7b2 100644
--- a/src/test/mir-opt/inline/inline-into-box-place.rs
+++ b/src/test/mir-opt/inline/inline_into_box_place.rs
diff --git a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir
index 361b02715..1c590be94 100644
--- a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir
@@ -1,55 +1,55 @@
// MIR for `main` after Inline
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-options.rs:+0:11: +0:11
- let _1: (); // in scope 0 at $DIR/inline-options.rs:+1:5: +1:18
- let _2: (); // in scope 0 at $DIR/inline-options.rs:+2:5: +2:21
- scope 1 (inlined inlined::<u32>) { // at $DIR/inline-options.rs:10:5: 10:21
- let _3: (); // in scope 1 at $DIR/inline-options.rs:16:23: 16:26
- let _4: (); // in scope 1 at $DIR/inline-options.rs:16:28: 16:31
- let _5: (); // in scope 1 at $DIR/inline-options.rs:16:33: 16:36
+ let mut _0: (); // return place in scope 0 at $DIR/inline_options.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/inline_options.rs:+1:5: +1:18
+ let _2: (); // in scope 0 at $DIR/inline_options.rs:+2:5: +2:21
+ scope 1 (inlined inlined::<u32>) { // at $DIR/inline_options.rs:10:5: 10:21
+ let _3: (); // in scope 1 at $DIR/inline_options.rs:16:23: 16:26
+ let _4: (); // in scope 1 at $DIR/inline_options.rs:16:28: 16:31
+ let _5: (); // in scope 1 at $DIR/inline_options.rs:16:33: 16:36
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-options.rs:+1:5: +1:18
- _1 = not_inlined() -> bb1; // scope 0 at $DIR/inline-options.rs:+1:5: +1:18
+ StorageLive(_1); // scope 0 at $DIR/inline_options.rs:+1:5: +1:18
+ _1 = not_inlined() -> bb1; // scope 0 at $DIR/inline_options.rs:+1:5: +1:18
// mir::Constant
- // + span: $DIR/inline-options.rs:9:5: 9:16
+ // + span: $DIR/inline_options.rs:9:5: 9:16
// + literal: Const { ty: fn() {not_inlined}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_1); // scope 0 at $DIR/inline-options.rs:+1:18: +1:19
- StorageLive(_2); // scope 0 at $DIR/inline-options.rs:+2:5: +2:21
- StorageLive(_3); // scope 1 at $DIR/inline-options.rs:16:23: 16:26
- _3 = g() -> bb2; // scope 1 at $DIR/inline-options.rs:16:23: 16:26
+ StorageDead(_1); // scope 0 at $DIR/inline_options.rs:+1:18: +1:19
+ StorageLive(_2); // scope 0 at $DIR/inline_options.rs:+2:5: +2:21
+ StorageLive(_3); // scope 1 at $DIR/inline_options.rs:16:23: 16:26
+ _3 = g() -> bb2; // scope 1 at $DIR/inline_options.rs:16:23: 16:26
// mir::Constant
- // + span: $DIR/inline-options.rs:16:23: 16:24
+ // + span: $DIR/inline_options.rs:16:23: 16:24
// + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_3); // scope 1 at $DIR/inline-options.rs:16:26: 16:27
- StorageLive(_4); // scope 1 at $DIR/inline-options.rs:16:28: 16:31
- _4 = g() -> bb3; // scope 1 at $DIR/inline-options.rs:16:28: 16:31
+ StorageDead(_3); // scope 1 at $DIR/inline_options.rs:16:26: 16:27
+ StorageLive(_4); // scope 1 at $DIR/inline_options.rs:16:28: 16:31
+ _4 = g() -> bb3; // scope 1 at $DIR/inline_options.rs:16:28: 16:31
// mir::Constant
- // + span: $DIR/inline-options.rs:16:28: 16:29
+ // + span: $DIR/inline_options.rs:16:28: 16:29
// + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
}
bb3: {
- StorageDead(_4); // scope 1 at $DIR/inline-options.rs:16:31: 16:32
- StorageLive(_5); // scope 1 at $DIR/inline-options.rs:16:33: 16:36
- _5 = g() -> bb4; // scope 1 at $DIR/inline-options.rs:16:33: 16:36
+ StorageDead(_4); // scope 1 at $DIR/inline_options.rs:16:31: 16:32
+ StorageLive(_5); // scope 1 at $DIR/inline_options.rs:16:33: 16:36
+ _5 = g() -> bb4; // scope 1 at $DIR/inline_options.rs:16:33: 16:36
// mir::Constant
- // + span: $DIR/inline-options.rs:16:33: 16:34
+ // + span: $DIR/inline_options.rs:16:33: 16:34
// + literal: Const { ty: fn() {g}, val: Value(<ZST>) }
}
bb4: {
- StorageDead(_5); // scope 1 at $DIR/inline-options.rs:16:36: 16:37
- StorageDead(_2); // scope 0 at $DIR/inline-options.rs:+2:21: +2:22
- _0 = const (); // scope 0 at $DIR/inline-options.rs:+0:11: +3:2
- return; // scope 0 at $DIR/inline-options.rs:+3:2: +3:2
+ StorageDead(_5); // scope 1 at $DIR/inline_options.rs:16:36: 16:37
+ StorageDead(_2); // scope 0 at $DIR/inline_options.rs:+2:21: +2:22
+ _0 = const (); // scope 0 at $DIR/inline_options.rs:+0:11: +3:2
+ return; // scope 0 at $DIR/inline_options.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/inline/inline-options.rs b/src/test/mir-opt/inline/inline_options.rs
index 477f050b6..477f050b6 100644
--- a/src/test/mir-opt/inline/inline-options.rs
+++ b/src/test/mir-opt/inline/inline_options.rs
diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
index 169e7f5c5..60149ff36 100644
--- a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
@@ -1,72 +1,68 @@
// MIR for `bar` after Inline
fn bar() -> bool {
- let mut _0: bool; // return place in scope 0 at $DIR/inline-retag.rs:+0:13: +0:17
- let _1: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; // in scope 0 at $DIR/inline-retag.rs:+1:9: +1:10
- let mut _2: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; // in scope 0 at $DIR/inline-retag.rs:+2:5: +2:6
- let mut _3: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:7: +2:9
- let _4: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:7: +2:9
- let _5: i32; // in scope 0 at $DIR/inline-retag.rs:+2:8: +2:9
- let mut _6: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:11: +2:14
- let _7: &i32; // in scope 0 at $DIR/inline-retag.rs:+2:11: +2:14
- let _8: i32; // in scope 0 at $DIR/inline-retag.rs:+2:12: +2:14
+ let mut _0: bool; // return place in scope 0 at $DIR/inline_retag.rs:+0:13: +0:17
+ let _1: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; // in scope 0 at $DIR/inline_retag.rs:+1:9: +1:10
+ let mut _2: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}; // in scope 0 at $DIR/inline_retag.rs:+2:5: +2:6
+ let mut _3: &i32; // in scope 0 at $DIR/inline_retag.rs:+2:7: +2:9
+ let _4: &i32; // in scope 0 at $DIR/inline_retag.rs:+2:7: +2:9
+ let _5: i32; // in scope 0 at $DIR/inline_retag.rs:+2:8: +2:9
+ let mut _6: &i32; // in scope 0 at $DIR/inline_retag.rs:+2:11: +2:14
+ let _7: &i32; // in scope 0 at $DIR/inline_retag.rs:+2:11: +2:14
+ let _8: i32; // in scope 0 at $DIR/inline_retag.rs:+2:12: +2:14
scope 1 {
- debug f => _1; // in scope 1 at $DIR/inline-retag.rs:+1:9: +1:10
- let mut _9: &i32; // in scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
- let mut _10: &i32; // in scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
- scope 2 (inlined foo) { // at $DIR/inline-retag.rs:12:5: 12:15
- debug x => _3; // in scope 2 at $DIR/inline-retag.rs:16:8: 16:9
- debug y => _6; // in scope 2 at $DIR/inline-retag.rs:16:17: 16:18
- let mut _11: i32; // in scope 2 at $DIR/inline-retag.rs:17:5: 17:7
- let mut _12: i32; // in scope 2 at $DIR/inline-retag.rs:17:11: 17:13
+ debug f => _1; // in scope 1 at $DIR/inline_retag.rs:+1:9: +1:10
+ let mut _9: &i32; // in scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
+ let mut _10: &i32; // in scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
+ scope 2 (inlined foo) { // at $DIR/inline_retag.rs:12:5: 12:15
+ debug x => _3; // in scope 2 at $DIR/inline_retag.rs:16:8: 16:9
+ debug y => _6; // in scope 2 at $DIR/inline_retag.rs:16:17: 16:18
+ let mut _11: i32; // in scope 2 at $DIR/inline_retag.rs:17:5: 17:7
+ let mut _12: i32; // in scope 2 at $DIR/inline_retag.rs:17:11: 17:13
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-retag.rs:+1:9: +1:10
- _1 = foo; // scope 0 at $DIR/inline-retag.rs:+1:13: +1:16
+ StorageLive(_1); // scope 0 at $DIR/inline_retag.rs:+1:9: +1:10
+ _1 = foo; // scope 0 at $DIR/inline_retag.rs:+1:13: +1:16
// mir::Constant
- // + span: $DIR/inline-retag.rs:11:13: 11:16
+ // + span: $DIR/inline_retag.rs:11:13: 11:16
// + literal: Const { ty: for<'a, 'b> fn(&'a i32, &'b i32) -> bool {foo}, val: Value(<ZST>) }
- StorageLive(_2); // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6
- _2 = _1; // scope 1 at $DIR/inline-retag.rs:+2:5: +2:6
- StorageLive(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
- StorageLive(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
- _10 = const _; // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
+ StorageLive(_2); // scope 1 at $DIR/inline_retag.rs:+2:5: +2:6
+ _2 = _1; // scope 1 at $DIR/inline_retag.rs:+2:5: +2:6
+ StorageLive(_3); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
+ StorageLive(_4); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
+ _10 = const _; // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
// mir::Constant
- // + span: $DIR/inline-retag.rs:12:7: 12:9
+ // + span: $DIR/inline_retag.rs:12:7: 12:9
// + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[1])) }
- Retag(_10); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
- _4 = &(*_10); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
- Retag(_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
- _3 = &(*_4); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
- Retag(_3); // scope 1 at $DIR/inline-retag.rs:+2:7: +2:9
- StorageLive(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
- StorageLive(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
- _9 = const _; // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
+ Retag(_10); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
+ _4 = &(*_10); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
+ _3 = &(*_4); // scope 1 at $DIR/inline_retag.rs:+2:7: +2:9
+ StorageLive(_6); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
+ StorageLive(_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
+ _9 = const _; // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
// mir::Constant
- // + span: $DIR/inline-retag.rs:12:11: 12:14
+ // + span: $DIR/inline_retag.rs:12:11: 12:14
// + literal: Const { ty: &i32, val: Unevaluated(bar, [], Some(promoted[0])) }
- Retag(_9); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
- _7 = &(*_9); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
- Retag(_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
- _6 = &(*_7); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
- Retag(_6); // scope 1 at $DIR/inline-retag.rs:+2:11: +2:14
- Retag(_3); // scope 2 at $DIR/inline-retag.rs:16:8: 16:9
- Retag(_6); // scope 2 at $DIR/inline-retag.rs:16:17: 16:18
- StorageLive(_11); // scope 2 at $DIR/inline-retag.rs:17:5: 17:7
- _11 = (*_3); // scope 2 at $DIR/inline-retag.rs:17:5: 17:7
- StorageLive(_12); // scope 2 at $DIR/inline-retag.rs:17:11: 17:13
- _12 = (*_6); // scope 2 at $DIR/inline-retag.rs:17:11: 17:13
- _0 = Eq(move _11, move _12); // scope 2 at $DIR/inline-retag.rs:17:5: 17:13
- StorageDead(_12); // scope 2 at $DIR/inline-retag.rs:17:12: 17:13
- StorageDead(_11); // scope 2 at $DIR/inline-retag.rs:17:12: 17:13
- StorageDead(_6); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15
- StorageDead(_3); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15
- StorageDead(_2); // scope 1 at $DIR/inline-retag.rs:+2:14: +2:15
- StorageDead(_1); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2
- StorageDead(_7); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2
- StorageDead(_4); // scope 0 at $DIR/inline-retag.rs:+3:1: +3:2
- return; // scope 0 at $DIR/inline-retag.rs:+3:2: +3:2
+ Retag(_9); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
+ _7 = &(*_9); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
+ _6 = &(*_7); // scope 1 at $DIR/inline_retag.rs:+2:11: +2:14
+ Retag(_3); // scope 2 at $DIR/inline_retag.rs:16:8: 16:9
+ Retag(_6); // scope 2 at $DIR/inline_retag.rs:16:17: 16:18
+ StorageLive(_11); // scope 2 at $DIR/inline_retag.rs:17:5: 17:7
+ _11 = (*_3); // scope 2 at $DIR/inline_retag.rs:17:5: 17:7
+ StorageLive(_12); // scope 2 at $DIR/inline_retag.rs:17:11: 17:13
+ _12 = (*_6); // scope 2 at $DIR/inline_retag.rs:17:11: 17:13
+ _0 = Eq(move _11, move _12); // scope 2 at $DIR/inline_retag.rs:17:5: 17:13
+ StorageDead(_12); // scope 2 at $DIR/inline_retag.rs:17:12: 17:13
+ StorageDead(_11); // scope 2 at $DIR/inline_retag.rs:17:12: 17:13
+ StorageDead(_6); // scope 1 at $DIR/inline_retag.rs:+2:14: +2:15
+ StorageDead(_3); // scope 1 at $DIR/inline_retag.rs:+2:14: +2:15
+ StorageDead(_2); // scope 1 at $DIR/inline_retag.rs:+2:14: +2:15
+ StorageDead(_1); // scope 0 at $DIR/inline_retag.rs:+3:1: +3:2
+ StorageDead(_7); // scope 0 at $DIR/inline_retag.rs:+3:1: +3:2
+ StorageDead(_4); // scope 0 at $DIR/inline_retag.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/inline_retag.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/inline/inline-retag.rs b/src/test/mir-opt/inline/inline_retag.rs
index c6950f269..c6950f269 100644
--- a/src/test/mir-opt/inline/inline-retag.rs
+++ b/src/test/mir-opt/inline/inline_retag.rs
diff --git a/src/test/mir-opt/inline/inline_shims.clone.Inline.diff b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff
index d691e90b7..969573ba3 100644
--- a/src/test/mir-opt/inline/inline_shims.clone.Inline.diff
+++ b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff
@@ -2,25 +2,25 @@
+ // MIR for `clone` after Inline
fn clone(_1: fn(A, B)) -> fn(A, B) {
- debug f => _1; // in scope 0 at $DIR/inline-shims.rs:+0:20: +0:21
- let mut _0: fn(A, B); // return place in scope 0 at $DIR/inline-shims.rs:+0:36: +0:44
- let mut _2: &fn(A, B); // in scope 0 at $DIR/inline-shims.rs:+1:5: +1:14
-+ scope 1 (inlined <fn(A, B) as Clone>::clone - shim(fn(A, B))) { // at $DIR/inline-shims.rs:6:5: 6:14
+ debug f => _1; // in scope 0 at $DIR/inline_shims.rs:+0:20: +0:21
+ let mut _0: fn(A, B); // return place in scope 0 at $DIR/inline_shims.rs:+0:36: +0:44
+ let mut _2: &fn(A, B); // in scope 0 at $DIR/inline_shims.rs:+1:5: +1:14
++ scope 1 (inlined <fn(A, B) as Clone>::clone - shim(fn(A, B))) { // at $DIR/inline_shims.rs:6:5: 6:14
+ }
bb0: {
- StorageLive(_2); // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14
- _2 = &_1; // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14
-- _0 = <fn(A, B) as Clone>::clone(move _2) -> bb1; // scope 0 at $DIR/inline-shims.rs:+1:5: +1:14
+ StorageLive(_2); // scope 0 at $DIR/inline_shims.rs:+1:5: +1:14
+ _2 = &_1; // scope 0 at $DIR/inline_shims.rs:+1:5: +1:14
+- _0 = <fn(A, B) as Clone>::clone(move _2) -> bb1; // scope 0 at $DIR/inline_shims.rs:+1:5: +1:14
- // mir::Constant
-- // + span: $DIR/inline-shims.rs:6:7: 6:12
+- // + span: $DIR/inline_shims.rs:6:7: 6:12
- // + literal: Const { ty: for<'a> fn(&'a fn(A, B)) -> fn(A, B) {<fn(A, B) as Clone>::clone}, val: Value(<ZST>) }
- }
-
- bb1: {
+ _0 = (*_2); // scope 1 at $SRC_DIR/core/src/clone.rs:LL:COL
- StorageDead(_2); // scope 0 at $DIR/inline-shims.rs:+1:13: +1:14
- return; // scope 0 at $DIR/inline-shims.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/inline_shims.rs:+1:13: +1:14
+ return; // scope 0 at $DIR/inline_shims.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff
index f7b1cde80..7a54beca2 100644
--- a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff
+++ b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff
@@ -2,51 +2,51 @@
+ // MIR for `drop` after Inline
fn drop(_1: *mut Vec<A>, _2: *mut Option<B>) -> () {
- debug a => _1; // in scope 0 at $DIR/inline-shims.rs:+0:19: +0:20
- debug b => _2; // in scope 0 at $DIR/inline-shims.rs:+0:35: +0:36
- let mut _0: (); // return place in scope 0 at $DIR/inline-shims.rs:+0:54: +0:54
- let _3: (); // in scope 0 at $DIR/inline-shims.rs:+1:14: +1:40
- let mut _4: *mut std::vec::Vec<A>; // in scope 0 at $DIR/inline-shims.rs:+1:38: +1:39
- let mut _5: *mut std::option::Option<B>; // in scope 0 at $DIR/inline-shims.rs:+2:38: +2:39
+ debug a => _1; // in scope 0 at $DIR/inline_shims.rs:+0:19: +0:20
+ debug b => _2; // in scope 0 at $DIR/inline_shims.rs:+0:35: +0:36
+ let mut _0: (); // return place in scope 0 at $DIR/inline_shims.rs:+0:54: +0:54
+ let _3: (); // in scope 0 at $DIR/inline_shims.rs:+1:14: +1:40
+ let mut _4: *mut std::vec::Vec<A>; // in scope 0 at $DIR/inline_shims.rs:+1:38: +1:39
+ let mut _5: *mut std::option::Option<B>; // in scope 0 at $DIR/inline_shims.rs:+2:38: +2:39
scope 1 {
}
scope 2 {
-+ scope 3 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) { // at $DIR/inline-shims.rs:12:14: 12:40
++ scope 3 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) { // at $DIR/inline_shims.rs:12:14: 12:40
+ let mut _6: isize; // in scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ let mut _7: isize; // in scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ }
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/inline-shims.rs:+1:5: +1:42
- StorageLive(_4); // scope 1 at $DIR/inline-shims.rs:+1:38: +1:39
- _4 = _1; // scope 1 at $DIR/inline-shims.rs:+1:38: +1:39
- _3 = std::ptr::drop_in_place::<Vec<A>>(move _4) -> bb1; // scope 1 at $DIR/inline-shims.rs:+1:14: +1:40
+ StorageLive(_3); // scope 0 at $DIR/inline_shims.rs:+1:5: +1:42
+ StorageLive(_4); // scope 1 at $DIR/inline_shims.rs:+1:38: +1:39
+ _4 = _1; // scope 1 at $DIR/inline_shims.rs:+1:38: +1:39
+ _3 = std::ptr::drop_in_place::<Vec<A>>(move _4) -> bb1; // scope 1 at $DIR/inline_shims.rs:+1:14: +1:40
// mir::Constant
- // + span: $DIR/inline-shims.rs:11:14: 11:37
+ // + span: $DIR/inline_shims.rs:11:14: 11:37
// + literal: Const { ty: unsafe fn(*mut Vec<A>) {std::ptr::drop_in_place::<Vec<A>>}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_4); // scope 1 at $DIR/inline-shims.rs:+1:39: +1:40
- StorageDead(_3); // scope 0 at $DIR/inline-shims.rs:+1:41: +1:42
- StorageLive(_5); // scope 2 at $DIR/inline-shims.rs:+2:38: +2:39
- _5 = _2; // scope 2 at $DIR/inline-shims.rs:+2:38: +2:39
-- _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> bb2; // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40
+ StorageDead(_4); // scope 1 at $DIR/inline_shims.rs:+1:39: +1:40
+ StorageDead(_3); // scope 0 at $DIR/inline_shims.rs:+1:41: +1:42
+ StorageLive(_5); // scope 2 at $DIR/inline_shims.rs:+2:38: +2:39
+ _5 = _2; // scope 2 at $DIR/inline_shims.rs:+2:38: +2:39
+- _0 = std::ptr::drop_in_place::<Option<B>>(move _5) -> bb2; // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40
- // mir::Constant
-- // + span: $DIR/inline-shims.rs:12:14: 12:37
+- // + span: $DIR/inline_shims.rs:12:14: 12:37
- // + literal: Const { ty: unsafe fn(*mut Option<B>) {std::ptr::drop_in_place::<Option<B>>}, val: Value(<ZST>) }
-+ StorageLive(_6); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40
-+ StorageLive(_7); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40
++ StorageLive(_6); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40
++ StorageLive(_7); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40
+ _6 = discriminant((*_5)); // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ switchInt(move _6) -> [0_isize: bb2, otherwise: bb3]; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
}
bb2: {
-+ StorageDead(_7); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40
-+ StorageDead(_6); // scope 2 at $DIR/inline-shims.rs:+2:14: +2:40
- StorageDead(_5); // scope 2 at $DIR/inline-shims.rs:+2:39: +2:40
- return; // scope 0 at $DIR/inline-shims.rs:+3:2: +3:2
++ StorageDead(_7); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40
++ StorageDead(_6); // scope 2 at $DIR/inline_shims.rs:+2:14: +2:40
+ StorageDead(_5); // scope 2 at $DIR/inline_shims.rs:+2:39: +2:40
+ return; // scope 0 at $DIR/inline_shims.rs:+3:2: +3:2
+ }
+
+ bb3: {
diff --git a/src/test/mir-opt/inline/inline-shims.rs b/src/test/mir-opt/inline/inline_shims.rs
index 7c8618f71..7c8618f71 100644
--- a/src/test/mir-opt/inline/inline-shims.rs
+++ b/src/test/mir-opt/inline/inline_shims.rs
diff --git a/src/test/mir-opt/inline/inline_specialization.main.Inline.diff b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff
index fdf2a1e1f..af08296ed 100644
--- a/src/test/mir-opt/inline/inline_specialization.main.Inline.diff
+++ b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff
@@ -2,27 +2,27 @@
+ // MIR for `main` after Inline
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/inline-specialization.rs:+0:11: +0:11
- let _1: u32; // in scope 0 at $DIR/inline-specialization.rs:+1:9: +1:10
+ let mut _0: (); // return place in scope 0 at $DIR/inline_specialization.rs:+0:11: +0:11
+ let _1: u32; // in scope 0 at $DIR/inline_specialization.rs:+1:9: +1:10
scope 1 {
- debug x => _1; // in scope 1 at $DIR/inline-specialization.rs:+1:9: +1:10
+ debug x => _1; // in scope 1 at $DIR/inline_specialization.rs:+1:9: +1:10
}
-+ scope 2 (inlined <Vec<()> as Foo>::bar) { // at $DIR/inline-specialization.rs:5:13: 5:38
++ scope 2 (inlined <Vec<()> as Foo>::bar) { // at $DIR/inline_specialization.rs:5:13: 5:38
+ }
bb0: {
- StorageLive(_1); // scope 0 at $DIR/inline-specialization.rs:+1:9: +1:10
-- _1 = <Vec<()> as Foo>::bar() -> bb1; // scope 0 at $DIR/inline-specialization.rs:+1:13: +1:38
+ StorageLive(_1); // scope 0 at $DIR/inline_specialization.rs:+1:9: +1:10
+- _1 = <Vec<()> as Foo>::bar() -> bb1; // scope 0 at $DIR/inline_specialization.rs:+1:13: +1:38
- // mir::Constant
-- // + span: $DIR/inline-specialization.rs:5:13: 5:36
+- // + span: $DIR/inline_specialization.rs:5:13: 5:36
- // + literal: Const { ty: fn() -> u32 {<Vec<()> as Foo>::bar}, val: Value(<ZST>) }
- }
-
- bb1: {
-+ _1 = const 123_u32; // scope 2 at $DIR/inline-specialization.rs:14:31: 14:34
- _0 = const (); // scope 0 at $DIR/inline-specialization.rs:+0:11: +2:2
- StorageDead(_1); // scope 0 at $DIR/inline-specialization.rs:+2:1: +2:2
- return; // scope 0 at $DIR/inline-specialization.rs:+2:2: +2:2
++ _1 = const 123_u32; // scope 2 at $DIR/inline_specialization.rs:14:31: 14:34
+ _0 = const (); // scope 0 at $DIR/inline_specialization.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/inline_specialization.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/inline_specialization.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline-specialization.rs b/src/test/mir-opt/inline/inline_specialization.rs
index 87275b4e5..87275b4e5 100644
--- a/src/test/mir-opt/inline/inline-specialization.rs
+++ b/src/test/mir-opt/inline/inline_specialization.rs
diff --git a/src/test/mir-opt/inline/inline-trait-method.rs b/src/test/mir-opt/inline/inline_trait_method.rs
index 74be53f55..74be53f55 100644
--- a/src/test/mir-opt/inline/inline-trait-method.rs
+++ b/src/test/mir-opt/inline/inline_trait_method.rs
diff --git a/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir
index 89eefc292..637bf282a 100644
--- a/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_trait_method.test.Inline.after.mir
@@ -1,21 +1,21 @@
// MIR for `test` after Inline
fn test(_1: &dyn X) -> u32 {
- debug x => _1; // in scope 0 at $DIR/inline-trait-method.rs:+0:9: +0:10
- let mut _0: u32; // return place in scope 0 at $DIR/inline-trait-method.rs:+0:23: +0:26
- let mut _2: &dyn X; // in scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10
+ debug x => _1; // in scope 0 at $DIR/inline_trait_method.rs:+0:9: +0:10
+ let mut _0: u32; // return place in scope 0 at $DIR/inline_trait_method.rs:+0:23: +0:26
+ let mut _2: &dyn X; // in scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10
bb0: {
- StorageLive(_2); // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10
- _2 = &(*_1); // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10
- _0 = <dyn X as X>::y(move _2) -> bb1; // scope 0 at $DIR/inline-trait-method.rs:+1:5: +1:10
+ StorageLive(_2); // scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10
+ _2 = &(*_1); // scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10
+ _0 = <dyn X as X>::y(move _2) -> bb1; // scope 0 at $DIR/inline_trait_method.rs:+1:5: +1:10
// mir::Constant
- // + span: $DIR/inline-trait-method.rs:9:7: 9:8
+ // + span: $DIR/inline_trait_method.rs:9:7: 9:8
// + literal: Const { ty: for<'a> fn(&'a dyn X) -> u32 {<dyn X as X>::y}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_2); // scope 0 at $DIR/inline-trait-method.rs:+1:9: +1:10
- return; // scope 0 at $DIR/inline-trait-method.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/inline_trait_method.rs:+1:9: +1:10
+ return; // scope 0 at $DIR/inline_trait_method.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/inline-trait-method_2.rs b/src/test/mir-opt/inline/inline_trait_method_2.rs
index 378e71a25..378e71a25 100644
--- a/src/test/mir-opt/inline/inline-trait-method_2.rs
+++ b/src/test/mir-opt/inline/inline_trait_method_2.rs
diff --git a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
index 3d05869fa..73aea719e 100644
--- a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
+++ b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir
@@ -1,32 +1,28 @@
// MIR for `test2` after Inline
fn test2(_1: &dyn X) -> bool {
- debug x => _1; // in scope 0 at $DIR/inline-trait-method_2.rs:+0:10: +0:11
- let mut _0: bool; // return place in scope 0 at $DIR/inline-trait-method_2.rs:+0:24: +0:28
- let mut _2: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
- let mut _3: &dyn X; // in scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
- scope 1 (inlined test) { // at $DIR/inline-trait-method_2.rs:5:5: 5:12
- debug x => _2; // in scope 1 at $DIR/inline-trait-method_2.rs:9:9: 9:10
- let mut _4: &dyn X; // in scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10
+ debug x => _1; // in scope 0 at $DIR/inline_trait_method_2.rs:+0:10: +0:11
+ let mut _0: bool; // return place in scope 0 at $DIR/inline_trait_method_2.rs:+0:24: +0:28
+ let mut _2: &dyn X; // in scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11
+ let mut _3: &dyn X; // in scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11
+ scope 1 (inlined test) { // at $DIR/inline_trait_method_2.rs:5:5: 5:12
+ debug x => _2; // in scope 1 at $DIR/inline_trait_method_2.rs:9:9: 9:10
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
- StorageLive(_3); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
- _3 = &(*_1); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
- _2 = move _3 as &dyn X (Pointer(Unsize)); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
- StorageDead(_3); // scope 0 at $DIR/inline-trait-method_2.rs:+1:10: +1:11
- StorageLive(_4); // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10
- _4 = _2; // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10
- _0 = <dyn X as X>::y(move _4) -> bb1; // scope 1 at $DIR/inline-trait-method_2.rs:10:5: 10:10
+ StorageLive(_2); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11
+ StorageLive(_3); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11
+ _3 = &(*_1); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11
+ _2 = move _3 as &dyn X (Pointer(Unsize)); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11
+ StorageDead(_3); // scope 0 at $DIR/inline_trait_method_2.rs:+1:10: +1:11
+ _0 = <dyn X as X>::y(move _2) -> bb1; // scope 1 at $DIR/inline_trait_method_2.rs:10:5: 10:10
// mir::Constant
- // + span: $DIR/inline-trait-method_2.rs:10:7: 10:8
+ // + span: $DIR/inline_trait_method_2.rs:10:7: 10:8
// + literal: Const { ty: for<'a> fn(&'a dyn X) -> bool {<dyn X as X>::y}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_4); // scope 1 at $DIR/inline-trait-method_2.rs:10:9: 10:10
- StorageDead(_2); // scope 0 at $DIR/inline-trait-method_2.rs:+1:11: +1:12
- return; // scope 0 at $DIR/inline-trait-method_2.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/inline_trait_method_2.rs:+1:11: +1:12
+ return; // scope 0 at $DIR/inline_trait_method_2.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir
index 5168ae031..777681e1c 100644
--- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir
@@ -1,30 +1,30 @@
// MIR for `a` after Inline
fn a(_1: &mut [T]) -> &mut [T] {
- debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14
- let mut _0: &mut [T]; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:29: +0:37
- let mut _2: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- let mut _3: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- let mut _4: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- scope 1 (inlined <[T] as AsMut<[T]>>::as_mut) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
+ debug x => _1; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:13: +0:14
+ let mut _0: &mut [T]; // return place in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:29: +0:37
+ let mut _2: &mut [T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ let mut _3: &mut [T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ let mut _4: &mut [T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ scope 1 (inlined <[T] as AsMut<[T]>>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:3:5: 3:15
debug self => _4; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
let mut _5: &mut [T]; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageLive(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ _4 = &mut (*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
StorageLive(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
_5 = &mut (*_4); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
_3 = &mut (*_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
StorageDead(_5); // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15
- _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
- StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
- return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2
+ _2 = &mut (*_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageDead(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15
+ _0 = &mut (*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2
+ StorageDead(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
index 06d442ae8..83545c991 100644
--- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir
@@ -1,12 +1,12 @@
// MIR for `b` after Inline
fn b(_1: &mut Box<T>) -> &mut T {
- debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14
- let mut _0: &mut T; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:32: +0:38
- let mut _2: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- let mut _3: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- let mut _4: &mut std::boxed::Box<T>; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- scope 1 (inlined <Box<T> as AsMut<T>>::as_mut) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
+ debug x => _1; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:13: +0:14
+ let mut _0: &mut T; // return place in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:32: +0:38
+ let mut _2: &mut T; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ let mut _3: &mut T; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ let mut _4: &mut std::boxed::Box<T>; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ scope 1 (inlined <Box<T> as AsMut<T>>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:8:5: 8:15
debug self => _4; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
let mut _5: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
let mut _6: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
@@ -15,10 +15,10 @@ fn b(_1: &mut Box<T>) -> &mut T {
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageLive(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ _4 = &mut (*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
StorageLive(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_7 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
@@ -28,11 +28,11 @@ fn b(_1: &mut Box<T>) -> &mut T {
_3 = &mut (*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
StorageDead(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
StorageDead(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
- _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15
- _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
- StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
- return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2
+ _2 = &mut (*_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageDead(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15
+ _0 = &mut (*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2
+ StorageDead(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir
index c7f20ff98..ed4e9927c 100644
--- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir
@@ -1,22 +1,22 @@
// MIR for `c` after Inline
fn c(_1: &[T]) -> &[T] {
- debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14
- let mut _0: &[T]; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:25: +0:29
- let _2: &[T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- let mut _3: &[T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- scope 1 (inlined <[T] as AsRef<[T]>>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:5: 13:15
+ debug x => _1; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:13: +0:14
+ let mut _0: &[T]; // return place in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:25: +0:29
+ let _2: &[T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ let mut _3: &[T]; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ scope 1 (inlined <[T] as AsRef<[T]>>::as_ref) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:13:5: 13:15
debug self => _3; // in scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- _3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ _3 = &(*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
_2 = _3; // scope 1 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- _0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15
- StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
- return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2
+ _0 = &(*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15
+ StorageDead(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
index d5f06c54a..18a2670be 100644
--- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir
@@ -1,26 +1,26 @@
// MIR for `d` after Inline
fn d(_1: &Box<T>) -> &T {
- debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:13: +0:14
- let mut _0: &T; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+0:28: +0:30
- let _2: &T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- let mut _3: &std::boxed::Box<T>; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- scope 1 (inlined <Box<T> as AsRef<T>>::as_ref) { // at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
+ debug x => _1; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:13: +0:14
+ let mut _0: &T; // return place in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+0:28: +0:30
+ let _2: &T; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ let mut _3: &std::boxed::Box<T>; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ scope 1 (inlined <Box<T> as AsRef<T>>::as_ref) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:18:5: 18:15
debug self => _3; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
let mut _4: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
let mut _5: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- _3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
+ StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ _3 = &(*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
_4 = deref_copy (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_5 = (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
_2 = &(*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
- _0 = &(*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:5: +1:15
- StorageDead(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+1:14: +1:15
- StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:1: +2:2
- return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:+2:2: +2:2
+ _0 = &(*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
+ StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15
+ StorageDead(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs
index 94f926d39..94f926d39 100644
--- a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs
+++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.rs
diff --git a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir
index fca53a72f..d99ae1a6c 100644
--- a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir
+++ b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir
@@ -1,42 +1,42 @@
// MIR for `main` after Inline
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+0:11: +0:11
- let _1: [closure@$DIR/issue-76997-inline-scopes-parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10
- let mut _2: &[closure@$DIR/issue-76997-inline-scopes-parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6
- let mut _3: ((),); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
- let mut _4: (); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9
- let mut _5: (); // in scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
+ let mut _0: (); // return place in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+0:11: +0:11
+ let _1: [closure@$DIR/issue_76997_inline_scopes_parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:9: +1:10
+ let mut _2: &[closure@$DIR/issue_76997_inline_scopes_parenting.rs:5:13: 5:16]; // in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:6
+ let mut _3: ((),); // in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10
+ let mut _4: (); // in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:7: +2:9
+ let mut _5: (); // in scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10
scope 1 {
- debug f => _1; // in scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10
- scope 2 (inlined main::{closure#0}) { // at $DIR/issue-76997-inline-scopes-parenting.rs:6:5: 6:10
- debug x => _5; // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:14: +1:15
- let _6: (); // in scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24
+ debug f => _1; // in scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:9: +1:10
+ scope 2 (inlined main::{closure#0}) { // at $DIR/issue_76997_inline_scopes_parenting.rs:6:5: 6:10
+ debug x => _5; // in scope 2 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:14: +1:15
+ let _6: (); // in scope 2 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:23: +1:24
scope 3 {
- debug y => _6; // in scope 3 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24
+ debug y => _6; // in scope 3 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:23: +1:24
}
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:9: +1:10
- Deinit(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:13: +1:33
- StorageLive(_2); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6
- _2 = &_1; // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:6
- StorageLive(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
- StorageLive(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9
- Deinit(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:7: +2:9
- Deinit(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
- (_3.0: ()) = move _4; // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
- StorageLive(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
- _5 = move (_3.0: ()); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
- StorageLive(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:23: +1:24
- StorageDead(_6); // scope 2 at $DIR/issue-76997-inline-scopes-parenting.rs:+1:32: +1:33
- StorageDead(_5); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:5: +2:10
- StorageDead(_4); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10
- StorageDead(_3); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10
- StorageDead(_2); // scope 1 at $DIR/issue-76997-inline-scopes-parenting.rs:+2:9: +2:10
- StorageDead(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+3:1: +3:2
- return; // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:+3:2: +3:2
+ StorageLive(_1); // scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:9: +1:10
+ Deinit(_1); // scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:13: +1:33
+ StorageLive(_2); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:6
+ _2 = &_1; // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:6
+ StorageLive(_3); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10
+ StorageLive(_4); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:7: +2:9
+ Deinit(_4); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:7: +2:9
+ Deinit(_3); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10
+ (_3.0: ()) = move _4; // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10
+ StorageLive(_5); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10
+ _5 = move (_3.0: ()); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10
+ StorageLive(_6); // scope 2 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:23: +1:24
+ StorageDead(_6); // scope 2 at $DIR/issue_76997_inline_scopes_parenting.rs:+1:32: +1:33
+ StorageDead(_5); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:5: +2:10
+ StorageDead(_4); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:9: +2:10
+ StorageDead(_3); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:9: +2:10
+ StorageDead(_2); // scope 1 at $DIR/issue_76997_inline_scopes_parenting.rs:+2:9: +2:10
+ StorageDead(_1); // scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/issue_76997_inline_scopes_parenting.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.rs
index 76d806acc..76d806acc 100644
--- a/src/test/mir-opt/inline/issue-76997-inline-scopes-parenting.rs
+++ b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.rs
diff --git a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff
index 4186650df..51a98465f 100644
--- a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff
+++ b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff
@@ -2,67 +2,67 @@
+ // MIR for `bar` after Inline
fn bar(_1: P) -> () {
- debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:+2:5: +2:9
- let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:+3:3: +3:3
- let _2: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
- let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
- let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
- let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
-+ scope 1 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) { // at $DIR/issue-78442.rs:11:5: 11:17
+ debug _baz => _1; // in scope 0 at $DIR/issue_78442.rs:+2:5: +2:9
+ let mut _0: (); // return place in scope 0 at $DIR/issue_78442.rs:+3:3: +3:3
+ let _2: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
+ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
+ let _4: fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
+ let mut _5: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
++ scope 1 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) { // at $DIR/issue_78442.rs:11:5: 11:17
+ }
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
- StorageLive(_3); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
- StorageLive(_4); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
-- _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
-+ _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ StorageLive(_2); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
+ StorageLive(_3); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
+ StorageLive(_4); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
+- _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
++ _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
// mir::Constant
- // + span: $DIR/issue-78442.rs:11:5: 11:13
+ // + span: $DIR/issue_78442.rs:11:5: 11:13
// + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(<ZST>) }
}
bb1: {
- _3 = &_4; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
- StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
- Deinit(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
-- _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+ _3 = &_4; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
+ StorageLive(_5); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
+ Deinit(_5); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
+- _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
- // mir::Constant
-- // + span: $DIR/issue-78442.rs:11:5: 11:15
+- // + span: $DIR/issue_78442.rs:11:5: 11:15
- // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() {foo}, ()) -> <fn() {foo} as FnOnce<()>>::Output {<fn() {foo} as Fn<()>>::call}, val: Value(<ZST>) }
+ _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $SRC_DIR/core/src/ops/function.rs:LL:COL
}
bb2: {
-- StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
-- StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
-- StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
-- StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
-- _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2
-- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
-+ return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2
+- StorageDead(_5); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17
+- StorageDead(_3); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17
+- StorageDead(_4); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18
+- StorageDead(_2); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18
+- _0 = const (); // scope 0 at $DIR/issue_78442.rs:+3:3: +5:2
+- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2
++ return; // scope 0 at $DIR/issue_78442.rs:+5:2: +5:2
}
- bb3: {
-- return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2
+- return; // scope 0 at $DIR/issue_78442.rs:+5:2: +5:2
+ bb3 (cleanup): {
-+ drop(_1) -> bb4; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
++ drop(_1) -> bb4; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2
}
bb4 (cleanup): {
-- drop(_1) -> bb5; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
-+ resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2
+- drop(_1) -> bb5; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2
++ resume; // scope 0 at $DIR/issue_78442.rs:+0:1: +5:2
}
- bb5 (cleanup): {
-- resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2
+- resume; // scope 0 at $DIR/issue_78442.rs:+0:1: +5:2
+ bb5: {
-+ StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
-+ StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
-+ StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
-+ StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
-+ _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2
-+ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
++ StorageDead(_5); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17
++ StorageDead(_3); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17
++ StorageDead(_4); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18
++ StorageDead(_2); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18
++ _0 = const (); // scope 0 at $DIR/issue_78442.rs:+3:3: +5:2
++ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2
}
}
diff --git a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff
index 24e9a3df1..e47466c5e 100644
--- a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff
+++ b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff
@@ -2,56 +2,56 @@
+ // MIR for `bar` after RevealAll
fn bar(_1: P) -> () {
- debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:+2:5: +2:9
- let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:+3:3: +3:3
- let _2: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
-- let mut _3: &impl Fn(); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
-- let _4: impl Fn(); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
-+ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
-+ let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
- let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+ debug _baz => _1; // in scope 0 at $DIR/issue_78442.rs:+2:5: +2:9
+ let mut _0: (); // return place in scope 0 at $DIR/issue_78442.rs:+3:3: +3:3
+ let _2: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
+- let mut _3: &impl Fn(); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
+- let _4: impl Fn(); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
++ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
++ let _4: fn() {foo}; // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
+ let mut _5: (); // in scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
- StorageLive(_3); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
- StorageLive(_4); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
- _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
+ StorageLive(_2); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
+ StorageLive(_3); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
+ StorageLive(_4); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
+ _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
// mir::Constant
- // + span: $DIR/issue-78442.rs:11:5: 11:13
+ // + span: $DIR/issue_78442.rs:11:5: 11:13
// + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(<ZST>) }
}
bb1: {
- _3 = &_4; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15
- StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
- Deinit(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
-- _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
-+ _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17
+ _3 = &_4; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:15
+ StorageLive(_5); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
+ Deinit(_5); // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
+- _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
++ _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_78442.rs:+4:5: +4:17
// mir::Constant
- // + span: $DIR/issue-78442.rs:11:5: 11:15
+ // + span: $DIR/issue_78442.rs:11:5: 11:15
- // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(), ()) -> <impl Fn() as FnOnce<()>>::Output {<impl Fn() as Fn<()>>::call}, val: Value(<ZST>) }
+ // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a fn() {foo}, ()) -> <fn() {foo} as FnOnce<()>>::Output {<fn() {foo} as Fn<()>>::call}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
- StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17
- StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
- StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18
- _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2
- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
+ StorageDead(_5); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17
+ StorageDead(_3); // scope 0 at $DIR/issue_78442.rs:+4:16: +4:17
+ StorageDead(_4); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18
+ StorageDead(_2); // scope 0 at $DIR/issue_78442.rs:+4:17: +4:18
+ _0 = const (); // scope 0 at $DIR/issue_78442.rs:+3:3: +5:2
+ drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2
}
bb3: {
- return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2
+ return; // scope 0 at $DIR/issue_78442.rs:+5:2: +5:2
}
bb4 (cleanup): {
- drop(_1) -> bb5; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2
+ drop(_1) -> bb5; // scope 0 at $DIR/issue_78442.rs:+5:1: +5:2
}
bb5 (cleanup): {
- resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2
+ resume; // scope 0 at $DIR/issue_78442.rs:+0:1: +5:2
}
}
diff --git a/src/test/mir-opt/inline/issue-78442.rs b/src/test/mir-opt/inline/issue_78442.rs
index aa8ede2df..aa8ede2df 100644
--- a/src/test/mir-opt/inline/issue-78442.rs
+++ b/src/test/mir-opt/inline/issue_78442.rs
diff --git a/src/test/mir-opt/inline/polymorphic-recursion.rs b/src/test/mir-opt/inline/polymorphic_recursion.rs
index 7388722b7..7388722b7 100644
--- a/src/test/mir-opt/inline/polymorphic-recursion.rs
+++ b/src/test/mir-opt/inline/polymorphic_recursion.rs
diff --git a/src/test/mir-opt/issue_101973.inner.ConstProp.diff b/src/test/mir-opt/issue_101973.inner.ConstProp.diff
index 281afe4be..8fe60a024 100644
--- a/src/test/mir-opt/issue_101973.inner.ConstProp.diff
+++ b/src/test/mir-opt/issue_101973.inner.ConstProp.diff
@@ -2,99 +2,94 @@
+ // MIR for `inner` after ConstProp
fn inner(_1: u32) -> i64 {
- debug fields => _1; // in scope 0 at $DIR/issue-101973.rs:+0:14: +0:20
- let mut _0: i64; // return place in scope 0 at $DIR/issue-101973.rs:+0:30: +0:33
- let mut _2: i32; // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:65
- let mut _3: u32; // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:58
- let mut _4: u32; // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:17
- let mut _5: u32; // in scope 0 at $DIR/issue-101973.rs:+1:10: +1:16
- let mut _6: u32; // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
- let mut _7: u32; // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:52
- let mut _8: u32; // in scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
- let mut _9: u32; // in scope 0 at $DIR/issue-101973.rs:+1:33: +1:39
- let mut _10: (u32, bool); // in scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
- let mut _11: (u32, bool); // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
- scope 1 (inlined imm8) { // at $DIR/issue-101973.rs:14:5: 14:17
- debug x => _5; // in scope 1 at $DIR/issue-101973.rs:5:13: 5:14
- let mut _12: u32; // in scope 1 at $DIR/issue-101973.rs:7:12: 7:27
- let mut _13: u32; // in scope 1 at $DIR/issue-101973.rs:7:12: 7:20
- let mut _14: u32; // in scope 1 at $DIR/issue-101973.rs:7:13: 7:14
- let mut _15: (u32, bool); // in scope 1 at $DIR/issue-101973.rs:7:12: 7:20
+ debug fields => _1; // in scope 0 at $DIR/issue_101973.rs:+0:14: +0:20
+ let mut _0: i64; // return place in scope 0 at $DIR/issue_101973.rs:+0:30: +0:33
+ let mut _2: i32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:65
+ let mut _3: u32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:58
+ let mut _4: u32; // in scope 0 at $DIR/issue_101973.rs:+1:5: +1:17
+ let mut _5: u32; // in scope 0 at $DIR/issue_101973.rs:+1:10: +1:16
+ let mut _6: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ let mut _7: u32; // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:52
+ let mut _8: u32; // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ let mut _9: u32; // in scope 0 at $DIR/issue_101973.rs:+1:33: +1:39
+ let mut _10: (u32, bool); // in scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ let mut _11: (u32, bool); // in scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ scope 1 (inlined imm8) { // at $DIR/issue_101973.rs:14:5: 14:17
+ debug x => _5; // in scope 1 at $DIR/issue_101973.rs:5:13: 5:14
+ let mut _12: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:27
+ let mut _13: u32; // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20
+ let mut _14: (u32, bool); // in scope 1 at $DIR/issue_101973.rs:7:12: 7:20
scope 2 {
- debug out => _4; // in scope 2 at $DIR/issue-101973.rs:6:9: 6:16
+ debug out => _4; // in scope 2 at $DIR/issue_101973.rs:6:9: 6:16
}
}
- scope 3 (inlined core::num::<impl u32>::rotate_right) { // at $DIR/issue-101973.rs:14:5: 14:58
+ scope 3 (inlined core::num::<impl u32>::rotate_right) { // at $DIR/issue_101973.rs:14:5: 14:58
debug self => _4; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
debug n => _6; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ let mut _15: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
let mut _16: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
- let mut _17: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:65
- StorageLive(_3); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:58
- StorageLive(_4); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:17
- StorageLive(_5); // scope 0 at $DIR/issue-101973.rs:+1:10: +1:16
- _5 = _1; // scope 0 at $DIR/issue-101973.rs:+1:10: +1:16
- _4 = const 0_u32; // scope 1 at $DIR/issue-101973.rs:6:19: 6:23
- StorageLive(_12); // scope 2 at $DIR/issue-101973.rs:7:12: 7:27
- StorageLive(_13); // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
- StorageLive(_14); // scope 2 at $DIR/issue-101973.rs:7:13: 7:14
- _14 = _5; // scope 2 at $DIR/issue-101973.rs:7:13: 7:14
- _15 = CheckedShr(_14, const 0_i32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
- assert(!move (_15.1: bool), "attempt to shift right by `{}`, which would overflow", const 0_i32) -> bb3; // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
+ StorageLive(_2); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65
+ StorageLive(_3); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:58
+ StorageLive(_4); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:17
+ StorageLive(_5); // scope 0 at $DIR/issue_101973.rs:+1:10: +1:16
+ _5 = _1; // scope 0 at $DIR/issue_101973.rs:+1:10: +1:16
+ StorageLive(_12); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27
+ StorageLive(_13); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
+ _14 = CheckedShr(_5, const 0_i32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
+ assert(!move (_14.1: bool), "attempt to shift right by `{}`, which would overflow", const 0_i32) -> bb3; // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
}
bb1: {
- _8 = move (_10.0: u32); // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
- StorageDead(_9); // scope 0 at $DIR/issue-101973.rs:+1:44: +1:45
- _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:52
- StorageDead(_8); // scope 0 at $DIR/issue-101973.rs:+1:51: +1:52
- _11 = CheckedShl(_7, const 1_i32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
- assert(!move (_11.1: bool), "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+ _8 = move (_10.0: u32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ StorageDead(_9); // scope 0 at $DIR/issue_101973.rs:+1:44: +1:45
+ _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52
+ StorageDead(_8); // scope 0 at $DIR/issue_101973.rs:+1:51: +1:52
+ _11 = CheckedShl(_7, const 1_i32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ assert(!move (_11.1: bool), "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
}
bb2: {
- _6 = move (_11.0: u32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
- StorageDead(_7); // scope 0 at $DIR/issue-101973.rs:+1:56: +1:57
+ _6 = move (_11.0: u32); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ StorageDead(_7); // scope 0 at $DIR/issue_101973.rs:+1:56: +1:57
+ StorageLive(_15); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ _15 = _4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
StorageLive(_16); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
- _16 = _4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
- StorageLive(_17); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
- _17 = _6; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
- _3 = rotate_right::<u32>(move _16, move _17) -> bb4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ _16 = _6; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ _3 = rotate_right::<u32>(move _15, move _16) -> bb4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
// + literal: Const { ty: extern "rust-intrinsic" fn(u32, u32) -> u32 {rotate_right::<u32>}, val: Value(<ZST>) }
}
bb3: {
- _13 = move (_15.0: u32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
- StorageDead(_14); // scope 2 at $DIR/issue-101973.rs:7:19: 7:20
- _12 = BitAnd(move _13, const 255_u32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:27
- StorageDead(_13); // scope 2 at $DIR/issue-101973.rs:7:26: 7:27
- _4 = BitOr(_4, move _12); // scope 2 at $DIR/issue-101973.rs:7:5: 7:27
- StorageDead(_12); // scope 2 at $DIR/issue-101973.rs:7:26: 7:27
- StorageDead(_5); // scope 0 at $DIR/issue-101973.rs:+1:16: +1:17
- StorageLive(_6); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
- StorageLive(_7); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:52
- StorageLive(_8); // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
- StorageLive(_9); // scope 0 at $DIR/issue-101973.rs:+1:33: +1:39
- _9 = _1; // scope 0 at $DIR/issue-101973.rs:+1:33: +1:39
- _10 = CheckedShr(_9, const 8_i32); // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
- assert(!move (_10.1: bool), "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+ _13 = move (_14.0: u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20
+ _12 = BitAnd(move _13, const 255_u32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27
+ StorageDead(_13); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27
+ _4 = BitOr(const 0_u32, move _12); // scope 2 at $DIR/issue_101973.rs:7:5: 7:27
+ StorageDead(_12); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27
+ StorageDead(_5); // scope 0 at $DIR/issue_101973.rs:+1:16: +1:17
+ StorageLive(_6); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57
+ StorageLive(_7); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52
+ StorageLive(_8); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ StorageLive(_9); // scope 0 at $DIR/issue_101973.rs:+1:33: +1:39
+ _9 = _1; // scope 0 at $DIR/issue_101973.rs:+1:33: +1:39
+ _10 = CheckedShr(_9, const 8_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
+ assert(!move (_10.1: bool), "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45
}
bb4: {
- StorageDead(_17); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
StorageDead(_16); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
- StorageDead(_6); // scope 0 at $DIR/issue-101973.rs:+1:57: +1:58
- StorageDead(_4); // scope 0 at $DIR/issue-101973.rs:+1:57: +1:58
- _2 = move _3 as i32 (IntToInt); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:65
- StorageDead(_3); // scope 0 at $DIR/issue-101973.rs:+1:64: +1:65
- _0 = move _2 as i64 (IntToInt); // scope 0 at $DIR/issue-101973.rs:+1:5: +1:72
- StorageDead(_2); // scope 0 at $DIR/issue-101973.rs:+1:71: +1:72
- return; // scope 0 at $DIR/issue-101973.rs:+2:2: +2:2
+ StorageDead(_15); // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+ StorageDead(_6); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58
+ StorageDead(_4); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58
+ _2 = move _3 as i32 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65
+ StorageDead(_3); // scope 0 at $DIR/issue_101973.rs:+1:64: +1:65
+ _0 = move _2 as i64 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:72
+ StorageDead(_2); // scope 0 at $DIR/issue_101973.rs:+1:71: +1:72
+ return; // scope 0 at $DIR/issue_101973.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/issue-101973.rs b/src/test/mir-opt/issue_101973.rs
index 216659a23..216659a23 100644
--- a/src/test/mir-opt/issue-101973.rs
+++ b/src/test/mir-opt/issue_101973.rs
diff --git a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir
index b13987f73..822100818 100644
--- a/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/issue_38669.main.SimplifyCfg-initial.after.mir
@@ -1,52 +1,52 @@
// MIR for `main` after SimplifyCfg-initial
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-38669.rs:+0:11: +0:11
- let mut _1: bool; // in scope 0 at $DIR/issue-38669.rs:+1:9: +1:25
- let mut _2: (); // in scope 0 at $DIR/issue-38669.rs:+0:1: +8:2
- let _3: (); // in scope 0 at $DIR/issue-38669.rs:+3:9: +5:10
- let mut _4: bool; // in scope 0 at $DIR/issue-38669.rs:+3:12: +3:24
- let mut _5: !; // in scope 0 at $DIR/issue-38669.rs:+3:25: +5:10
+ let mut _0: (); // return place in scope 0 at $DIR/issue_38669.rs:+0:11: +0:11
+ let mut _1: bool; // in scope 0 at $DIR/issue_38669.rs:+1:9: +1:25
+ let mut _2: (); // in scope 0 at $DIR/issue_38669.rs:+0:1: +8:2
+ let _3: (); // in scope 0 at $DIR/issue_38669.rs:+3:9: +5:10
+ let mut _4: bool; // in scope 0 at $DIR/issue_38669.rs:+3:12: +3:24
+ let mut _5: !; // in scope 0 at $DIR/issue_38669.rs:+3:25: +5:10
scope 1 {
- debug should_break => _1; // in scope 1 at $DIR/issue-38669.rs:+1:9: +1:25
+ debug should_break => _1; // in scope 1 at $DIR/issue_38669.rs:+1:9: +1:25
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-38669.rs:+1:9: +1:25
- _1 = const false; // scope 0 at $DIR/issue-38669.rs:+1:28: +1:33
- FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue-38669.rs:+1:9: +1:25
- goto -> bb1; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6
+ StorageLive(_1); // scope 0 at $DIR/issue_38669.rs:+1:9: +1:25
+ _1 = const false; // scope 0 at $DIR/issue_38669.rs:+1:28: +1:33
+ FakeRead(ForLet(None), _1); // scope 0 at $DIR/issue_38669.rs:+1:9: +1:25
+ goto -> bb1; // scope 1 at $DIR/issue_38669.rs:+2:5: +7:6
}
bb1: {
- falseUnwind -> [real: bb2, cleanup: bb5]; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6
+ falseUnwind -> [real: bb2, cleanup: bb5]; // scope 1 at $DIR/issue_38669.rs:+2:5: +7:6
}
bb2: {
- StorageLive(_3); // scope 1 at $DIR/issue-38669.rs:+3:9: +5:10
- StorageLive(_4); // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24
- _4 = _1; // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24
- switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/issue-38669.rs:+3:12: +3:24
+ StorageLive(_3); // scope 1 at $DIR/issue_38669.rs:+3:9: +5:10
+ StorageLive(_4); // scope 1 at $DIR/issue_38669.rs:+3:12: +3:24
+ _4 = _1; // scope 1 at $DIR/issue_38669.rs:+3:12: +3:24
+ switchInt(move _4) -> [false: bb4, otherwise: bb3]; // scope 1 at $DIR/issue_38669.rs:+3:12: +3:24
}
bb3: {
- _0 = const (); // scope 1 at $DIR/issue-38669.rs:+4:13: +4:18
- StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10
- StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10
- StorageDead(_1); // scope 0 at $DIR/issue-38669.rs:+8:1: +8:2
- return; // scope 0 at $DIR/issue-38669.rs:+8:2: +8:2
+ _0 = const (); // scope 1 at $DIR/issue_38669.rs:+4:13: +4:18
+ StorageDead(_4); // scope 1 at $DIR/issue_38669.rs:+5:9: +5:10
+ StorageDead(_3); // scope 1 at $DIR/issue_38669.rs:+5:9: +5:10
+ StorageDead(_1); // scope 0 at $DIR/issue_38669.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/issue_38669.rs:+8:2: +8:2
}
bb4: {
- _3 = const (); // scope 1 at $DIR/issue-38669.rs:+5:10: +5:10
- StorageDead(_4); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10
- StorageDead(_3); // scope 1 at $DIR/issue-38669.rs:+5:9: +5:10
- _1 = const true; // scope 1 at $DIR/issue-38669.rs:+6:9: +6:28
- _2 = const (); // scope 1 at $DIR/issue-38669.rs:+2:10: +7:6
- goto -> bb1; // scope 1 at $DIR/issue-38669.rs:+2:5: +7:6
+ _3 = const (); // scope 1 at $DIR/issue_38669.rs:+5:10: +5:10
+ StorageDead(_4); // scope 1 at $DIR/issue_38669.rs:+5:9: +5:10
+ StorageDead(_3); // scope 1 at $DIR/issue_38669.rs:+5:9: +5:10
+ _1 = const true; // scope 1 at $DIR/issue_38669.rs:+6:9: +6:28
+ _2 = const (); // scope 1 at $DIR/issue_38669.rs:+2:10: +7:6
+ goto -> bb1; // scope 1 at $DIR/issue_38669.rs:+2:5: +7:6
}
bb5 (cleanup): {
- resume; // scope 0 at $DIR/issue-38669.rs:+0:1: +8:2
+ resume; // scope 0 at $DIR/issue_38669.rs:+0:1: +8:2
}
}
diff --git a/src/test/mir-opt/issue-38669.rs b/src/test/mir-opt/issue_38669.rs
index db3f89472..db3f89472 100644
--- a/src/test/mir-opt/issue-38669.rs
+++ b/src/test/mir-opt/issue_38669.rs
diff --git a/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir
index 1d7cb91d6..c573ad5a8 100644
--- a/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir
+++ b/src/test/mir-opt/issue_41110.main.ElaborateDrops.after.mir
@@ -1,70 +1,70 @@
// MIR for `main` after ElaborateDrops
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-41110.rs:+0:11: +0:11
- let _1: (); // in scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
- let mut _2: S; // in scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
- let mut _3: S; // in scope 0 at $DIR/issue-41110.rs:+1:21: +1:27
- let mut _4: S; // in scope 0 at $DIR/issue-41110.rs:+1:21: +1:22
- let mut _5: bool; // in scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ let mut _0: (); // return place in scope 0 at $DIR/issue_41110.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+ let mut _2: S; // in scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+ let mut _3: S; // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
+ let mut _4: S; // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
+ let mut _5: bool; // in scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
scope 1 {
- debug x => _1; // in scope 1 at $DIR/issue-41110.rs:+1:9: +1:10
+ debug x => _1; // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10
}
bb0: {
- _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
- StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
- StorageLive(_2); // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
- _5 = const true; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
- _2 = S; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
- StorageLive(_3); // scope 0 at $DIR/issue-41110.rs:+1:21: +1:27
- StorageLive(_4); // scope 0 at $DIR/issue-41110.rs:+1:21: +1:22
- _4 = S; // scope 0 at $DIR/issue-41110.rs:+1:21: +1:22
- _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-41110.rs:+1:21: +1:27
+ _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+ StorageLive(_1); // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+ StorageLive(_2); // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+ _5 = const true; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+ _2 = S; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+ StorageLive(_3); // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
+ StorageLive(_4); // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
+ _4 = S; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22
+ _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27
// mir::Constant
- // + span: $DIR/issue-41110.rs:8:23: 8:25
+ // + span: $DIR/issue_41110.rs:8:23: 8:25
// + literal: Const { ty: fn(S) -> S {S::id}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_4); // scope 0 at $DIR/issue-41110.rs:+1:26: +1:27
- _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:28
- _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:28
+ StorageDead(_4); // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
+ _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28
+ _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28
// mir::Constant
- // + span: $DIR/issue-41110.rs:8:15: 8:20
+ // + span: $DIR/issue_41110.rs:8:15: 8:20
// + literal: Const { ty: fn(S, S) {S::other}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_3); // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
- _5 = const false; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
- StorageDead(_2); // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
- _0 = const (); // scope 0 at $DIR/issue-41110.rs:+0:11: +2:2
- StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:+2:1: +2:2
- return; // scope 0 at $DIR/issue-41110.rs:+2:2: +2:2
+ StorageDead(_3); // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+ _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+ StorageDead(_2); // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
+ _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:11: +2:2
+ StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue_41110.rs:+2:2: +2:2
}
bb3 (cleanup): {
- goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
}
bb4 (cleanup): {
- goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+1:26: +1:27
+ goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27
}
bb5 (cleanup): {
- goto -> bb8; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ goto -> bb8; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
}
bb6 (cleanup): {
- resume; // scope 0 at $DIR/issue-41110.rs:+0:1: +2:2
+ resume; // scope 0 at $DIR/issue_41110.rs:+0:1: +2:2
}
bb7 (cleanup): {
- drop(_2) -> bb6; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ drop(_2) -> bb6; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
}
bb8 (cleanup): {
- switchInt(_5) -> [false: bb6, otherwise: bb7]; // scope 0 at $DIR/issue-41110.rs:+1:27: +1:28
+ switchInt(_5) -> [false: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28
}
}
diff --git a/src/test/mir-opt/issue-41110.rs b/src/test/mir-opt/issue_41110.rs
index 638dc601e..638dc601e 100644
--- a/src/test/mir-opt/issue-41110.rs
+++ b/src/test/mir-opt/issue_41110.rs
diff --git a/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir
index b0e3496b2..470b03232 100644
--- a/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir
+++ b/src/test/mir-opt/issue_41110.test.ElaborateDrops.after.mir
@@ -1,101 +1,101 @@
// MIR for `test` after ElaborateDrops
fn test() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-41110.rs:+0:15: +0:15
- let _1: S; // in scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
- let _3: (); // in scope 0 at $DIR/issue-41110.rs:+3:5: +3:12
- let mut _4: S; // in scope 0 at $DIR/issue-41110.rs:+3:10: +3:11
- let mut _5: S; // in scope 0 at $DIR/issue-41110.rs:+4:9: +4:10
- let mut _6: bool; // in scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ let mut _0: (); // return place in scope 0 at $DIR/issue_41110.rs:+0:15: +0:15
+ let _1: S; // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+ let _3: (); // in scope 0 at $DIR/issue_41110.rs:+3:5: +3:12
+ let mut _4: S; // in scope 0 at $DIR/issue_41110.rs:+3:10: +3:11
+ let mut _5: S; // in scope 0 at $DIR/issue_41110.rs:+4:9: +4:10
+ let mut _6: bool; // in scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
scope 1 {
- debug u => _1; // in scope 1 at $DIR/issue-41110.rs:+1:9: +1:10
- let mut _2: S; // in scope 1 at $DIR/issue-41110.rs:+2:9: +2:14
+ debug u => _1; // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10
+ let mut _2: S; // in scope 1 at $DIR/issue_41110.rs:+2:9: +2:14
scope 2 {
- debug v => _2; // in scope 2 at $DIR/issue-41110.rs:+2:9: +2:14
+ debug v => _2; // in scope 2 at $DIR/issue_41110.rs:+2:9: +2:14
}
}
bb0: {
- _6 = const false; // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
- StorageLive(_1); // scope 0 at $DIR/issue-41110.rs:+1:9: +1:10
- _6 = const true; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
- _1 = S; // scope 0 at $DIR/issue-41110.rs:+1:13: +1:14
- StorageLive(_2); // scope 1 at $DIR/issue-41110.rs:+2:9: +2:14
- _2 = S; // scope 1 at $DIR/issue-41110.rs:+2:17: +2:18
- StorageLive(_3); // scope 2 at $DIR/issue-41110.rs:+3:5: +3:12
- StorageLive(_4); // scope 2 at $DIR/issue-41110.rs:+3:10: +3:11
- _4 = move _2; // scope 2 at $DIR/issue-41110.rs:+3:10: +3:11
- _3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue-41110.rs:+3:5: +3:12
+ _6 = const false; // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+ StorageLive(_1); // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10
+ _6 = const true; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+ _1 = S; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14
+ StorageLive(_2); // scope 1 at $DIR/issue_41110.rs:+2:9: +2:14
+ _2 = S; // scope 1 at $DIR/issue_41110.rs:+2:17: +2:18
+ StorageLive(_3); // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12
+ StorageLive(_4); // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11
+ _4 = move _2; // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11
+ _3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12
// mir::Constant
- // + span: $DIR/issue-41110.rs:17:5: 17:9
+ // + span: $DIR/issue_41110.rs:17:5: 17:9
// + literal: Const { ty: fn(S) {std::mem::drop::<S>}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_4); // scope 2 at $DIR/issue-41110.rs:+3:11: +3:12
- StorageDead(_3); // scope 2 at $DIR/issue-41110.rs:+3:12: +3:13
- StorageLive(_5); // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
- _6 = const false; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
- _5 = move _1; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
- goto -> bb12; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6
+ StorageDead(_4); // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
+ StorageDead(_3); // scope 2 at $DIR/issue_41110.rs:+3:12: +3:13
+ StorageLive(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+ _6 = const false; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+ _5 = move _1; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+ goto -> bb12; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
}
bb2: {
- goto -> bb3; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
+ goto -> bb3; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
}
bb3: {
- StorageDead(_5); // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
- _0 = const (); // scope 0 at $DIR/issue-41110.rs:+0:15: +5:2
- drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2
+ StorageDead(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
+ _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2
+ drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
}
bb4: {
- StorageDead(_2); // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2
- goto -> bb5; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ StorageDead(_2); // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
+ goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
}
bb5: {
- _6 = const false; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
- StorageDead(_1); // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
- return; // scope 0 at $DIR/issue-41110.rs:+5:2: +5:2
+ _6 = const false; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+ StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/issue_41110.rs:+5:2: +5:2
}
bb6 (cleanup): {
- goto -> bb8; // scope 2 at $DIR/issue-41110.rs:+4:9: +4:10
+ goto -> bb8; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10
}
bb7 (cleanup): {
- goto -> bb8; // scope 2 at $DIR/issue-41110.rs:+3:11: +3:12
+ goto -> bb8; // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12
}
bb8 (cleanup): {
- goto -> bb9; // scope 1 at $DIR/issue-41110.rs:+5:1: +5:2
+ goto -> bb9; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2
}
bb9 (cleanup): {
- goto -> bb14; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ goto -> bb14; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
}
bb10 (cleanup): {
- resume; // scope 0 at $DIR/issue-41110.rs:+0:1: +5:2
+ resume; // scope 0 at $DIR/issue_41110.rs:+0:1: +5:2
}
bb11 (cleanup): {
- _2 = move _5; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6
- goto -> bb6; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6
+ _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
+ goto -> bb6; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
}
bb12: {
- _2 = move _5; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6
- goto -> bb2; // scope 2 at $DIR/issue-41110.rs:+4:5: +4:6
+ _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
+ goto -> bb2; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6
}
bb13 (cleanup): {
- drop(_1) -> bb10; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ drop(_1) -> bb10; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
}
bb14 (cleanup): {
- switchInt(_6) -> [false: bb10, otherwise: bb13]; // scope 0 at $DIR/issue-41110.rs:+5:1: +5:2
+ switchInt(_6) -> [false: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2
}
}
diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue_41697.rs
index cbd8633a3..cbd8633a3 100644
--- a/src/test/mir-opt/issue-41697.rs
+++ b/src/test/mir-opt/issue_41697.rs
diff --git a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
index 047b24db4..8af087d84 100644
--- a/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
+++ b/src/test/mir-opt/issue_41697.{impl#0}-{constant#0}.SimplifyCfg-promote-consts.after.mir
@@ -1,20 +1,20 @@
-// MIR for `<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}` after SimplifyCfg-promote-consts
+// MIR for `<impl at $DIR/issue_41697.rs:18:1: 18:23>::{constant#0}` after SimplifyCfg-promote-consts
-<impl at $DIR/issue-41697.rs:18:1: 18:23>::{constant#0}: usize = {
- let mut _0: usize; // return place in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
- let mut _1: (usize, bool); // in scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+<impl at $DIR/issue_41697.rs:18:1: 18:23>::{constant#0}: usize = {
+ let mut _0: usize; // return place in scope 0 at $DIR/issue_41697.rs:+0:19: +0:22
+ let mut _1: (usize, bool); // in scope 0 at $DIR/issue_41697.rs:+0:19: +0:22
bb0: {
- _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
- assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ _1 = CheckedAdd(const 1_usize, const 1_usize); // scope 0 at $DIR/issue_41697.rs:+0:19: +0:22
+ assert(!move (_1.1: bool), "attempt to compute `{} + {}`, which would overflow", const 1_usize, const 1_usize) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue_41697.rs:+0:19: +0:22
}
bb1: {
- _0 = move (_1.0: usize); // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
- return; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ _0 = move (_1.0: usize); // scope 0 at $DIR/issue_41697.rs:+0:19: +0:22
+ return; // scope 0 at $DIR/issue_41697.rs:+0:19: +0:22
}
bb2 (cleanup): {
- resume; // scope 0 at $DIR/issue-41697.rs:+0:19: +0:22
+ resume; // scope 0 at $DIR/issue_41697.rs:+0:19: +0:22
}
}
diff --git a/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir
index f95a0a1c0..73372c97b 100644
--- a/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir
+++ b/src/test/mir-opt/issue_41888.main.ElaborateDrops.after.mir
@@ -1,152 +1,152 @@
// MIR for `main` after ElaborateDrops
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-41888.rs:+0:11: +0:11
- let _1: E; // in scope 0 at $DIR/issue-41888.rs:+1:9: +1:10
- let mut _2: bool; // in scope 0 at $DIR/issue-41888.rs:+2:8: +2:14
- let mut _3: E; // in scope 0 at $DIR/issue-41888.rs:+3:13: +3:20
- let mut _4: K; // in scope 0 at $DIR/issue-41888.rs:+3:18: +3:19
- let mut _5: isize; // in scope 0 at $DIR/issue-41888.rs:+4:16: +4:24
- let mut _7: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- let mut _8: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- let mut _9: bool; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- let mut _10: isize; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- let mut _11: isize; // in scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ let mut _0: (); // return place in scope 0 at $DIR/issue_41888.rs:+0:11: +0:11
+ let _1: E; // in scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+ let mut _2: bool; // in scope 0 at $DIR/issue_41888.rs:+2:8: +2:14
+ let mut _3: E; // in scope 0 at $DIR/issue_41888.rs:+3:13: +3:20
+ let mut _4: K; // in scope 0 at $DIR/issue_41888.rs:+3:18: +3:19
+ let mut _5: isize; // in scope 0 at $DIR/issue_41888.rs:+4:16: +4:24
+ let mut _7: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ let mut _8: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ let mut _9: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ let mut _10: isize; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ let mut _11: isize; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
scope 1 {
- debug e => _1; // in scope 1 at $DIR/issue-41888.rs:+1:9: +1:10
+ debug e => _1; // in scope 1 at $DIR/issue_41888.rs:+1:9: +1:10
scope 2 {
- debug _k => _6; // in scope 2 at $DIR/issue-41888.rs:+4:21: +4:23
- let _6: K; // in scope 2 at $DIR/issue-41888.rs:+4:21: +4:23
+ debug _k => _6; // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+ let _6: K; // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
}
}
bb0: {
- _9 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10
- _7 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10
- _8 = const false; // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10
- StorageLive(_1); // scope 0 at $DIR/issue-41888.rs:+1:9: +1:10
- StorageLive(_2); // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14
- _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14
+ _9 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+ _7 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+ _8 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+ StorageLive(_1); // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10
+ StorageLive(_2); // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
+ _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
// mir::Constant
- // + span: $DIR/issue-41888.rs:8:8: 8:12
+ // + span: $DIR/issue_41888.rs:8:8: 8:12
// + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
}
bb1: {
- switchInt(move _2) -> [false: bb7, otherwise: bb2]; // scope 1 at $DIR/issue-41888.rs:+2:8: +2:14
+ switchInt(move _2) -> [false: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14
}
bb2: {
- StorageLive(_3); // scope 1 at $DIR/issue-41888.rs:+3:13: +3:20
- StorageLive(_4); // scope 1 at $DIR/issue-41888.rs:+3:18: +3:19
- _4 = K; // scope 1 at $DIR/issue-41888.rs:+3:18: +3:19
- _3 = E::F(move _4); // scope 1 at $DIR/issue-41888.rs:+3:13: +3:20
- StorageDead(_4); // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20
- goto -> bb14; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ StorageLive(_3); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20
+ StorageLive(_4); // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19
+ _4 = K; // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19
+ _3 = E::F(move _4); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20
+ StorageDead(_4); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
+ goto -> bb14; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
}
bb3: {
- goto -> bb4; // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20
+ goto -> bb4; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
}
bb4: {
- StorageDead(_3); // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20
- _5 = discriminant(_1); // scope 2 at $DIR/issue-41888.rs:+4:16: +4:24
- switchInt(move _5) -> [0_isize: bb5, otherwise: bb6]; // scope 2 at $DIR/issue-41888.rs:+4:16: +4:24
+ StorageDead(_3); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
+ _5 = discriminant(_1); // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24
+ switchInt(move _5) -> [0_isize: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24
}
bb5: {
- StorageLive(_6); // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23
- _9 = const false; // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23
- _6 = move ((_1 as F).0: K); // scope 2 at $DIR/issue-41888.rs:+4:21: +4:23
- _0 = const (); // scope 2 at $DIR/issue-41888.rs:+4:29: +7:10
- StorageDead(_6); // scope 1 at $DIR/issue-41888.rs:+7:9: +7:10
- goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+4:9: +7:10
+ StorageLive(_6); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+ _9 = const false; // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+ _6 = move ((_1 as F).0: K); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23
+ _0 = const (); // scope 2 at $DIR/issue_41888.rs:+4:29: +7:10
+ StorageDead(_6); // scope 1 at $DIR/issue_41888.rs:+7:9: +7:10
+ goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10
}
bb6: {
- _0 = const (); // scope 1 at $DIR/issue-41888.rs:+7:10: +7:10
- goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+4:9: +7:10
+ _0 = const (); // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10
+ goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10
}
bb7: {
- _0 = const (); // scope 1 at $DIR/issue-41888.rs:+8:6: +8:6
- goto -> bb8; // scope 1 at $DIR/issue-41888.rs:+2:5: +8:6
+ _0 = const (); // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6
+ goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6
}
bb8: {
- StorageDead(_2); // scope 1 at $DIR/issue-41888.rs:+8:5: +8:6
- goto -> bb20; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ StorageDead(_2); // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6
+ goto -> bb20; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
}
bb9: {
- _7 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- _8 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- _9 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- StorageDead(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- return; // scope 0 at $DIR/issue-41888.rs:+9:2: +9:2
+ _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ _8 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ _9 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ StorageDead(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ return; // scope 0 at $DIR/issue_41888.rs:+9:2: +9:2
}
bb10 (cleanup): {
- goto -> bb11; // scope 1 at $DIR/issue-41888.rs:+3:19: +3:20
+ goto -> bb11; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20
}
bb11 (cleanup): {
- goto -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
}
bb12 (cleanup): {
- resume; // scope 0 at $DIR/issue-41888.rs:+0:1: +9:2
+ resume; // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2
}
bb13 (cleanup): {
- _7 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
- _8 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
- _9 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
- _1 = move _3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
- goto -> bb10; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
+ _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
+ _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
+ _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
+ goto -> bb10; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
}
bb14: {
- _7 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
- _8 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
- _9 = const true; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
- _1 = move _3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
- goto -> bb3; // scope 1 at $DIR/issue-41888.rs:+3:9: +3:10
+ _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
+ _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
+ _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
+ _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
+ goto -> bb3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10
}
bb15: {
- _7 = const false; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- goto -> bb9; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ goto -> bb9; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
}
bb16 (cleanup): {
- goto -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
}
bb17: {
- drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
}
bb18 (cleanup): {
- drop(_1) -> bb12; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ drop(_1) -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
}
bb19: {
- _10 = discriminant(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- switchInt(move _10) -> [0_isize: bb15, otherwise: bb17]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ _10 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ switchInt(move _10) -> [0_isize: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
}
bb20: {
- switchInt(_7) -> [false: bb15, otherwise: bb19]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ switchInt(_7) -> [false: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
}
bb21 (cleanup): {
- _11 = discriminant(_1); // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
- switchInt(move _11) -> [0_isize: bb16, otherwise: bb18]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ _11 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
+ switchInt(move _11) -> [0_isize: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
}
bb22 (cleanup): {
- switchInt(_7) -> [false: bb12, otherwise: bb21]; // scope 0 at $DIR/issue-41888.rs:+9:1: +9:2
+ switchInt(_7) -> [false: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2
}
}
diff --git a/src/test/mir-opt/issue-41888.rs b/src/test/mir-opt/issue_41888.rs
index c1046c14d..c1046c14d 100644
--- a/src/test/mir-opt/issue-41888.rs
+++ b/src/test/mir-opt/issue_41888.rs
diff --git a/src/test/mir-opt/issue-62289.rs b/src/test/mir-opt/issue_62289.rs
index 37e3390d5..37e3390d5 100644
--- a/src/test/mir-opt/issue-62289.rs
+++ b/src/test/mir-opt/issue_62289.rs
diff --git a/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir
index 72603dc5d..6969a66ac 100644
--- a/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir
+++ b/src/test/mir-opt/issue_62289.test.ElaborateDrops.before.mir
@@ -1,122 +1,122 @@
// MIR for `test` before ElaborateDrops
fn test() -> Option<Box<u32>> {
- let mut _0: std::option::Option<std::boxed::Box<u32>>; // return place in scope 0 at $DIR/issue-62289.rs:+0:14: +0:30
- let mut _1: std::boxed::Box<u32>; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
- let mut _2: usize; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
- let mut _3: usize; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
- let mut _4: *mut u8; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
- let mut _5: std::boxed::Box<u32>; // in scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
- let mut _6: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
- let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:19
- let mut _8: isize; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
- let _9: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
- let mut _10: !; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
- let mut _11: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
- let _12: u32; // in scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ let mut _0: std::option::Option<std::boxed::Box<u32>>; // return place in scope 0 at $DIR/issue_62289.rs:+0:14: +0:30
+ let mut _1: std::boxed::Box<u32>; // in scope 0 at $DIR/issue_62289.rs:+1:10: +1:21
+ let mut _2: usize; // in scope 0 at $DIR/issue_62289.rs:+1:10: +1:21
+ let mut _3: usize; // in scope 0 at $DIR/issue_62289.rs:+1:10: +1:21
+ let mut _4: *mut u8; // in scope 0 at $DIR/issue_62289.rs:+1:10: +1:21
+ let mut _5: std::boxed::Box<u32>; // in scope 0 at $DIR/issue_62289.rs:+1:10: +1:21
+ let mut _6: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>; // in scope 0 at $DIR/issue_62289.rs:+1:15: +1:20
+ let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/issue_62289.rs:+1:15: +1:19
+ let mut _8: isize; // in scope 0 at $DIR/issue_62289.rs:+1:19: +1:20
+ let _9: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue_62289.rs:+1:19: +1:20
+ let mut _10: !; // in scope 0 at $DIR/issue_62289.rs:+1:19: +1:20
+ let mut _11: std::option::Option<std::convert::Infallible>; // in scope 0 at $DIR/issue_62289.rs:+1:19: +1:20
+ let _12: u32; // in scope 0 at $DIR/issue_62289.rs:+1:15: +1:20
scope 1 {
}
scope 2 {
- debug residual => _9; // in scope 2 at $DIR/issue-62289.rs:+1:19: +1:20
+ debug residual => _9; // in scope 2 at $DIR/issue_62289.rs:+1:19: +1:20
scope 3 {
}
}
scope 4 {
- debug val => _12; // in scope 4 at $DIR/issue-62289.rs:+1:15: +1:20
+ debug val => _12; // in scope 4 at $DIR/issue_62289.rs:+1:15: +1:20
scope 5 {
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
- _2 = SizeOf(u32); // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21
- _3 = AlignOf(u32); // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21
- _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/issue-62289.rs:+1:10: +1:21
+ StorageLive(_1); // scope 0 at $DIR/issue_62289.rs:+1:10: +1:21
+ _2 = SizeOf(u32); // scope 1 at $DIR/issue_62289.rs:+1:10: +1:21
+ _3 = AlignOf(u32); // scope 1 at $DIR/issue_62289.rs:+1:10: +1:21
+ _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/issue_62289.rs:+1:10: +1:21
// mir::Constant
- // + span: $DIR/issue-62289.rs:9:10: 9:21
+ // + span: $DIR/issue_62289.rs:9:10: 9:21
// + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(<ZST>) }
}
bb1: {
- StorageLive(_5); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
- _5 = ShallowInitBox(move _4, u32); // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
- StorageLive(_6); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
- StorageLive(_7); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:19
- _7 = Option::<u32>::None; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:19
- _6 = <Option<u32> as Try>::branch(move _7) -> [return: bb2, unwind: bb12]; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ StorageLive(_5); // scope 0 at $DIR/issue_62289.rs:+1:10: +1:21
+ _5 = ShallowInitBox(move _4, u32); // scope 0 at $DIR/issue_62289.rs:+1:10: +1:21
+ StorageLive(_6); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20
+ StorageLive(_7); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:19
+ _7 = Option::<u32>::None; // scope 0 at $DIR/issue_62289.rs:+1:15: +1:19
+ _6 = <Option<u32> as Try>::branch(move _7) -> [return: bb2, unwind: bb12]; // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20
// mir::Constant
- // + span: $DIR/issue-62289.rs:9:15: 9:20
+ // + span: $DIR/issue_62289.rs:9:15: 9:20
// + literal: Const { ty: fn(Option<u32>) -> ControlFlow<<Option<u32> as Try>::Residual, <Option<u32> as Try>::Output> {<Option<u32> as Try>::branch}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_7); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
- _8 = discriminant(_6); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
- switchInt(move _8) -> [0_isize: bb3, 1_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ StorageDead(_7); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20
+ _8 = discriminant(_6); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20
+ switchInt(move _8) -> [0_isize: bb3, 1_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20
}
bb3: {
- StorageLive(_12); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
- _12 = ((_6 as Continue).0: u32); // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
- (*_5) = _12; // scope 5 at $DIR/issue-62289.rs:+1:15: +1:20
- StorageDead(_12); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
- _1 = move _5; // scope 0 at $DIR/issue-62289.rs:+1:10: +1:21
- drop(_5) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21
+ StorageLive(_12); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20
+ _12 = ((_6 as Continue).0: u32); // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20
+ (*_5) = _12; // scope 5 at $DIR/issue_62289.rs:+1:15: +1:20
+ StorageDead(_12); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20
+ _1 = move _5; // scope 0 at $DIR/issue_62289.rs:+1:10: +1:21
+ drop(_5) -> [return: bb7, unwind: bb11]; // scope 0 at $DIR/issue_62289.rs:+1:20: +1:21
}
bb4: {
- unreachable; // scope 0 at $DIR/issue-62289.rs:+1:15: +1:20
+ unreachable; // scope 0 at $DIR/issue_62289.rs:+1:15: +1:20
}
bb5: {
- StorageLive(_9); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
- _9 = ((_6 as Break).0: std::option::Option<std::convert::Infallible>); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
- StorageLive(_11); // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20
- _11 = _9; // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20
- _0 = <Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _11) -> [return: bb6, unwind: bb12]; // scope 3 at $DIR/issue-62289.rs:+1:15: +1:20
+ StorageLive(_9); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20
+ _9 = ((_6 as Break).0: std::option::Option<std::convert::Infallible>); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20
+ StorageLive(_11); // scope 3 at $DIR/issue_62289.rs:+1:19: +1:20
+ _11 = _9; // scope 3 at $DIR/issue_62289.rs:+1:19: +1:20
+ _0 = <Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _11) -> [return: bb6, unwind: bb12]; // scope 3 at $DIR/issue_62289.rs:+1:15: +1:20
// mir::Constant
- // + span: $DIR/issue-62289.rs:9:19: 9:20
+ // + span: $DIR/issue_62289.rs:9:19: 9:20
// + literal: Const { ty: fn(Option<Infallible>) -> Option<Box<u32>> {<Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual}, val: Value(<ZST>) }
}
bb6: {
- StorageDead(_11); // scope 3 at $DIR/issue-62289.rs:+1:19: +1:20
- StorageDead(_9); // scope 0 at $DIR/issue-62289.rs:+1:19: +1:20
- drop(_5) -> bb9; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21
+ StorageDead(_11); // scope 3 at $DIR/issue_62289.rs:+1:19: +1:20
+ StorageDead(_9); // scope 0 at $DIR/issue_62289.rs:+1:19: +1:20
+ drop(_5) -> bb9; // scope 0 at $DIR/issue_62289.rs:+1:20: +1:21
}
bb7: {
- StorageDead(_5); // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21
- _0 = Option::<Box<u32>>::Some(move _1); // scope 0 at $DIR/issue-62289.rs:+1:5: +1:22
- drop(_1) -> bb8; // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22
+ StorageDead(_5); // scope 0 at $DIR/issue_62289.rs:+1:20: +1:21
+ _0 = Option::<Box<u32>>::Some(move _1); // scope 0 at $DIR/issue_62289.rs:+1:5: +1:22
+ drop(_1) -> bb8; // scope 0 at $DIR/issue_62289.rs:+1:21: +1:22
}
bb8: {
- StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22
- StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:+2:1: +2:2
- goto -> bb10; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2
+ StorageDead(_1); // scope 0 at $DIR/issue_62289.rs:+1:21: +1:22
+ StorageDead(_6); // scope 0 at $DIR/issue_62289.rs:+2:1: +2:2
+ goto -> bb10; // scope 0 at $DIR/issue_62289.rs:+2:2: +2:2
}
bb9: {
- StorageDead(_5); // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21
- StorageDead(_1); // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22
- StorageDead(_6); // scope 0 at $DIR/issue-62289.rs:+2:1: +2:2
- goto -> bb10; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2
+ StorageDead(_5); // scope 0 at $DIR/issue_62289.rs:+1:20: +1:21
+ StorageDead(_1); // scope 0 at $DIR/issue_62289.rs:+1:21: +1:22
+ StorageDead(_6); // scope 0 at $DIR/issue_62289.rs:+2:1: +2:2
+ goto -> bb10; // scope 0 at $DIR/issue_62289.rs:+2:2: +2:2
}
bb10: {
- return; // scope 0 at $DIR/issue-62289.rs:+2:2: +2:2
+ return; // scope 0 at $DIR/issue_62289.rs:+2:2: +2:2
}
bb11 (cleanup): {
- drop(_1) -> bb13; // scope 0 at $DIR/issue-62289.rs:+1:21: +1:22
+ drop(_1) -> bb13; // scope 0 at $DIR/issue_62289.rs:+1:21: +1:22
}
bb12 (cleanup): {
- drop(_5) -> bb13; // scope 0 at $DIR/issue-62289.rs:+1:20: +1:21
+ drop(_5) -> bb13; // scope 0 at $DIR/issue_62289.rs:+1:20: +1:21
}
bb13 (cleanup): {
- resume; // scope 0 at $DIR/issue-62289.rs:+0:1: +2:2
+ resume; // scope 0 at $DIR/issue_62289.rs:+0:1: +2:2
}
}
diff --git a/src/test/mir-opt/issue_72181.bar.mir_map.0.mir b/src/test/mir-opt/issue_72181.bar.built.after.mir
index 972ce1d50..ebee89001 100644
--- a/src/test/mir-opt/issue_72181.bar.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181.bar.built.after.mir
@@ -1,17 +1,17 @@
-// MIR for `bar` 0 mir_map
+// MIR for `bar` after built
fn bar(_1: [(Never, u32); 1]) -> u32 {
- let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:40: +0:43
- let _2: u32; // in scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
+ let mut _0: u32; // return place in scope 0 at $DIR/issue_72181.rs:+0:40: +0:43
+ let _2: u32; // in scope 0 at $DIR/issue_72181.rs:+0:13: +0:14
scope 1 {
- debug x => _2; // in scope 1 at $DIR/issue-72181.rs:+0:13: +0:14
+ debug x => _2; // in scope 1 at $DIR/issue_72181.rs:+0:13: +0:14
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
- _2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:13: +0:14
- _0 = _2; // scope 1 at $DIR/issue-72181.rs:+0:46: +0:47
- StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
- return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
+ StorageLive(_2); // scope 0 at $DIR/issue_72181.rs:+0:13: +0:14
+ _2 = (_1[0 of 1].1: u32); // scope 0 at $DIR/issue_72181.rs:+0:13: +0:14
+ _0 = _2; // scope 1 at $DIR/issue_72181.rs:+0:46: +0:47
+ StorageDead(_2); // scope 0 at $DIR/issue_72181.rs:+0:48: +0:49
+ return; // scope 0 at $DIR/issue_72181.rs:+0:49: +0:49
}
}
diff --git a/src/test/mir-opt/issue_72181.foo.mir_map.0.mir b/src/test/mir-opt/issue_72181.foo.built.after.mir
index 534f131ea..90c978520 100644
--- a/src/test/mir-opt/issue_72181.foo.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181.foo.built.after.mir
@@ -1,27 +1,27 @@
-// MIR for `foo` 0 mir_map
+// MIR for `foo` after built
fn foo(_1: [(Never, u32); 1]) -> u32 {
- debug xs => _1; // in scope 0 at $DIR/issue-72181.rs:+0:8: +0:10
- let mut _0: u32; // return place in scope 0 at $DIR/issue-72181.rs:+0:34: +0:37
- let _2: usize; // in scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
- let mut _3: usize; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
- let mut _4: bool; // in scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+ debug xs => _1; // in scope 0 at $DIR/issue_72181.rs:+0:8: +0:10
+ let mut _0: u32; // return place in scope 0 at $DIR/issue_72181.rs:+0:34: +0:37
+ let _2: usize; // in scope 0 at $DIR/issue_72181.rs:+0:43: +0:44
+ let mut _3: usize; // in scope 0 at $DIR/issue_72181.rs:+0:40: +0:45
+ let mut _4: bool; // in scope 0 at $DIR/issue_72181.rs:+0:40: +0:45
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
- _2 = const 0_usize; // scope 0 at $DIR/issue-72181.rs:+0:43: +0:44
- _3 = Len(_1); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
- _4 = Lt(_2, _3); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
- assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-72181.rs:+0:40: +0:45
+ StorageLive(_2); // scope 0 at $DIR/issue_72181.rs:+0:43: +0:44
+ _2 = const 0_usize; // scope 0 at $DIR/issue_72181.rs:+0:43: +0:44
+ _3 = Len(_1); // scope 0 at $DIR/issue_72181.rs:+0:40: +0:45
+ _4 = Lt(_2, _3); // scope 0 at $DIR/issue_72181.rs:+0:40: +0:45
+ assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, _2) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue_72181.rs:+0:40: +0:45
}
bb1: {
- _0 = (_1[_2].1: u32); // scope 0 at $DIR/issue-72181.rs:+0:40: +0:47
- StorageDead(_2); // scope 0 at $DIR/issue-72181.rs:+0:48: +0:49
- return; // scope 0 at $DIR/issue-72181.rs:+0:49: +0:49
+ _0 = (_1[_2].1: u32); // scope 0 at $DIR/issue_72181.rs:+0:40: +0:47
+ StorageDead(_2); // scope 0 at $DIR/issue_72181.rs:+0:48: +0:49
+ return; // scope 0 at $DIR/issue_72181.rs:+0:49: +0:49
}
bb2 (cleanup): {
- resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +0:49
+ resume; // scope 0 at $DIR/issue_72181.rs:+0:1: +0:49
}
}
diff --git a/src/test/mir-opt/issue_72181.main.mir_map.0.mir b/src/test/mir-opt/issue_72181.main.built.after.mir
index 425906f84..e86836927 100644
--- a/src/test/mir-opt/issue_72181.main.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181.main.built.after.mir
@@ -1,18 +1,18 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-72181.rs:+0:11: +0:11
- let mut _1: usize; // in scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
- let mut _3: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:14: +3:27
- let mut _4: Foo; // in scope 0 at $DIR/issue-72181.rs:+3:29: +3:42
- let mut _5: u64; // in scope 0 at $DIR/issue-72181.rs:+4:13: +4:30
- let _6: usize; // in scope 0 at $DIR/issue-72181.rs:+4:24: +4:25
- let mut _7: usize; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
- let mut _8: bool; // in scope 0 at $DIR/issue-72181.rs:+4:22: +4:26
+ let mut _0: (); // return place in scope 0 at $DIR/issue_72181.rs:+0:11: +0:11
+ let mut _1: usize; // in scope 0 at $DIR/issue_72181.rs:+1:13: +1:34
+ let mut _3: Foo; // in scope 0 at $DIR/issue_72181.rs:+3:14: +3:27
+ let mut _4: Foo; // in scope 0 at $DIR/issue_72181.rs:+3:29: +3:42
+ let mut _5: u64; // in scope 0 at $DIR/issue_72181.rs:+4:13: +4:30
+ let _6: usize; // in scope 0 at $DIR/issue_72181.rs:+4:24: +4:25
+ let mut _7: usize; // in scope 0 at $DIR/issue_72181.rs:+4:22: +4:26
+ let mut _8: bool; // in scope 0 at $DIR/issue_72181.rs:+4:22: +4:26
scope 1 {
- let _2: [Foo; 2]; // in scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
+ let _2: [Foo; 2]; // in scope 1 at $DIR/issue_72181.rs:+3:9: +3:10
scope 2 {
- debug f => _2; // in scope 2 at $DIR/issue-72181.rs:+3:9: +3:10
+ debug f => _2; // in scope 2 at $DIR/issue_72181.rs:+3:9: +3:10
scope 3 {
}
scope 4 {
@@ -21,42 +21,42 @@ fn main() -> () {
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
- _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-72181.rs:+1:13: +1:34
+ StorageLive(_1); // scope 0 at $DIR/issue_72181.rs:+1:13: +1:34
+ _1 = std::mem::size_of::<Foo>() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue_72181.rs:+1:13: +1:34
// mir::Constant
- // + span: $DIR/issue-72181.rs:24:13: 24:32
+ // + span: $DIR/issue_72181.rs:24:13: 24:32
// + literal: Const { ty: fn() -> usize {std::mem::size_of::<Foo>}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_1); // scope 0 at $DIR/issue-72181.rs:+1:34: +1:35
- StorageLive(_2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
- StorageLive(_3); // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
- _3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:14: +3:27
- StorageLive(_4); // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
- _4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue-72181.rs:+3:29: +3:42
- _2 = [move _3, move _4]; // scope 1 at $DIR/issue-72181.rs:+3:13: +3:43
- StorageDead(_4); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
- StorageDead(_3); // scope 1 at $DIR/issue-72181.rs:+3:42: +3:43
- FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue-72181.rs:+3:9: +3:10
- StorageLive(_5); // scope 2 at $DIR/issue-72181.rs:+4:13: +4:30
- StorageLive(_6); // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
- _6 = const 0_usize; // scope 4 at $DIR/issue-72181.rs:+4:24: +4:25
- _7 = Len(_2); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
- _8 = Lt(_6, _7); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue-72181.rs:+4:22: +4:26
+ StorageDead(_1); // scope 0 at $DIR/issue_72181.rs:+1:34: +1:35
+ StorageLive(_2); // scope 1 at $DIR/issue_72181.rs:+3:9: +3:10
+ StorageLive(_3); // scope 1 at $DIR/issue_72181.rs:+3:14: +3:27
+ _3 = Foo { a: const 42_u64 }; // scope 1 at $DIR/issue_72181.rs:+3:14: +3:27
+ StorageLive(_4); // scope 1 at $DIR/issue_72181.rs:+3:29: +3:42
+ _4 = Foo { a: const 10_u64 }; // scope 1 at $DIR/issue_72181.rs:+3:29: +3:42
+ _2 = [move _3, move _4]; // scope 1 at $DIR/issue_72181.rs:+3:13: +3:43
+ StorageDead(_4); // scope 1 at $DIR/issue_72181.rs:+3:42: +3:43
+ StorageDead(_3); // scope 1 at $DIR/issue_72181.rs:+3:42: +3:43
+ FakeRead(ForLet(None), _2); // scope 1 at $DIR/issue_72181.rs:+3:9: +3:10
+ StorageLive(_5); // scope 2 at $DIR/issue_72181.rs:+4:13: +4:30
+ StorageLive(_6); // scope 4 at $DIR/issue_72181.rs:+4:24: +4:25
+ _6 = const 0_usize; // scope 4 at $DIR/issue_72181.rs:+4:24: +4:25
+ _7 = Len(_2); // scope 4 at $DIR/issue_72181.rs:+4:22: +4:26
+ _8 = Lt(_6, _7); // scope 4 at $DIR/issue_72181.rs:+4:22: +4:26
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb2, unwind: bb3]; // scope 4 at $DIR/issue_72181.rs:+4:22: +4:26
}
bb2: {
- _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue-72181.rs:+4:22: +4:28
- StorageDead(_6); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
- StorageDead(_5); // scope 2 at $DIR/issue-72181.rs:+4:30: +4:31
- _0 = const (); // scope 0 at $DIR/issue-72181.rs:+0:11: +5:2
- StorageDead(_2); // scope 1 at $DIR/issue-72181.rs:+5:1: +5:2
- return; // scope 0 at $DIR/issue-72181.rs:+5:2: +5:2
+ _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue_72181.rs:+4:22: +4:28
+ StorageDead(_6); // scope 2 at $DIR/issue_72181.rs:+4:30: +4:31
+ StorageDead(_5); // scope 2 at $DIR/issue_72181.rs:+4:30: +4:31
+ _0 = const (); // scope 0 at $DIR/issue_72181.rs:+0:11: +5:2
+ StorageDead(_2); // scope 1 at $DIR/issue_72181.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/issue_72181.rs:+5:2: +5:2
}
bb3 (cleanup): {
- resume; // scope 0 at $DIR/issue-72181.rs:+0:1: +5:2
+ resume; // scope 0 at $DIR/issue_72181.rs:+0:1: +5:2
}
}
diff --git a/src/test/mir-opt/issue-72181.rs b/src/test/mir-opt/issue_72181.rs
index ebb5f5042..6a32d4bbe 100644
--- a/src/test/mir-opt/issue-72181.rs
+++ b/src/test/mir-opt/issue_72181.rs
@@ -12,14 +12,14 @@ union Foo {
}
-// EMIT_MIR issue_72181.foo.mir_map.0.mir
+// EMIT_MIR issue_72181.foo.built.after.mir
fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 }
-// EMIT_MIR issue_72181.bar.mir_map.0.mir
+// EMIT_MIR issue_72181.bar.built.after.mir
fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x }
-// EMIT_MIR issue_72181.main.mir_map.0.mir
+// EMIT_MIR issue_72181.main.built.after.mir
fn main() {
let _ = mem::size_of::<Foo>();
diff --git a/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.f.built.after.mir
index e1a35d88b..4086da520 100644
--- a/src/test/mir-opt/issue_72181_1.f.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181_1.f.built.after.mir
@@ -1,29 +1,29 @@
-// MIR for `f` 0 mir_map
+// MIR for `f` after built
fn f(_1: Void) -> ! {
- debug v => _1; // in scope 0 at $DIR/issue-72181-1.rs:+0:6: +0:7
- let mut _0: !; // return place in scope 0 at $DIR/issue-72181-1.rs:+0:18: +0:19
- let mut _2: !; // in scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2
- let mut _3: !; // in scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15
+ debug v => _1; // in scope 0 at $DIR/issue_72181_1.rs:+0:6: +0:7
+ let mut _0: !; // return place in scope 0 at $DIR/issue_72181_1.rs:+0:18: +0:19
+ let mut _2: !; // in scope 0 at $DIR/issue_72181_1.rs:+0:20: +2:2
+ let mut _3: !; // in scope 0 at $DIR/issue_72181_1.rs:+1:5: +1:15
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2
- StorageLive(_3); // scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15
- FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/issue-72181-1.rs:+1:11: +1:12
- unreachable; // scope 0 at $DIR/issue-72181-1.rs:+1:11: +1:12
+ StorageLive(_2); // scope 0 at $DIR/issue_72181_1.rs:+0:20: +2:2
+ StorageLive(_3); // scope 0 at $DIR/issue_72181_1.rs:+1:5: +1:15
+ FakeRead(ForMatchedPlace(None), _1); // scope 0 at $DIR/issue_72181_1.rs:+1:11: +1:12
+ unreachable; // scope 0 at $DIR/issue_72181_1.rs:+1:11: +1:12
}
bb1: {
- unreachable; // scope 0 at $DIR/issue-72181-1.rs:+1:5: +1:15
+ unreachable; // scope 0 at $DIR/issue_72181_1.rs:+1:5: +1:15
}
bb2: {
- StorageDead(_3); // scope 0 at $DIR/issue-72181-1.rs:+1:14: +1:15
- unreachable; // scope 0 at $DIR/issue-72181-1.rs:+0:20: +2:2
+ StorageDead(_3); // scope 0 at $DIR/issue_72181_1.rs:+1:14: +1:15
+ unreachable; // scope 0 at $DIR/issue_72181_1.rs:+0:20: +2:2
}
bb3: {
- StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:+2:1: +2:2
- return; // scope 0 at $DIR/issue-72181-1.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/issue_72181_1.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/issue_72181_1.rs:+2:2: +2:2
}
}
diff --git a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.built.after.mir
index 336693337..2172f3aa9 100644
--- a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181_1.main.built.after.mir
@@ -1,57 +1,57 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
| User Type Annotations
-| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void
-| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue-72181-1.rs:16:12: 16:16, inferred_ty: Void
+| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue_72181_1.rs:16:12: 16:16, inferred_ty: Void
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(Void) }, span: $DIR/issue_72181_1.rs:16:12: 16:16, inferred_ty: Void
|
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-72181-1.rs:+0:11: +0:11
- let mut _1: !; // in scope 0 at $DIR/issue-72181-1.rs:+0:11: +6:2
- let _2: Void as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10
- let mut _3: (); // in scope 0 at $DIR/issue-72181-1.rs:+2:41: +2:43
- let _4: !; // in scope 0 at $DIR/issue-72181-1.rs:+5:5: +5:9
- let mut _5: Void; // in scope 0 at $DIR/issue-72181-1.rs:+5:7: +5:8
+ let mut _0: (); // return place in scope 0 at $DIR/issue_72181_1.rs:+0:11: +0:11
+ let mut _1: !; // in scope 0 at $DIR/issue_72181_1.rs:+0:11: +6:2
+ let _2: Void as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/issue_72181_1.rs:+1:9: +1:10
+ let mut _3: (); // in scope 0 at $DIR/issue_72181_1.rs:+2:41: +2:43
+ let _4: !; // in scope 0 at $DIR/issue_72181_1.rs:+5:5: +5:9
+ let mut _5: Void; // in scope 0 at $DIR/issue_72181_1.rs:+5:7: +5:8
scope 1 {
- debug v => _2; // in scope 1 at $DIR/issue-72181-1.rs:+1:9: +1:10
+ debug v => _2; // in scope 1 at $DIR/issue_72181_1.rs:+1:9: +1:10
}
scope 2 {
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10
- StorageLive(_3); // scope 2 at $DIR/issue-72181-1.rs:+2:41: +2:43
- _3 = (); // scope 2 at $DIR/issue-72181-1.rs:+2:41: +2:43
- _2 = transmute::<(), Void>(move _3) -> bb4; // scope 2 at $DIR/issue-72181-1.rs:+2:9: +2:44
+ StorageLive(_2); // scope 0 at $DIR/issue_72181_1.rs:+1:9: +1:10
+ StorageLive(_3); // scope 2 at $DIR/issue_72181_1.rs:+2:41: +2:43
+ _3 = (); // scope 2 at $DIR/issue_72181_1.rs:+2:41: +2:43
+ _2 = transmute::<(), Void>(move _3) -> bb4; // scope 2 at $DIR/issue_72181_1.rs:+2:9: +2:44
// mir::Constant
- // + span: $DIR/issue-72181-1.rs:17:9: 17:40
+ // + span: $DIR/issue_72181_1.rs:17:9: 17:40
// + literal: Const { ty: unsafe extern "rust-intrinsic" fn(()) -> Void {transmute::<(), Void>}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 2 at $DIR/issue-72181-1.rs:+2:43: +2:44
- FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-72181-1.rs:+1:9: +1:10
- AscribeUserType(_2, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue-72181-1.rs:+1:12: +1:16
- StorageLive(_4); // scope 1 at $DIR/issue-72181-1.rs:+5:5: +5:9
- StorageLive(_5); // scope 1 at $DIR/issue-72181-1.rs:+5:7: +5:8
- _5 = move _2; // scope 1 at $DIR/issue-72181-1.rs:+5:7: +5:8
- _4 = f(move _5) -> bb4; // scope 1 at $DIR/issue-72181-1.rs:+5:5: +5:9
+ StorageDead(_3); // scope 2 at $DIR/issue_72181_1.rs:+2:43: +2:44
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_72181_1.rs:+1:9: +1:10
+ AscribeUserType(_2, o, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at $DIR/issue_72181_1.rs:+1:12: +1:16
+ StorageLive(_4); // scope 1 at $DIR/issue_72181_1.rs:+5:5: +5:9
+ StorageLive(_5); // scope 1 at $DIR/issue_72181_1.rs:+5:7: +5:8
+ _5 = move _2; // scope 1 at $DIR/issue_72181_1.rs:+5:7: +5:8
+ _4 = f(move _5) -> bb4; // scope 1 at $DIR/issue_72181_1.rs:+5:5: +5:9
// mir::Constant
- // + span: $DIR/issue-72181-1.rs:20:5: 20:6
+ // + span: $DIR/issue_72181_1.rs:20:5: 20:6
// + literal: Const { ty: fn(Void) -> ! {f}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_5); // scope 1 at $DIR/issue-72181-1.rs:+5:8: +5:9
- StorageDead(_4); // scope 1 at $DIR/issue-72181-1.rs:+5:9: +5:10
- StorageDead(_2); // scope 0 at $DIR/issue-72181-1.rs:+6:1: +6:2
- unreachable; // scope 0 at $DIR/issue-72181-1.rs:+0:11: +6:2
+ StorageDead(_5); // scope 1 at $DIR/issue_72181_1.rs:+5:8: +5:9
+ StorageDead(_4); // scope 1 at $DIR/issue_72181_1.rs:+5:9: +5:10
+ StorageDead(_2); // scope 0 at $DIR/issue_72181_1.rs:+6:1: +6:2
+ unreachable; // scope 0 at $DIR/issue_72181_1.rs:+0:11: +6:2
}
bb3: {
- return; // scope 0 at $DIR/issue-72181-1.rs:+6:2: +6:2
+ return; // scope 0 at $DIR/issue_72181_1.rs:+6:2: +6:2
}
bb4 (cleanup): {
- resume; // scope 0 at $DIR/issue-72181-1.rs:+0:1: +6:2
+ resume; // scope 0 at $DIR/issue_72181_1.rs:+0:1: +6:2
}
}
diff --git a/src/test/mir-opt/issue-72181-1.rs b/src/test/mir-opt/issue_72181_1.rs
index 91e98adbe..8ae2599ec 100644
--- a/src/test/mir-opt/issue-72181-1.rs
+++ b/src/test/mir-opt/issue_72181_1.rs
@@ -6,12 +6,12 @@
enum Void {}
-// EMIT_MIR issue_72181_1.f.mir_map.0.mir
+// EMIT_MIR issue_72181_1.f.built.after.mir
fn f(v: Void) -> ! {
match v {}
}
-// EMIT_MIR issue_72181_1.main.mir_map.0.mir
+// EMIT_MIR issue_72181_1.main.built.after.mir
fn main() {
let v: Void = unsafe {
std::mem::transmute::<(), Void>(())
diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
index 269e4e326..b88cdfcbc 100644
--- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
+++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
@@ -2,18 +2,18 @@
+ // MIR for `main` after SimplifyArmIdentity
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
- let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
- let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- let mut _3: isize; // in scope 0 at $DIR/issue-73223.rs:+2:9: +2:16
- let _4: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- let mut _5: !; // in scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
- let mut _7: i32; // in scope 0 at $DIR/issue-73223.rs:+6:22: +6:27
+ let mut _0: (); // return place in scope 0 at $DIR/issue_73223.rs:+0:11: +0:11
+ let _1: i32; // in scope 0 at $DIR/issue_73223.rs:+1:9: +1:14
+ let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
+ let mut _3: isize; // in scope 0 at $DIR/issue_73223.rs:+2:9: +2:16
+ let _4: i32; // in scope 0 at $DIR/issue_73223.rs:+2:14: +2:15
+ let mut _5: !; // in scope 0 at $DIR/issue_73223.rs:+3:17: +3:23
+ let mut _7: i32; // in scope 0 at $DIR/issue_73223.rs:+6:22: +6:27
let _8: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _9: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _10: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _11: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _12: i32; // in scope 0 at $DIR/issue-73223.rs:+7:23: +7:24
+ let _12: i32; // in scope 0 at $DIR/issue_73223.rs:+7:23: +7:24
let mut _15: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _16: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _17: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -26,11 +26,13 @@
let mut _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _27: std::option::Option<std::fmt::Arguments<'_>>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _29: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _30: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
scope 1 {
- debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
- let _6: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
+ debug split => _1; // in scope 1 at $DIR/issue_73223.rs:+1:9: +1:14
+ let _6: std::option::Option<i32>; // in scope 1 at $DIR/issue_73223.rs:+6:9: +6:14
scope 3 {
- debug _prev => _6; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
+ debug _prev => _6; // in scope 3 at $DIR/issue_73223.rs:+6:9: +6:14
let _13: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _14: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _28: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -45,45 +47,46 @@
}
}
scope 2 {
- debug v => _4; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
+ debug v => _4; // in scope 2 at $DIR/issue_73223.rs:+2:14: +2:15
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
- StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- _3 = const 1_isize; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
- goto -> bb3; // scope 0 at $DIR/issue-73223.rs:+1:17: +1:30
+ StorageLive(_1); // scope 0 at $DIR/issue_73223.rs:+1:9: +1:14
+ StorageLive(_2); // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
+ Deinit(_2); // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
+ ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
+ discriminant(_2) = 1; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
+ _3 = const 1_isize; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
+ goto -> bb3; // scope 0 at $DIR/issue_73223.rs:+1:17: +1:30
}
bb1: {
- nop; // scope 0 at $DIR/issue-73223.rs:+3:17: +3:23
- StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
- StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
- return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
+ nop; // scope 0 at $DIR/issue_73223.rs:+3:17: +3:23
+ StorageDead(_2); // scope 0 at $DIR/issue_73223.rs:+4:6: +4:7
+ StorageDead(_1); // scope 0 at $DIR/issue_73223.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/issue_73223.rs:+8:2: +8:2
}
bb2: {
- unreachable; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
+ unreachable; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
}
bb3: {
- StorageLive(_4); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- _4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
- _1 = _4; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
- StorageDead(_4); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21
- StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
- StorageLive(_6); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
- StorageLive(_7); // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
- _7 = _1; // scope 1 at $DIR/issue-73223.rs:+6:22: +6:27
- Deinit(_6); // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
- ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
- discriminant(_6) = 1; // scope 1 at $DIR/issue-73223.rs:+6:17: +6:28
- StorageDead(_7); // scope 1 at $DIR/issue-73223.rs:+6:27: +6:28
+ StorageLive(_4); // scope 0 at $DIR/issue_73223.rs:+2:14: +2:15
+ _4 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue_73223.rs:+2:14: +2:15
+ _1 = _4; // scope 2 at $DIR/issue_73223.rs:+2:20: +2:21
+ StorageDead(_4); // scope 0 at $DIR/issue_73223.rs:+2:20: +2:21
+ StorageDead(_2); // scope 0 at $DIR/issue_73223.rs:+4:6: +4:7
+ StorageLive(_6); // scope 1 at $DIR/issue_73223.rs:+6:9: +6:14
+ StorageLive(_7); // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27
+ _7 = _1; // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27
+ Deinit(_6); // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28
+ ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28
+ discriminant(_6) = 1; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28
+ StorageDead(_7); // scope 1 at $DIR/issue_73223.rs:+6:27: +6:28
StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -92,15 +95,16 @@
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
_11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Deinit(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- (_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- (_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Deinit(_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _29 = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _30 = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _13 = (_9.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _13 = _29; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _14 = (_9.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _14 = _30; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -150,12 +154,13 @@
StorageDead(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- nop; // scope 0 at $DIR/issue-73223.rs:+0:11: +8:2
- StorageDead(_6); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
- StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
- return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
+ nop; // scope 0 at $DIR/issue_73223.rs:+0:11: +8:2
+ StorageDead(_6); // scope 1 at $DIR/issue_73223.rs:+8:1: +8:2
+ StorageDead(_1); // scope 0 at $DIR/issue_73223.rs:+8:1: +8:2
+ return; // scope 0 at $DIR/issue_73223.rs:+8:2: +8:2
}
}
diff --git a/src/test/mir-opt/issue-73223.rs b/src/test/mir-opt/issue_73223.rs
index be114cab7..be114cab7 100644
--- a/src/test/mir-opt/issue-73223.rs
+++ b/src/test/mir-opt/issue_73223.rs
diff --git a/src/test/mir-opt/issue_78192.f.InstCombine.diff b/src/test/mir-opt/issue_78192.f.InstCombine.diff
index 8ec94d65f..116ca304c 100644
--- a/src/test/mir-opt/issue_78192.f.InstCombine.diff
+++ b/src/test/mir-opt/issue_78192.f.InstCombine.diff
@@ -2,28 +2,28 @@
+ // MIR for `f` after InstCombine
fn f(_1: &T) -> *const T {
- debug a => _1; // in scope 0 at $DIR/issue-78192.rs:+0:13: +0:14
- let mut _0: *const T; // return place in scope 0 at $DIR/issue-78192.rs:+0:23: +0:31
- let _2: &*const T; // in scope 0 at $DIR/issue-78192.rs:+1:9: +1:10
- let _3: &*const T; // in scope 0 at $DIR/issue-78192.rs:+1:24: +1:40
- let _4: *const T; // in scope 0 at $DIR/issue-78192.rs:+1:25: +1:40
+ debug a => _1; // in scope 0 at $DIR/issue_78192.rs:+0:13: +0:14
+ let mut _0: *const T; // return place in scope 0 at $DIR/issue_78192.rs:+0:23: +0:31
+ let _2: &*const T; // in scope 0 at $DIR/issue_78192.rs:+1:9: +1:10
+ let _3: &*const T; // in scope 0 at $DIR/issue_78192.rs:+1:24: +1:40
+ let _4: *const T; // in scope 0 at $DIR/issue_78192.rs:+1:25: +1:40
scope 1 {
- debug b => _2; // in scope 1 at $DIR/issue-78192.rs:+1:9: +1:10
+ debug b => _2; // in scope 1 at $DIR/issue_78192.rs:+1:9: +1:10
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-78192.rs:+1:9: +1:10
- StorageLive(_3); // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40
- StorageLive(_4); // scope 0 at $DIR/issue-78192.rs:+1:25: +1:40
- _4 = &raw const (*_1); // scope 0 at $DIR/issue-78192.rs:+1:26: +1:27
- _3 = &_4; // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40
-- _2 = &(*_3); // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40
-+ _2 = _3; // scope 0 at $DIR/issue-78192.rs:+1:24: +1:40
- StorageDead(_3); // scope 0 at $DIR/issue-78192.rs:+1:40: +1:41
- _0 = (*_2); // scope 1 at $DIR/issue-78192.rs:+2:5: +2:7
- StorageDead(_4); // scope 0 at $DIR/issue-78192.rs:+3:1: +3:2
- StorageDead(_2); // scope 0 at $DIR/issue-78192.rs:+3:1: +3:2
- return; // scope 0 at $DIR/issue-78192.rs:+3:2: +3:2
+ StorageLive(_2); // scope 0 at $DIR/issue_78192.rs:+1:9: +1:10
+ StorageLive(_3); // scope 0 at $DIR/issue_78192.rs:+1:24: +1:40
+ StorageLive(_4); // scope 0 at $DIR/issue_78192.rs:+1:25: +1:40
+ _4 = &raw const (*_1); // scope 0 at $DIR/issue_78192.rs:+1:26: +1:27
+ _3 = &_4; // scope 0 at $DIR/issue_78192.rs:+1:24: +1:40
+- _2 = &(*_3); // scope 0 at $DIR/issue_78192.rs:+1:24: +1:40
++ _2 = _3; // scope 0 at $DIR/issue_78192.rs:+1:24: +1:40
+ StorageDead(_3); // scope 0 at $DIR/issue_78192.rs:+1:40: +1:41
+ _0 = (*_2); // scope 1 at $DIR/issue_78192.rs:+2:5: +2:7
+ StorageDead(_4); // scope 0 at $DIR/issue_78192.rs:+3:1: +3:2
+ StorageDead(_2); // scope 0 at $DIR/issue_78192.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/issue_78192.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/issue-78192.rs b/src/test/mir-opt/issue_78192.rs
index 39f665402..39f665402 100644
--- a/src/test/mir-opt/issue-78192.rs
+++ b/src/test/mir-opt/issue_78192.rs
diff --git a/src/test/mir-opt/issue_91633.bar.mir_map.0.mir b/src/test/mir-opt/issue_91633.bar.built.after.mir
index 625f6c736..c3fb90e84 100644
--- a/src/test/mir-opt/issue_91633.bar.mir_map.0.mir
+++ b/src/test/mir-opt/issue_91633.bar.built.after.mir
@@ -1,39 +1,39 @@
-// MIR for `bar` 0 mir_map
+// MIR for `bar` after built
fn bar(_1: Box<[T]>) -> () {
- debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
- let mut _0: (); // return place in scope 0 at $DIR/issue-91633.rs:+1:2: +1:2
- let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
- let mut _3: &[T]; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
+ debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14
+ let mut _0: (); // return place in scope 0 at $DIR/issue_91633.rs:+1:2: +1:2
+ let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:19
+ let mut _3: &[T]; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:16
scope 1 {
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
- StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
- _3 = &(*_1); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:16
- _2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-91633.rs:+4:14: +4:19
+ StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:19
+ StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:16
+ _3 = &(*_1); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:16
+ _2 = <[T] as Index<usize>>::index(move _3, const 0_usize) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue_91633.rs:+4:14: +4:19
// mir::Constant
- // + span: $DIR/issue-91633.rs:15:14: 15:19
+ // + span: $DIR/issue_91633.rs:15:14: 15:19
// + literal: Const { ty: for<'a> fn(&'a [T], usize) -> &'a <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+4:18: +4:19
- StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:19: +4:20
- _0 = const (); // scope 0 at $DIR/issue-91633.rs:+3:2: +5:3
- drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
+ StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+4:18: +4:19
+ StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:19: +4:20
+ _0 = const (); // scope 0 at $DIR/issue_91633.rs:+3:2: +5:3
+ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3
}
bb2: {
- return; // scope 0 at $DIR/issue-91633.rs:+5:3: +5:3
+ return; // scope 0 at $DIR/issue_91633.rs:+5:3: +5:3
}
bb3 (cleanup): {
- drop(_1) -> bb4; // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
+ drop(_1) -> bb4; // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3
}
bb4 (cleanup): {
- resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +5:3
+ resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +5:3
}
}
diff --git a/src/test/mir-opt/issue_91633.foo.mir_map.0.mir b/src/test/mir-opt/issue_91633.foo.built.after.mir
index 9903e203a..4e3dd365e 100644
--- a/src/test/mir-opt/issue_91633.foo.mir_map.0.mir
+++ b/src/test/mir-opt/issue_91633.foo.built.after.mir
@@ -1,57 +1,57 @@
-// MIR for `foo` 0 mir_map
+// MIR for `foo` after built
fn foo(_1: Box<[T]>) -> T {
- debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:19: +0:21
- let mut _0: T; // return place in scope 0 at $DIR/issue-91633.rs:+0:36: +0:37
- let _2: T; // in scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
- let mut _3: &T; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
- let _4: usize; // in scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
- let mut _5: usize; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
- let mut _6: bool; // in scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+ debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:19: +0:21
+ let mut _0: T; // return place in scope 0 at $DIR/issue_91633.rs:+0:36: +0:37
+ let _2: T; // in scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ let mut _3: &T; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:27
+ let _4: usize; // in scope 0 at $DIR/issue_91633.rs:+2:17: +2:18
+ let mut _5: usize; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:19
+ let mut _6: bool; // in scope 0 at $DIR/issue_91633.rs:+2:14: +2:19
scope 1 {
- debug f => _2; // in scope 1 at $DIR/issue-91633.rs:+2:10: +2:11
+ debug f => _2; // in scope 1 at $DIR/issue_91633.rs:+2:10: +2:11
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
- StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
- StorageLive(_4); // scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
- _4 = const 0_usize; // scope 0 at $DIR/issue-91633.rs:+2:17: +2:18
- _5 = Len((*_1)); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
- _6 = Lt(_4, _5); // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
- assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:19
+ StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27
+ StorageLive(_4); // scope 0 at $DIR/issue_91633.rs:+2:17: +2:18
+ _4 = const 0_usize; // scope 0 at $DIR/issue_91633.rs:+2:17: +2:18
+ _5 = Len((*_1)); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19
+ _6 = Lt(_4, _5); // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19
+ assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:19
}
bb1: {
- _3 = &(*_1)[_4]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
- _2 = <T as Clone>::clone(move _3) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:27
+ _3 = &(*_1)[_4]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27
+ _2 = <T as Clone>::clone(move _3) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:27
// mir::Constant
- // + span: $DIR/issue-91633.rs:28:20: 28:25
+ // + span: $DIR/issue_91633.rs:28:20: 28:25
// + literal: Const { ty: for<'a> fn(&'a T) -> T {<T as Clone>::clone}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+2:26: +2:27
- FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
- StorageDead(_4); // scope 0 at $DIR/issue-91633.rs:+2:27: +2:28
- _0 = move _2; // scope 1 at $DIR/issue-91633.rs:+3:6: +3:7
- drop(_2) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+ StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+2:26: +2:27
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ StorageDead(_4); // scope 0 at $DIR/issue_91633.rs:+2:27: +2:28
+ _0 = move _2; // scope 1 at $DIR/issue_91633.rs:+3:6: +3:7
+ drop(_2) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
}
bb3: {
- StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
- drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+ StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
+ drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
}
bb4: {
- return; // scope 0 at $DIR/issue-91633.rs:+4:3: +4:3
+ return; // scope 0 at $DIR/issue_91633.rs:+4:3: +4:3
}
bb5 (cleanup): {
- drop(_1) -> bb6; // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
+ drop(_1) -> bb6; // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
}
bb6 (cleanup): {
- resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +4:3
+ resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +4:3
}
}
diff --git a/src/test/mir-opt/issue_91633.fun.mir_map.0.mir b/src/test/mir-opt/issue_91633.fun.built.after.mir
index ded9a4cf7..42486d3a5 100644
--- a/src/test/mir-opt/issue_91633.fun.mir_map.0.mir
+++ b/src/test/mir-opt/issue_91633.fun.built.after.mir
@@ -1,35 +1,35 @@
-// MIR for `fun` 0 mir_map
+// MIR for `fun` after built
fn fun(_1: &[T]) -> &T {
- debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
- let mut _0: &T; // return place in scope 0 at $DIR/issue-91633.rs:+0:25: +0:27
- let _2: &T; // in scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
- let _3: usize; // in scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
- let mut _4: usize; // in scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
- let mut _5: bool; // in scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+ debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14
+ let mut _0: &T; // return place in scope 0 at $DIR/issue_91633.rs:+0:25: +0:27
+ let _2: &T; // in scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ let _3: usize; // in scope 0 at $DIR/issue_91633.rs:+2:18: +2:19
+ let mut _4: usize; // in scope 0 at $DIR/issue_91633.rs:+2:15: +2:20
+ let mut _5: bool; // in scope 0 at $DIR/issue_91633.rs:+2:15: +2:20
scope 1 {
- debug f => _2; // in scope 1 at $DIR/issue-91633.rs:+2:10: +2:11
+ debug f => _2; // in scope 1 at $DIR/issue_91633.rs:+2:10: +2:11
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
- StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
- _3 = const 0_usize; // scope 0 at $DIR/issue-91633.rs:+2:18: +2:19
- _4 = Len((*_1)); // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
- _5 = Lt(_3, _4); // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue-91633.rs:+2:15: +2:20
+ StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+2:18: +2:19
+ _3 = const 0_usize; // scope 0 at $DIR/issue_91633.rs:+2:18: +2:19
+ _4 = Len((*_1)); // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20
+ _5 = Lt(_3, _4); // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb2]; // scope 0 at $DIR/issue_91633.rs:+2:15: +2:20
}
bb1: {
- _2 = &(*_1)[_3]; // scope 0 at $DIR/issue-91633.rs:+2:14: +2:20
- FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue-91633.rs:+2:10: +2:11
- _0 = &(*_2); // scope 1 at $DIR/issue-91633.rs:+3:6: +3:7
- StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
- StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:2: +4:3
- return; // scope 0 at $DIR/issue-91633.rs:+4:3: +4:3
+ _2 = &(*_1)[_3]; // scope 0 at $DIR/issue_91633.rs:+2:14: +2:20
+ FakeRead(ForLet(None), _2); // scope 0 at $DIR/issue_91633.rs:+2:10: +2:11
+ _0 = &(*_2); // scope 1 at $DIR/issue_91633.rs:+3:6: +3:7
+ StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
+ StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:2: +4:3
+ return; // scope 0 at $DIR/issue_91633.rs:+4:3: +4:3
}
bb2 (cleanup): {
- resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +4:3
+ resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +4:3
}
}
diff --git a/src/test/mir-opt/issue_91633.hey.mir_map.0.mir b/src/test/mir-opt/issue_91633.hey.built.after.mir
index 37c3b3fca..ccb06dd59 100644
--- a/src/test/mir-opt/issue_91633.hey.mir_map.0.mir
+++ b/src/test/mir-opt/issue_91633.hey.built.after.mir
@@ -1,35 +1,35 @@
-// MIR for `hey` 0 mir_map
+// MIR for `hey` after built
fn hey(_1: &[T]) -> () {
- debug it => _1; // in scope 0 at $DIR/issue-91633.rs:+0:12: +0:14
- let mut _0: (); // return place in scope 0 at $DIR/issue-91633.rs:+1:2: +1:2
- let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
- let _3: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
- let mut _4: &[T]; // in scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
+ debug it => _1; // in scope 0 at $DIR/issue_91633.rs:+0:12: +0:14
+ let mut _0: (); // return place in scope 0 at $DIR/issue_91633.rs:+1:2: +1:2
+ let mut _2: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:14: +4:20
+ let _3: &<[T] as std::ops::Index<usize>>::Output; // in scope 0 at $DIR/issue_91633.rs:+4:15: +4:20
+ let mut _4: &[T]; // in scope 0 at $DIR/issue_91633.rs:+4:15: +4:17
scope 1 {
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
- StorageLive(_3); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
- StorageLive(_4); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
- _4 = &(*_1); // scope 0 at $DIR/issue-91633.rs:+4:15: +4:17
- _3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/issue-91633.rs:+4:15: +4:20
+ StorageLive(_2); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:20
+ StorageLive(_3); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:20
+ StorageLive(_4); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:17
+ _4 = &(*_1); // scope 0 at $DIR/issue_91633.rs:+4:15: +4:17
+ _3 = <[T] as Index<usize>>::index(move _4, const 0_usize) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/issue_91633.rs:+4:15: +4:20
// mir::Constant
- // + span: $DIR/issue-91633.rs:7:15: 7:20
+ // + span: $DIR/issue_91633.rs:7:15: 7:20
// + literal: Const { ty: for<'a> fn(&'a [T], usize) -> &'a <[T] as Index<usize>>::Output {<[T] as Index<usize>>::index}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_4); // scope 0 at $DIR/issue-91633.rs:+4:19: +4:20
- _2 = &(*_3); // scope 0 at $DIR/issue-91633.rs:+4:14: +4:20
- StorageDead(_2); // scope 0 at $DIR/issue-91633.rs:+4:20: +4:21
- _0 = const (); // scope 0 at $DIR/issue-91633.rs:+3:2: +5:3
- StorageDead(_3); // scope 0 at $DIR/issue-91633.rs:+5:2: +5:3
- return; // scope 0 at $DIR/issue-91633.rs:+5:3: +5:3
+ StorageDead(_4); // scope 0 at $DIR/issue_91633.rs:+4:19: +4:20
+ _2 = &(*_3); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:20
+ StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:20: +4:21
+ _0 = const (); // scope 0 at $DIR/issue_91633.rs:+3:2: +5:3
+ StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3
+ return; // scope 0 at $DIR/issue_91633.rs:+5:3: +5:3
}
bb2 (cleanup): {
- resume; // scope 0 at $DIR/issue-91633.rs:+0:1: +5:3
+ resume; // scope 0 at $DIR/issue_91633.rs:+0:1: +5:3
}
}
diff --git a/src/test/mir-opt/issue-91633.rs b/src/test/mir-opt/issue_91633.rs
index 8f6601985..9127cacc9 100644
--- a/src/test/mir-opt/issue-91633.rs
+++ b/src/test/mir-opt/issue_91633.rs
@@ -1,5 +1,5 @@
// compile-flags: -Z mir-opt-level=0
-// EMIT_MIR issue_91633.hey.mir_map.0.mir
+// EMIT_MIR issue_91633.hey.built.after.mir
fn hey<T> (it: &[T])
where
[T] : std::ops::Index<usize>,
@@ -7,7 +7,7 @@ fn hey<T> (it: &[T])
let _ = &it[0];
}
-// EMIT_MIR issue_91633.bar.mir_map.0.mir
+// EMIT_MIR issue_91633.bar.built.after.mir
fn bar<T> (it: Box<[T]>)
where
[T] : std::ops::Index<usize>,
@@ -15,14 +15,14 @@ fn bar<T> (it: Box<[T]>)
let _ = it[0];
}
-// EMIT_MIR issue_91633.fun.mir_map.0.mir
+// EMIT_MIR issue_91633.fun.built.after.mir
fn fun<T> (it: &[T]) -> &T
{
let f = &it[0];
f
}
-// EMIT_MIR issue_91633.foo.mir_map.0.mir
+// EMIT_MIR issue_91633.foo.built.after.mir
fn foo<T: Clone> (it: Box<[T]>) -> T
{
let f = it[0].clone();
diff --git a/src/test/mir-opt/issue_99325.main.mir_map.0.mir b/src/test/mir-opt/issue_99325.main.built.after.mir
index 165efa9df..3db40412b 100644
--- a/src/test/mir-opt/issue_99325.main.mir_map.0.mir
+++ b/src/test/mir-opt/issue_99325.main.built.after.mir
@@ -1,18 +1,18 @@
-// MIR for `main` 0 mir_map
+// MIR for `main` after built
| User Type Annotations
-| 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
-| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [] }) }], user_self_ty: None }) }, span: $DIR/issue-99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 0: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }) }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 1: user_ty: Canonical { max_universe: U0, variables: [], value: TypeOf(DefId(0:3 ~ issue_99325[8f58]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[8f58]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[8f58]::function_with_bytes::BYTES)) }, substs: [] }) }], user_self_ty: None }) }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/issue-99325.rs:+0:15: +0:15
+ let mut _0: (); // return place in scope 0 at $DIR/issue_99325.rs:+0:15: +0:15
let _1: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _2: (&&[u8], &&[u8; 4]); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _3: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _4: &[u8]; // in scope 0 at $DIR/issue-99325.rs:+1:16: +1:48
+ let _4: &[u8]; // in scope 0 at $DIR/issue_99325.rs:+1:16: +1:48
let mut _5: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _6: &[u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+1:50: +1:75
- let _7: [u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+1:51: +1:75
+ let _6: &[u8; 4]; // in scope 0 at $DIR/issue_99325.rs:+1:50: +1:75
+ let _7: [u8; 4]; // in scope 0 at $DIR/issue_99325.rs:+1:51: +1:75
let _8: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _9: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -30,9 +30,9 @@ fn main() -> () {
let _23: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _24: (&&[u8], &&[u8; 4]); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _25: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _26: &[u8]; // in scope 0 at $DIR/issue-99325.rs:+2:16: +2:70
+ let _26: &[u8]; // in scope 0 at $DIR/issue_99325.rs:+2:16: +2:70
let mut _27: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- let _28: &[u8; 4]; // in scope 0 at $DIR/issue-99325.rs:+2:72: +2:79
+ let _28: &[u8; 4]; // in scope 0 at $DIR/issue_99325.rs:+2:72: +2:79
let _29: &&[u8]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _30: &&[u8; 4]; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _31: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -68,10 +68,10 @@ fn main() -> () {
StorageLive(_1); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_4); // scope 0 at $DIR/issue-99325.rs:+1:16: +1:48
- _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb19]; // scope 0 at $DIR/issue-99325.rs:+1:16: +1:48
+ StorageLive(_4); // scope 0 at $DIR/issue_99325.rs:+1:16: +1:48
+ _4 = function_with_bytes::<&*b"AAAA">() -> [return: bb1, unwind: bb19]; // scope 0 at $DIR/issue_99325.rs:+1:16: +1:48
// mir::Constant
- // + span: $DIR/issue-99325.rs:10:16: 10:46
+ // + span: $DIR/issue_99325.rs:10:16: 10:46
// + user_ty: UserType(0)
// + literal: Const { ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}, val: Value(<ZST>) }
}
@@ -79,10 +79,10 @@ fn main() -> () {
bb1: {
_3 = &_4; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_6); // scope 0 at $DIR/issue-99325.rs:+1:50: +1:75
- StorageLive(_7); // scope 0 at $DIR/issue-99325.rs:+1:51: +1:75
- _7 = [const 65_u8, const 65_u8, const 65_u8, const 65_u8]; // scope 0 at $DIR/issue-99325.rs:+1:51: +1:75
- _6 = &_7; // scope 0 at $DIR/issue-99325.rs:+1:50: +1:75
+ StorageLive(_6); // scope 0 at $DIR/issue_99325.rs:+1:50: +1:75
+ StorageLive(_7); // scope 0 at $DIR/issue_99325.rs:+1:51: +1:75
+ _7 = [const 65_u8, const 65_u8, const 65_u8, const 65_u8]; // scope 0 at $DIR/issue_99325.rs:+1:51: +1:75
+ _6 = &_7; // scope 0 at $DIR/issue_99325.rs:+1:50: +1:75
_5 = &_6; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_2 = (move _3, move _5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_5); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -176,10 +176,10 @@ fn main() -> () {
StorageLive(_23); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_24); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_25); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_26); // scope 0 at $DIR/issue-99325.rs:+2:16: +2:70
- _26 = function_with_bytes::<&*b"AAAA">() -> [return: bb10, unwind: bb19]; // scope 0 at $DIR/issue-99325.rs:+2:16: +2:70
+ StorageLive(_26); // scope 0 at $DIR/issue_99325.rs:+2:16: +2:70
+ _26 = function_with_bytes::<&*b"AAAA">() -> [return: bb10, unwind: bb19]; // scope 0 at $DIR/issue_99325.rs:+2:16: +2:70
// mir::Constant
- // + span: $DIR/issue-99325.rs:11:16: 11:68
+ // + span: $DIR/issue_99325.rs:11:16: 11:68
// + user_ty: UserType(1)
// + literal: Const { ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}, val: Value(<ZST>) }
}
@@ -187,10 +187,10 @@ fn main() -> () {
bb10: {
_25 = &_26; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_27); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- StorageLive(_28); // scope 0 at $DIR/issue-99325.rs:+2:72: +2:79
- _28 = const b"AAAA"; // scope 0 at $DIR/issue-99325.rs:+2:72: +2:79
+ StorageLive(_28); // scope 0 at $DIR/issue_99325.rs:+2:72: +2:79
+ _28 = const b"AAAA"; // scope 0 at $DIR/issue_99325.rs:+2:72: +2:79
// mir::Constant
- // + span: $DIR/issue-99325.rs:11:72: 11:79
+ // + span: $DIR/issue_99325.rs:11:72: 11:79
// + literal: Const { ty: &[u8; 4], val: Value(Scalar(alloc4)) }
_27 = &_28; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_24 = (move _25, move _27); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -281,12 +281,12 @@ fn main() -> () {
StorageDead(_26); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_24); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_23); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _0 = const (); // scope 0 at $DIR/issue-99325.rs:+0:15: +3:2
- return; // scope 0 at $DIR/issue-99325.rs:+3:2: +3:2
+ _0 = const (); // scope 0 at $DIR/issue_99325.rs:+0:15: +3:2
+ return; // scope 0 at $DIR/issue_99325.rs:+3:2: +3:2
}
bb19 (cleanup): {
- resume; // scope 0 at $DIR/issue-99325.rs:+0:1: +3:2
+ resume; // scope 0 at $DIR/issue_99325.rs:+0:1: +3:2
}
}
diff --git a/src/test/mir-opt/issue-99325.rs b/src/test/mir-opt/issue_99325.rs
index b79946ea8..fe819cddb 100644
--- a/src/test/mir-opt/issue-99325.rs
+++ b/src/test/mir-opt/issue_99325.rs
@@ -5,7 +5,7 @@ pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] {
BYTES
}
-// EMIT_MIR issue_99325.main.mir_map.0.mir
+// EMIT_MIR issue_99325.main.built.after.mir
pub fn main() {
assert_eq!(function_with_bytes::<b"AAAA">(), &[0x41, 0x41, 0x41, 0x41]);
assert_eq!(function_with_bytes::<{ &[0x41, 0x41, 0x41, 0x41] }>(), b"AAAA");
diff --git a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir
index f46c10711..5a2f4feff 100644
--- a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir
+++ b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir
@@ -1,90 +1,77 @@
// MIR for `num_to_digit` after PreCodegen
fn num_to_digit(_1: char) -> u32 {
- debug num => _1; // in scope 0 at $DIR/issue-59352.rs:+0:21: +0:24
- let mut _0: u32; // return place in scope 0 at $DIR/issue-59352.rs:+0:35: +0:38
- let mut _2: char; // in scope 0 at $DIR/issue-59352.rs:+2:8: +2:11
- let mut _3: std::option::Option<u32>; // in scope 0 at $DIR/issue-59352.rs:+2:26: +2:41
- let mut _4: char; // in scope 0 at $DIR/issue-59352.rs:+2:26: +2:29
- let mut _5: u32; // in scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
- let mut _12: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- scope 1 (inlined char::methods::<impl char>::is_digit) { // at $DIR/issue-59352.rs:14:8: 14:23
- debug self => _2; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- debug radix => _5; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- let mut _6: &std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- let _7: std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- let mut _8: char; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ debug num => _1; // in scope 0 at $DIR/issue_59352.rs:+0:21: +0:24
+ let mut _0: u32; // return place in scope 0 at $DIR/issue_59352.rs:+0:35: +0:38
+ let mut _2: std::option::Option<u32>; // in scope 0 at $DIR/issue_59352.rs:+2:26: +2:41
+ let mut _3: u32; // in scope 0 at $DIR/issue_59352.rs:+2:8: +2:23
+ let mut _9: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 1 (inlined char::methods::<impl char>::is_digit) { // at $DIR/issue_59352.rs:14:8: 14:23
+ debug self => _1; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ debug radix => _3; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ let mut _4: &std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ let _5: std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ let mut _6: char; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
scope 2 (inlined Option::<u32>::is_some) { // at $SRC_DIR/core/src/char/methods.rs:LL:COL
- debug self => _6; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
- let mut _9: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
+ debug self => _4; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
}
}
- scope 3 (inlined #[track_caller] Option::<u32>::unwrap) { // at $DIR/issue-59352.rs:14:26: 14:50
- debug self => _3; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
- let mut _10: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
- let mut _11: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ scope 3 (inlined #[track_caller] Option::<u32>::unwrap) { // at $DIR/issue_59352.rs:14:26: 14:50
+ debug self => _2; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ let mut _7: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ let mut _8: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
scope 4 {
debug val => _0; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL
}
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:11
- _2 = _1; // scope 0 at $DIR/issue-59352.rs:+2:8: +2:11
- StorageLive(_5); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
+ StorageLive(_3); // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23
+ StorageLive(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageLive(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
StorageLive(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- StorageLive(_7); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- StorageLive(_8); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- _8 = _2; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- _7 = char::methods::<impl char>::to_digit(move _8, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ _6 = _1; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ _5 = char::methods::<impl char>::to_digit(move _6, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/char/methods.rs:LL:COL
// + literal: Const { ty: fn(char, u32) -> Option<u32> {char::methods::<impl char>::to_digit}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_12); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
- StorageLive(_3); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:41
- StorageLive(_4); // scope 0 at $DIR/issue-59352.rs:+2:26: +2:29
- _4 = _1; // scope 0 at $DIR/issue-59352.rs:+2:26: +2:29
- _3 = char::methods::<impl char>::to_digit(move _4, const 8_u32) -> bb2; // scope 0 at $DIR/issue-59352.rs:+2:26: +2:41
+ StorageLive(_2); // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41
+ _2 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> bb2; // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41
// mir::Constant
- // + span: $DIR/issue-59352.rs:14:30: 14:38
+ // + span: $DIR/issue_59352.rs:14:30: 14:38
// + literal: Const { ty: fn(char, u32) -> Option<u32> {char::methods::<impl char>::to_digit}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_4); // scope 0 at $DIR/issue-59352.rs:+2:40: +2:41
- _10 = discriminant(_3); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
- switchInt(move _10) -> [0_isize: bb6, 1_isize: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ _7 = discriminant(_2); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ switchInt(move _7) -> [0_isize: bb6, 1_isize: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
}
bb3: {
- StorageDead(_12); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
- _0 = const 0_u32; // scope 0 at $DIR/issue-59352.rs:+2:60: +2:61
- goto -> bb4; // scope 0 at $DIR/issue-59352.rs:+2:5: +2:63
+ _0 = const 0_u32; // scope 0 at $DIR/issue_59352.rs:+2:60: +2:61
+ goto -> bb4; // scope 0 at $DIR/issue_59352.rs:+2:5: +2:63
}
bb4: {
- return; // scope 0 at $DIR/issue-59352.rs:+3:2: +3:2
+ return; // scope 0 at $DIR/issue_59352.rs:+3:2: +3:2
}
bb5: {
- _6 = &_7; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- StorageDead(_8); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- _9 = discriminant((*_6)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
- StorageLive(_12); // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- _12 = move _9; // scope 2 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _4 = &_5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
StorageDead(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- StorageDead(_7); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
- StorageDead(_5); // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
- StorageDead(_2); // scope 0 at $DIR/issue-59352.rs:+2:22: +2:23
- switchInt(move _12) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/issue-59352.rs:+2:8: +2:23
+ _9 = discriminant((*_4)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL
+ StorageDead(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageDead(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL
+ StorageDead(_3); // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23
+ switchInt(move _9) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23
}
bb6: {
- StorageLive(_11); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
- _11 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value"); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ StorageLive(_8); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ _8 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value"); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/option.rs:LL:COL
// + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value(<ZST>) }
@@ -98,8 +85,8 @@ fn num_to_digit(_1: char) -> u32 {
}
bb8: {
- _0 = move ((_3 as Some).0: u32); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
- StorageDead(_3); // scope 0 at $DIR/issue-59352.rs:+2:49: +2:50
- goto -> bb4; // scope 0 at $DIR/issue-59352.rs:+2:5: +2:63
+ _0 = move ((_2 as Some).0: u32); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL
+ StorageDead(_2); // scope 0 at $DIR/issue_59352.rs:+2:49: +2:50
+ goto -> bb4; // scope 0 at $DIR/issue_59352.rs:+2:5: +2:63
}
}
diff --git a/src/test/mir-opt/issues/issue-59352.rs b/src/test/mir-opt/issues/issue_59352.rs
index 1e0045555..1e0045555 100644
--- a/src/test/mir-opt/issues/issue-59352.rs
+++ b/src/test/mir-opt/issues/issue_59352.rs
diff --git a/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
index 2ee4332ad..87066cc62 100644
--- a/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
+++ b/src/test/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
@@ -2,17 +2,17 @@
+ // MIR for `foo` after MatchBranchSimplification
fn foo(_1: [u8; 16]) -> Option<[u8; 4]> {
- debug bytes => _1; // in scope 0 at $DIR/issue-75439.rs:+0:12: +0:17
- let mut _0: std::option::Option<[u8; 4]>; // return place in scope 0 at $DIR/issue-75439.rs:+0:32: +0:47
- let _2: [u32; 4]; // in scope 0 at $DIR/issue-75439.rs:+2:9: +2:15
- let mut _3: [u8; 16]; // in scope 0 at $DIR/issue-75439.rs:+2:47: +2:52
- let mut _5: [u8; 4]; // in scope 0 at $DIR/issue-75439.rs:+5:14: +5:38
- let mut _6: u32; // in scope 0 at $DIR/issue-75439.rs:+5:33: +5:35
+ debug bytes => _1; // in scope 0 at $DIR/issue_75439.rs:+0:12: +0:17
+ let mut _0: std::option::Option<[u8; 4]>; // return place in scope 0 at $DIR/issue_75439.rs:+0:32: +0:47
+ let _2: [u32; 4]; // in scope 0 at $DIR/issue_75439.rs:+2:9: +2:15
+ let mut _3: [u8; 16]; // in scope 0 at $DIR/issue_75439.rs:+2:47: +2:52
+ let mut _5: [u8; 4]; // in scope 0 at $DIR/issue_75439.rs:+5:14: +5:38
+ let mut _6: u32; // in scope 0 at $DIR/issue_75439.rs:+5:33: +5:35
scope 1 {
- debug dwords => _2; // in scope 1 at $DIR/issue-75439.rs:+2:9: +2:15
+ debug dwords => _2; // in scope 1 at $DIR/issue_75439.rs:+2:9: +2:15
scope 3 {
- debug ip => _4; // in scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
- let _4: u32; // in scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
+ debug ip => _4; // in scope 3 at $DIR/issue_75439.rs:+4:27: +4:29
+ let _4: u32; // in scope 3 at $DIR/issue_75439.rs:+4:27: +4:29
scope 4 {
}
}
@@ -21,69 +21,69 @@
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/issue-75439.rs:+2:9: +2:15
- StorageLive(_3); // scope 2 at $DIR/issue-75439.rs:+2:47: +2:52
- _3 = _1; // scope 2 at $DIR/issue-75439.rs:+2:47: +2:52
- _2 = transmute::<[u8; 16], [u32; 4]>(move _3) -> bb1; // scope 2 at $DIR/issue-75439.rs:+2:37: +2:53
+ StorageLive(_2); // scope 0 at $DIR/issue_75439.rs:+2:9: +2:15
+ StorageLive(_3); // scope 2 at $DIR/issue_75439.rs:+2:47: +2:52
+ _3 = _1; // scope 2 at $DIR/issue_75439.rs:+2:47: +2:52
+ _2 = transmute::<[u8; 16], [u32; 4]>(move _3) -> bb1; // scope 2 at $DIR/issue_75439.rs:+2:37: +2:53
// mir::Constant
- // + span: $DIR/issue-75439.rs:7:37: 7:46
+ // + span: $DIR/issue_75439.rs:7:37: 7:46
// + literal: Const { ty: unsafe extern "rust-intrinsic" fn([u8; 16]) -> [u32; 4] {transmute::<[u8; 16], [u32; 4]>}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 2 at $DIR/issue-75439.rs:+2:52: +2:53
- switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30
+ StorageDead(_3); // scope 2 at $DIR/issue_75439.rs:+2:52: +2:53
+ switchInt(_2[0 of 4]) -> [0_u32: bb2, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30
}
bb2: {
- switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30
+ switchInt(_2[1 of 4]) -> [0_u32: bb3, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30
}
bb3: {
- switchInt(_2[2 of 4]) -> [0_u32: bb5, 4294901760_u32: bb6, otherwise: bb8]; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30
+ switchInt(_2[2 of 4]) -> [0_u32: bb5, 4294901760_u32: bb6, otherwise: bb8]; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30
}
bb4: {
- StorageLive(_5); // scope 3 at $DIR/issue-75439.rs:+5:14: +5:38
- StorageLive(_6); // scope 4 at $DIR/issue-75439.rs:+5:33: +5:35
- _6 = _4; // scope 4 at $DIR/issue-75439.rs:+5:33: +5:35
- _5 = transmute::<u32, [u8; 4]>(move _6) -> bb7; // scope 4 at $DIR/issue-75439.rs:+5:23: +5:36
+ StorageLive(_5); // scope 3 at $DIR/issue_75439.rs:+5:14: +5:38
+ StorageLive(_6); // scope 4 at $DIR/issue_75439.rs:+5:33: +5:35
+ _6 = _4; // scope 4 at $DIR/issue_75439.rs:+5:33: +5:35
+ _5 = transmute::<u32, [u8; 4]>(move _6) -> bb7; // scope 4 at $DIR/issue_75439.rs:+5:23: +5:36
// mir::Constant
- // + span: $DIR/issue-75439.rs:10:23: 10:32
+ // + span: $DIR/issue_75439.rs:10:23: 10:32
// + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u32) -> [u8; 4] {transmute::<u32, [u8; 4]>}, val: Value(<ZST>) }
}
bb5: {
- StorageLive(_4); // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
- _4 = _2[3 of 4]; // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
- goto -> bb4; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30
+ StorageLive(_4); // scope 3 at $DIR/issue_75439.rs:+4:27: +4:29
+ _4 = _2[3 of 4]; // scope 3 at $DIR/issue_75439.rs:+4:27: +4:29
+ goto -> bb4; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30
}
bb6: {
- StorageLive(_4); // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
- _4 = _2[3 of 4]; // scope 3 at $DIR/issue-75439.rs:+4:27: +4:29
- goto -> bb4; // scope 3 at $DIR/issue-75439.rs:+4:12: +4:30
+ StorageLive(_4); // scope 3 at $DIR/issue_75439.rs:+4:27: +4:29
+ _4 = _2[3 of 4]; // scope 3 at $DIR/issue_75439.rs:+4:27: +4:29
+ goto -> bb4; // scope 3 at $DIR/issue_75439.rs:+4:12: +4:30
}
bb7: {
- StorageDead(_6); // scope 4 at $DIR/issue-75439.rs:+5:35: +5:36
- Deinit(_0); // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39
- ((_0 as Some).0: [u8; 4]) = move _5; // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39
- discriminant(_0) = 1; // scope 3 at $DIR/issue-75439.rs:+5:9: +5:39
- StorageDead(_5); // scope 3 at $DIR/issue-75439.rs:+5:38: +5:39
- StorageDead(_4); // scope 1 at $DIR/issue-75439.rs:+6:5: +6:6
- goto -> bb9; // scope 1 at $DIR/issue-75439.rs:+4:5: +8:6
+ StorageDead(_6); // scope 4 at $DIR/issue_75439.rs:+5:35: +5:36
+ Deinit(_0); // scope 3 at $DIR/issue_75439.rs:+5:9: +5:39
+ ((_0 as Some).0: [u8; 4]) = move _5; // scope 3 at $DIR/issue_75439.rs:+5:9: +5:39
+ discriminant(_0) = 1; // scope 3 at $DIR/issue_75439.rs:+5:9: +5:39
+ StorageDead(_5); // scope 3 at $DIR/issue_75439.rs:+5:38: +5:39
+ StorageDead(_4); // scope 1 at $DIR/issue_75439.rs:+6:5: +6:6
+ goto -> bb9; // scope 1 at $DIR/issue_75439.rs:+4:5: +8:6
}
bb8: {
- Deinit(_0); // scope 1 at $DIR/issue-75439.rs:+7:9: +7:13
- discriminant(_0) = 0; // scope 1 at $DIR/issue-75439.rs:+7:9: +7:13
- goto -> bb9; // scope 1 at $DIR/issue-75439.rs:+4:5: +8:6
+ Deinit(_0); // scope 1 at $DIR/issue_75439.rs:+7:9: +7:13
+ discriminant(_0) = 0; // scope 1 at $DIR/issue_75439.rs:+7:9: +7:13
+ goto -> bb9; // scope 1 at $DIR/issue_75439.rs:+4:5: +8:6
}
bb9: {
- StorageDead(_2); // scope 0 at $DIR/issue-75439.rs:+9:1: +9:2
- return; // scope 0 at $DIR/issue-75439.rs:+9:2: +9:2
+ StorageDead(_2); // scope 0 at $DIR/issue_75439.rs:+9:1: +9:2
+ return; // scope 0 at $DIR/issue_75439.rs:+9:2: +9:2
}
}
diff --git a/src/test/mir-opt/issues/issue-75439.rs b/src/test/mir-opt/issues/issue_75439.rs
index ae2e03631..ae2e03631 100644
--- a/src/test/mir-opt/issues/issue-75439.rs
+++ b/src/test/mir-opt/issues/issue_75439.rs
diff --git a/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir b/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir
index 2c6c93cb1..9b1b07f38 100644
--- a/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir
+++ b/src/test/mir-opt/lower_array_len_e2e.array_bound.PreCodegen.after.mir
@@ -7,9 +7,8 @@ fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
let mut _3: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
let mut _4: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
let mut _5: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
- let _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
- let mut _7: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
- let mut _8: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ let mut _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ let mut _7: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
bb0: {
StorageLive(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
@@ -24,16 +23,13 @@ fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
}
bb1: {
- StorageLive(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
- _6 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
- _7 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
- _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ _6 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ _7 = Lt(_1, _6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _1) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
}
bb2: {
- _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
- StorageDead(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+3:5: +3:6
+ _0 = (*_2)[_1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
goto -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +5:6
}
diff --git a/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir b/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
index aee3a8242..29e379777 100644
--- a/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
+++ b/src/test/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
@@ -7,12 +7,11 @@ fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
let mut _3: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
let mut _4: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
let mut _5: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
- let _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
- let mut _7: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
- let mut _8: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
- let _9: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
- let mut _10: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
- let mut _11: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ let mut _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ let mut _7: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ let _8: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+ let mut _9: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ let mut _10: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
bb0: {
StorageLive(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
@@ -27,30 +26,27 @@ fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
}
bb1: {
- StorageLive(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
- _6 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
- _7 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
- _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ _6 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ _7 = Lt(_1, _6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
+ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _1) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
}
bb2: {
- _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
- StorageDead(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+3:5: +3:6
+ _0 = (*_2)[_1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
goto -> bb5; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6
}
bb3: {
- StorageLive(_9); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
- _9 = const 0_usize; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
- _10 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
- _11 = Lt(const 0_usize, _10); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
- assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ StorageLive(_8); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+ _8 = const 0_usize; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
+ _9 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ _10 = Lt(const 0_usize, _9); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
+ assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
}
bb4: {
- (*_2)[_9] = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:22
- StorageDead(_9); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:22: +4:23
+ (*_2)[_8] = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:22
+ StorageDead(_8); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:22: +4:23
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+6:9: +6:11
goto -> bb5; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6
}
diff --git a/src/test/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir b/src/test/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
index 8e185323e..f6d8bdd74 100644
--- a/src/test/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
+++ b/src/test/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
@@ -6,25 +6,20 @@ fn f_u64() -> () {
scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:15:5: 15:21
debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23
let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
- let mut _3: u64; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:19: 23:20
scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32
}
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
- _1 = const 0_u64; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
StorageLive(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
- StorageLive(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:19: 23:20
- _3 = move _1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:19: 23:20
- _2 = f_non_zst::<u64>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
+ _2 = f_non_zst::<u64>(const 0_u64) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
// mir::Constant
// + span: $DIR/lower_intrinsics_e2e.rs:23:9: 23:18
// + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:20: 23:21
StorageDead(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:21: 23:22
StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2
diff --git a/src/test/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir b/src/test/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
index a5b396ca0..b672e1a6e 100644
--- a/src/test/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
+++ b/src/test/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
@@ -6,7 +6,6 @@ fn f_unit() -> () {
scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics_e2e.rs:9:5: 9:19
debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23
let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
- let mut _3: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:21:15: 21:16
scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32
}
}
@@ -14,15 +13,13 @@ fn f_unit() -> () {
bb0: {
StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:16: +1:18
StorageLive(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
- StorageLive(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:15: 21:16
- _2 = f_zst::<()>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
+ _2 = f_zst::<()>(move _1) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
// mir::Constant
// + span: $DIR/lower_intrinsics_e2e.rs:21:9: 21:14
// + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:16: 21:17
StorageDead(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:17: 21:18
StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:18: +1:19
return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2
diff --git a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 25ab0c9f7..d3db3b182 100644
--- a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -2,271 +2,271 @@
+ // MIR for `complicated_match` after ElaborateDrops
fn complicated_match(_1: bool, _2: (bool, bool, String)) -> i32 {
- debug cond => _1; // in scope 0 at $DIR/match-arm-scopes.rs:+0:22: +0:26
- debug items => _2; // in scope 0 at $DIR/match-arm-scopes.rs:+0:34: +0:39
- let mut _0: i32; // return place in scope 0 at $DIR/match-arm-scopes.rs:+0:66: +0:69
- let mut _3: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
- let mut _4: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
- let _5: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
- let _6: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
- let _7: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
- let _8: &std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
- let mut _9: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
- let mut _10: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
- let mut _11: !; // in scope 0 at $DIR/match-arm-scopes.rs:+2:52: +2:60
- let mut _12: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
- let mut _13: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
- let mut _14: !; // in scope 0 at $DIR/match-arm-scopes.rs:+2:52: +2:60
- let _15: bool; // in scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17
- let _16: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20
+ debug cond => _1; // in scope 0 at $DIR/match_arm_scopes.rs:+0:22: +0:26
+ debug items => _2; // in scope 0 at $DIR/match_arm_scopes.rs:+0:34: +0:39
+ let mut _0: i32; // return place in scope 0 at $DIR/match_arm_scopes.rs:+0:66: +0:69
+ let mut _3: &bool; // in scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16
+ let mut _4: &bool; // in scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16
+ let _5: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18
+ let _6: &bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18
+ let _7: std::string::String; // in scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21
+ let _8: &std::string::String; // in scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21
+ let mut _9: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
+ let mut _10: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
+ let mut _11: !; // in scope 0 at $DIR/match_arm_scopes.rs:+2:52: +2:60
+ let mut _12: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
+ let mut _13: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
+ let mut _14: !; // in scope 0 at $DIR/match_arm_scopes.rs:+2:52: +2:60
+ let _15: bool; // in scope 0 at $DIR/match_arm_scopes.rs:+3:16: +3:17
+ let _16: std::string::String; // in scope 0 at $DIR/match_arm_scopes.rs:+3:19: +3:20
scope 1 {
- debug a => _5; // in scope 1 at $DIR/match-arm-scopes.rs:+2:17: +2:18
- debug a => _6; // in scope 1 at $DIR/match-arm-scopes.rs:+2:17: +2:18
- debug s => _7; // in scope 1 at $DIR/match-arm-scopes.rs:+2:20: +2:21
- debug s => _8; // in scope 1 at $DIR/match-arm-scopes.rs:+2:20: +2:21
+ debug a => _5; // in scope 1 at $DIR/match_arm_scopes.rs:+2:17: +2:18
+ debug a => _6; // in scope 1 at $DIR/match_arm_scopes.rs:+2:17: +2:18
+ debug s => _7; // in scope 1 at $DIR/match_arm_scopes.rs:+2:20: +2:21
+ debug s => _8; // in scope 1 at $DIR/match_arm_scopes.rs:+2:20: +2:21
}
scope 2 {
- debug b => _15; // in scope 2 at $DIR/match-arm-scopes.rs:+3:16: +3:17
- debug t => _16; // in scope 2 at $DIR/match-arm-scopes.rs:+3:19: +3:20
+ debug b => _15; // in scope 2 at $DIR/match_arm_scopes.rs:+3:16: +3:17
+ debug t => _16; // in scope 2 at $DIR/match_arm_scopes.rs:+3:19: +3:20
}
bb0: {
-- FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
-- switchInt((_2.0: bool)) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
-+ switchInt((_2.0: bool)) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
+- FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16
+- switchInt((_2.0: bool)) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16
++ switchInt((_2.0: bool)) -> [false: bb5, otherwise: bb1]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16
}
bb1: {
-- falseEdge -> [real: bb8, imaginary: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:+2:9: +2:22
-+ switchInt((_2.1: bool)) -> [false: bb10, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
+- falseEdge -> [real: bb8, imaginary: bb3]; // scope 0 at $DIR/match_arm_scopes.rs:+2:9: +2:22
++ switchInt((_2.1: bool)) -> [false: bb10, otherwise: bb2]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16
}
bb2: {
-- switchInt((_2.1: bool)) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
-+ switchInt((_2.0: bool)) -> [false: bb3, otherwise: bb17]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
+- switchInt((_2.1: bool)) -> [false: bb3, otherwise: bb4]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16
++ switchInt((_2.0: bool)) -> [false: bb3, otherwise: bb17]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16
}
bb3: {
-- falseEdge -> [real: bb13, imaginary: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+2:25: +2:38
+- falseEdge -> [real: bb13, imaginary: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+2:25: +2:38
- }
-
- bb4: {
-- switchInt((_2.0: bool)) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +1:16
+- switchInt((_2.0: bool)) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +1:16
- }
-
- bb5: {
-- falseEdge -> [real: bb20, imaginary: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:+3:9: +3:21
+- falseEdge -> [real: bb20, imaginary: bb6]; // scope 0 at $DIR/match_arm_scopes.rs:+3:9: +3:21
- }
-
- bb6: {
- StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:32: +3:33
- _15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+3:32: +3:33
- StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:35: +3:36
- _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+3:35: +3:36
-- goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
-+ goto -> bb16; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
+ StorageLive(_15); // scope 0 at $DIR/match_arm_scopes.rs:+3:32: +3:33
+ _15 = (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+3:32: +3:33
+ StorageLive(_16); // scope 0 at $DIR/match_arm_scopes.rs:+3:35: +3:36
+ _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+3:35: +3:36
+- goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6
++ goto -> bb16; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6
}
- bb7: {
+ bb4: {
- _0 = const 1_i32; // scope 1 at $DIR/match-arm-scopes.rs:+2:77: +2:78
-- drop(_7) -> [return: bb18, unwind: bb25]; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
-+ drop(_7) -> [return: bb15, unwind: bb22]; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+ _0 = const 1_i32; // scope 1 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+- drop(_7) -> [return: bb18, unwind: bb25]; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
++ drop(_7) -> [return: bb15, unwind: bb22]; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
}
- bb8: {
+ bb5: {
- StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
- _6 = &(_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
- StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
- _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
-- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
-- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
- StorageLive(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
- StorageLive(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
- _10 = _1; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
-- switchInt(move _10) -> [false: bb10, otherwise: bb9]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
-+ switchInt(move _10) -> [false: bb7, otherwise: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
+ StorageLive(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18
+ _6 = &(_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18
+ StorageLive(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21
+ _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21
+- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16
+- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16
+ StorageLive(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
+ StorageLive(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
+ _10 = _1; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
+- switchInt(move _10) -> [false: bb10, otherwise: bb9]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
++ switchInt(move _10) -> [false: bb7, otherwise: bb6]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
}
- bb9: {
+ bb6: {
- _0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:+2:59: +2:60
- StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
- StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ _0 = const 3_i32; // scope 0 at $DIR/match_arm_scopes.rs:+2:59: +2:60
+ StorageDead(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+ StorageDead(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
- goto -> bb23; // scope 0 at no-location
+ goto -> bb20; // scope 0 at no-location
}
- bb10: {
+ bb7: {
- _9 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:70: +2:71
-- switchInt(move _9) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
-+ switchInt(move _9) -> [false: bb9, otherwise: bb8]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ _9 = (*_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:70: +2:71
+- switchInt(move _9) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
++ switchInt(move _9) -> [false: bb9, otherwise: bb8]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
}
- bb11: {
+ bb8: {
- StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
- StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
-- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
-- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
-- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
-- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
- StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
- _5 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:17: +2:18
- StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
- _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:20: +2:21
-- goto -> bb7; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
-+ goto -> bb4; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
+ StorageDead(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+ StorageDead(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+ StorageLive(_5); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18
+ _5 = (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:17: +2:18
+ StorageLive(_7); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21
+ _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:20: +2:21
+- goto -> bb7; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6
++ goto -> bb4; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6
}
- bb12: {
+ bb9: {
- StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
- StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
- StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
- StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
-- falseEdge -> [real: bb2, imaginary: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
-+ goto -> bb1; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ StorageDead(_10); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+ StorageDead(_9); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+ StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+ StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+- falseEdge -> [real: bb2, imaginary: bb3]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
++ goto -> bb1; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
}
- bb13: {
+ bb10: {
- StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27
- _6 = &(_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27
- StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37
- _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37
-- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
-- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+1:11: +1:16
- StorageLive(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
- StorageLive(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
- _13 = _1; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
-- switchInt(move _13) -> [false: bb15, otherwise: bb14]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
-+ switchInt(move _13) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match-arm-scopes.rs:+2:45: +2:49
+ StorageLive(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27
+ _6 = &(_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27
+ StorageLive(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37
+ _8 = &(_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37
+- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16
+- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+1:11: +1:16
+ StorageLive(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
+ StorageLive(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
+ _13 = _1; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
+- switchInt(move _13) -> [false: bb15, otherwise: bb14]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
++ switchInt(move _13) -> [false: bb12, otherwise: bb11]; // scope 0 at $DIR/match_arm_scopes.rs:+2:45: +2:49
}
- bb14: {
+ bb11: {
- _0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:+2:59: +2:60
- StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
- StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
+ _0 = const 3_i32; // scope 0 at $DIR/match_arm_scopes.rs:+2:59: +2:60
+ StorageDead(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+ StorageDead(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
- goto -> bb23; // scope 0 at no-location
+ goto -> bb20; // scope 0 at no-location
}
- bb15: {
+ bb12: {
- _12 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:70: +2:71
-- switchInt(move _12) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
-+ switchInt(move _12) -> [false: bb14, otherwise: bb13]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ _12 = (*_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:70: +2:71
+- switchInt(move _12) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
++ switchInt(move _12) -> [false: bb14, otherwise: bb13]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
}
- bb16: {
+ bb13: {
- StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
- StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
-- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
-- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
-- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
-- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
- StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27
- _5 = (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:+2:26: +2:27
- StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37
- _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+2:36: +2:37
-- goto -> bb7; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
-+ goto -> bb4; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
+ StorageDead(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+ StorageDead(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+ StorageLive(_5); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27
+ _5 = (_2.0: bool); // scope 0 at $DIR/match_arm_scopes.rs:+2:26: +2:27
+ StorageLive(_7); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37
+ _7 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+2:36: +2:37
+- goto -> bb7; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6
++ goto -> bb4; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6
}
- bb17: {
+ bb14: {
- StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
- StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:+2:72: +2:73
- StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
- StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
-- falseEdge -> [real: bb4, imaginary: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
-+ goto -> bb2; // scope 0 at $DIR/match-arm-scopes.rs:+2:42: +2:73
+ StorageDead(_13); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+ StorageDead(_12); // scope 0 at $DIR/match_arm_scopes.rs:+2:72: +2:73
+ StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+ StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+- falseEdge -> [real: bb4, imaginary: bb5]; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
++ goto -> bb2; // scope 0 at $DIR/match_arm_scopes.rs:+2:42: +2:73
}
- bb18: {
+ bb15: {
- StorageDead(_7); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
- StorageDead(_5); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
- StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
- StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
-- goto -> bb22; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
-+ goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
+ StorageDead(_7); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+ StorageDead(_5); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+ StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+ StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+- goto -> bb22; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
++ goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
}
- bb19: {
+ bb16: {
- _0 = const 2_i32; // scope 2 at $DIR/match-arm-scopes.rs:+3:41: +3:42
-- drop(_16) -> [return: bb21, unwind: bb25]; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
-+ drop(_16) -> [return: bb18, unwind: bb22]; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
+ _0 = const 2_i32; // scope 2 at $DIR/match_arm_scopes.rs:+3:41: +3:42
+- drop(_16) -> [return: bb21, unwind: bb25]; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42
++ drop(_16) -> [return: bb18, unwind: bb22]; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42
}
- bb20: {
+ bb17: {
- StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17
- _15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:+3:16: +3:17
- StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20
- _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:+3:19: +3:20
-- goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
-+ goto -> bb16; // scope 0 at $DIR/match-arm-scopes.rs:+1:5: +4:6
+ StorageLive(_15); // scope 0 at $DIR/match_arm_scopes.rs:+3:16: +3:17
+ _15 = (_2.1: bool); // scope 0 at $DIR/match_arm_scopes.rs:+3:16: +3:17
+ StorageLive(_16); // scope 0 at $DIR/match_arm_scopes.rs:+3:19: +3:20
+ _16 = move (_2.2: std::string::String); // scope 0 at $DIR/match_arm_scopes.rs:+3:19: +3:20
+- goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6
++ goto -> bb16; // scope 0 at $DIR/match_arm_scopes.rs:+1:5: +4:6
}
- bb21: {
+ bb18: {
- StorageDead(_16); // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
- StorageDead(_15); // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
-- goto -> bb22; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
-+ goto -> bb19; // scope 0 at $DIR/match-arm-scopes.rs:+3:41: +3:42
+ StorageDead(_16); // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42
+ StorageDead(_15); // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42
+- goto -> bb22; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42
++ goto -> bb19; // scope 0 at $DIR/match_arm_scopes.rs:+3:41: +3:42
}
- bb22: {
-- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
+- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2
+ bb19: {
-+ goto -> bb26; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ goto -> bb26; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2
}
- bb23: {
+ bb20: {
- StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
- StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:+2:77: +2:78
-- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
-+ drop(_2) -> [return: bb21, unwind: bb23]; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
+ StorageDead(_8); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+ StorageDead(_6); // scope 0 at $DIR/match_arm_scopes.rs:+2:77: +2:78
+- drop(_2) -> [return: bb24, unwind: bb26]; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2
++ drop(_2) -> [return: bb21, unwind: bb23]; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2
}
- bb24: {
+ bb21: {
- return; // scope 0 at $DIR/match-arm-scopes.rs:+5:2: +5:2
+ return; // scope 0 at $DIR/match_arm_scopes.rs:+5:2: +5:2
}
- bb25 (cleanup): {
-- drop(_2) -> bb26; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
+- drop(_2) -> bb26; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2
+ bb22 (cleanup): {
-+ goto -> bb27; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ goto -> bb27; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2
}
- bb26 (cleanup): {
+ bb23 (cleanup): {
- resume; // scope 0 at $DIR/match-arm-scopes.rs:+0:1: +5:2
+ resume; // scope 0 at $DIR/match_arm_scopes.rs:+0:1: +5:2
+ }
+
+ bb24: {
-+ goto -> bb21; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ goto -> bb21; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2
+ }
+
+ bb25 (cleanup): {
-+ goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ goto -> bb23; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2
+ }
+
+ bb26: {
-+ goto -> bb24; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ goto -> bb24; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2
+ }
+
+ bb27 (cleanup): {
-+ goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:+5:1: +5:2
++ goto -> bb23; // scope 0 at $DIR/match_arm_scopes.rs:+5:1: +5:2
}
}
diff --git a/src/test/mir-opt/match-arm-scopes.rs b/src/test/mir-opt/match_arm_scopes.rs
index 7b7de7788..7b7de7788 100644
--- a/src/test/mir-opt/match-arm-scopes.rs
+++ b/src/test/mir-opt/match_arm_scopes.rs
diff --git a/src/test/mir-opt/nll/named-lifetimes-basic.rs b/src/test/mir-opt/nll/named_lifetimes_basic.rs
index 843716033..843716033 100644
--- a/src/test/mir-opt/nll/named-lifetimes-basic.rs
+++ b/src/test/mir-opt/nll/named_lifetimes_basic.rs
diff --git a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
index 0ab9d712d..6cd6d8b77 100644
--- a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
+++ b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir
@@ -24,24 +24,24 @@
| '_#2r live at {bb0[0..=1]}
| '_#3r live at {bb0[0..=1]}
| '_#4r live at {bb0[0..=1]}
-| '_#1r: '_#5r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0)
-| '_#1r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0)
-| '_#2r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0)
-| '_#3r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0)
-| '_#5r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0)
-| '_#6r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0)
-| '_#7r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0)
-| '_#8r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0)
+| '_#1r: '_#5r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:26: 12:27) ($DIR/named_lifetimes_basic.rs:12:26: 12:27 (#0)
+| '_#1r: '_#7r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:54: 12:55) ($DIR/named_lifetimes_basic.rs:12:54: 12:55 (#0)
+| '_#2r: '_#6r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:42: 12:43) ($DIR/named_lifetimes_basic.rs:12:42: 12:43 (#0)
+| '_#3r: '_#8r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0)
+| '_#5r: '_#1r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:26: 12:27) ($DIR/named_lifetimes_basic.rs:12:26: 12:27 (#0)
+| '_#6r: '_#2r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:42: 12:43) ($DIR/named_lifetimes_basic.rs:12:42: 12:43 (#0)
+| '_#7r: '_#1r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:54: 12:55) ($DIR/named_lifetimes_basic.rs:12:54: 12:55 (#0)
+| '_#8r: '_#3r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0)
|
fn use_x(_1: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r u32) -> bool {
- debug w => _1; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:26: +0:27
- debug x => _2; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:42: +0:43
- debug y => _3; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:54: +0:55
- debug z => _4; // in scope 0 at $DIR/named-lifetimes-basic.rs:+0:66: +0:67
- let mut _0: bool; // return place in scope 0 at $DIR/named-lifetimes-basic.rs:+0:81: +0:85
+ debug w => _1; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:26: +0:27
+ debug x => _2; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:42: +0:43
+ debug y => _3; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:54: +0:55
+ debug z => _4; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:66: +0:67
+ let mut _0: bool; // return place in scope 0 at $DIR/named_lifetimes_basic.rs:+0:81: +0:85
bb0: {
- _0 = const ConstValue(Scalar(0x01): bool); // bb0[0]: scope 0 at $DIR/named-lifetimes-basic.rs:+0:88: +0:92
- return; // bb0[1]: scope 0 at $DIR/named-lifetimes-basic.rs:+0:94: +0:94
+ _0 = const ConstValue(Scalar(0x01): bool); // bb0[0]: scope 0 at $DIR/named_lifetimes_basic.rs:+0:88: +0:92
+ return; // bb0[1]: scope 0 at $DIR/named_lifetimes_basic.rs:+0:94: +0:94
}
}
diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
index 36705d18e..3e3fda614 100644
--- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
+++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
@@ -17,95 +17,95 @@
| '_#2r live at {bb1[0]}
| '_#3r live at {bb1[1..=3]}
| '_#4r live at {bb1[4..=7], bb2[0..=2]}
-| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0)
-| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
+| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0)
+| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:19:13: 19:14 (#0)
|
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11
- let mut _1: [usize; Const { ty: usize, kind: Value(Leaf(0x00000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
- let _3: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:16: +2:17
- let mut _4: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
- let mut _5: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
- let mut _7: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
- let _8: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
- let mut _9: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
- let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
+ let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11
+ let mut _1: [usize; Const { ty: usize, kind: Value(Leaf(0x00000003)) }]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
+ let _3: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:16: +2:17
+ let mut _4: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
+ let mut _5: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
+ let mut _7: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+4:8: +4:12
+ let _8: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+5:9: +5:18
+ let mut _9: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+5:15: +5:17
+ let _10: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+7:9: +7:18
scope 1 {
- debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
- let _2: &'_#3r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ debug v => _1; // in scope 1 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
+ let _2: &'_#3r usize; // in scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
scope 2 {
- debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
- let _6: &'_#4r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ debug p => _2; // in scope 2 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ let _6: &'_#4r usize; // in scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
scope 3 {
- debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ debug q => _6; // in scope 3 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
}
}
}
bb0: {
- StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
- _1 = [const ConstValue(Scalar(0x00000001): usize), const ConstValue(Scalar(0x00000002): usize), const ConstValue(Scalar(0x00000003): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:+1:17: +1:26
- FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
- StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
- StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17
- _3 = const ConstValue(Scalar(0x00000000): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17
- _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
- _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
+ StorageLive(_1); // bb0[0]: scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
+ _1 = [const ConstValue(Scalar(0x00000001): usize), const ConstValue(Scalar(0x00000002): usize), const ConstValue(Scalar(0x00000003): usize)]; // bb0[1]: scope 0 at $DIR/region_subtyping_basic.rs:+1:17: +1:26
+ FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
+ StorageLive(_2); // bb0[3]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ StorageLive(_3); // bb0[4]: scope 1 at $DIR/region_subtyping_basic.rs:+2:16: +2:17
+ _3 = const ConstValue(Scalar(0x00000000): usize); // bb0[5]: scope 1 at $DIR/region_subtyping_basic.rs:+2:16: +2:17
+ _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
+ _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
}
bb1: {
- _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18
- FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
- StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
- _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14
- FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
- StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
- _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
- switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
+ _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region_subtyping_basic.rs:+2:13: +2:18
+ FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ StorageLive(_6); // bb1[2]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
+ _6 = _2; // bb1[3]: scope 2 at $DIR/region_subtyping_basic.rs:+3:13: +3:14
+ FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
+ StorageLive(_7); // bb1[5]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12
+ _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12
+ switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12
}
bb2: {
- StorageLive(_8); // bb2[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
- StorageLive(_9); // bb2[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
- _9 = (*_6); // bb2[2]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
- _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
+ StorageLive(_8); // bb2[0]: scope 3 at $DIR/region_subtyping_basic.rs:+5:9: +5:18
+ StorageLive(_9); // bb2[1]: scope 3 at $DIR/region_subtyping_basic.rs:+5:15: +5:17
+ _9 = (*_6); // bb2[2]: scope 3 at $DIR/region_subtyping_basic.rs:+5:15: +5:17
+ _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region_subtyping_basic.rs:+5:9: +5:18
// mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
+ // + span: $DIR/region_subtyping_basic.rs:21:9: 21:14
// + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) }
}
bb3: {
- StorageDead(_9); // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:17: +5:18
- StorageDead(_8); // bb3[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:18: +5:19
- _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:13: +6:6
- goto -> bb6; // bb3[3]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6
+ StorageDead(_9); // bb3[0]: scope 3 at $DIR/region_subtyping_basic.rs:+5:17: +5:18
+ StorageDead(_8); // bb3[1]: scope 3 at $DIR/region_subtyping_basic.rs:+5:18: +5:19
+ _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region_subtyping_basic.rs:+4:13: +6:6
+ goto -> bb6; // bb3[3]: scope 3 at $DIR/region_subtyping_basic.rs:+4:5: +8:6
}
bb4: {
- StorageLive(_10); // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
- _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
+ StorageLive(_10); // bb4[0]: scope 3 at $DIR/region_subtyping_basic.rs:+7:9: +7:18
+ _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region_subtyping_basic.rs:+7:9: +7:18
// mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14
+ // + span: $DIR/region_subtyping_basic.rs:23:9: 23:14
// + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) }
}
bb5: {
- StorageDead(_10); // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:18: +7:19
- _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:+6:12: +8:6
- goto -> bb6; // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6
+ StorageDead(_10); // bb5[0]: scope 3 at $DIR/region_subtyping_basic.rs:+7:18: +7:19
+ _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region_subtyping_basic.rs:+6:12: +8:6
+ goto -> bb6; // bb5[2]: scope 3 at $DIR/region_subtyping_basic.rs:+4:5: +8:6
}
bb6: {
- StorageDead(_7); // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:+8:5: +8:6
- StorageDead(_6); // bb6[1]: scope 2 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
- StorageDead(_3); // bb6[2]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
- StorageDead(_2); // bb6[3]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
- StorageDead(_1); // bb6[4]: scope 0 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
- return; // bb6[5]: scope 0 at $DIR/region-subtyping-basic.rs:+9:2: +9:2
+ StorageDead(_7); // bb6[0]: scope 3 at $DIR/region_subtyping_basic.rs:+8:5: +8:6
+ StorageDead(_6); // bb6[1]: scope 2 at $DIR/region_subtyping_basic.rs:+9:1: +9:2
+ StorageDead(_3); // bb6[2]: scope 1 at $DIR/region_subtyping_basic.rs:+9:1: +9:2
+ StorageDead(_2); // bb6[3]: scope 1 at $DIR/region_subtyping_basic.rs:+9:1: +9:2
+ StorageDead(_1); // bb6[4]: scope 0 at $DIR/region_subtyping_basic.rs:+9:1: +9:2
+ return; // bb6[5]: scope 0 at $DIR/region_subtyping_basic.rs:+9:2: +9:2
}
bb7 (cleanup): {
- resume; // bb7[0]: scope 0 at $DIR/region-subtyping-basic.rs:+0:1: +9:2
+ resume; // bb7[0]: scope 0 at $DIR/region_subtyping_basic.rs:+0:1: +9:2
}
}
diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
index 4f6256a67..39a53702a 100644
--- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
+++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
@@ -17,95 +17,95 @@
| '_#2r live at {bb1[0]}
| '_#3r live at {bb1[1..=3]}
| '_#4r live at {bb1[4..=7], bb2[0..=2]}
-| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0)
-| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
+| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0)
+| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:19:13: 19:14 (#0)
|
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:+0:11: +0:11
- let mut _1: [usize; Const { ty: usize, kind: Value(Leaf(0x0000000000000003)) }]; // in scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
- let _3: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:16: +2:17
- let mut _4: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
- let mut _5: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
- let mut _7: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
- let _8: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
- let mut _9: usize; // in scope 0 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
- let _10: bool; // in scope 0 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
+ let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11
+ let mut _1: [usize; Const { ty: usize, kind: Value(Leaf(0x0000000000000003)) }]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
+ let _3: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:16: +2:17
+ let mut _4: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
+ let mut _5: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
+ let mut _7: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+4:8: +4:12
+ let _8: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+5:9: +5:18
+ let mut _9: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+5:15: +5:17
+ let _10: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+7:9: +7:18
scope 1 {
- debug v => _1; // in scope 1 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
- let _2: &'_#3r usize; // in scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
+ debug v => _1; // in scope 1 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
+ let _2: &'_#3r usize; // in scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
scope 2 {
- debug p => _2; // in scope 2 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
- let _6: &'_#4r usize; // in scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ debug p => _2; // in scope 2 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ let _6: &'_#4r usize; // in scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
scope 3 {
- debug q => _6; // in scope 3 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
+ debug q => _6; // in scope 3 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
}
}
}
bb0: {
- StorageLive(_1); // bb0[0]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
- _1 = [const ConstValue(Scalar(0x0000000000000001): usize), const ConstValue(Scalar(0x0000000000000002): usize), const ConstValue(Scalar(0x0000000000000003): usize)]; // bb0[1]: scope 0 at $DIR/region-subtyping-basic.rs:+1:17: +1:26
- FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region-subtyping-basic.rs:+1:9: +1:14
- StorageLive(_2); // bb0[3]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
- StorageLive(_3); // bb0[4]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17
- _3 = const ConstValue(Scalar(0x0000000000000000): usize); // bb0[5]: scope 1 at $DIR/region-subtyping-basic.rs:+2:16: +2:17
- _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
- _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
- assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region-subtyping-basic.rs:+2:14: +2:18
+ StorageLive(_1); // bb0[0]: scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
+ _1 = [const ConstValue(Scalar(0x0000000000000001): usize), const ConstValue(Scalar(0x0000000000000002): usize), const ConstValue(Scalar(0x0000000000000003): usize)]; // bb0[1]: scope 0 at $DIR/region_subtyping_basic.rs:+1:17: +1:26
+ FakeRead(ForLet(None), _1); // bb0[2]: scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14
+ StorageLive(_2); // bb0[3]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ StorageLive(_3); // bb0[4]: scope 1 at $DIR/region_subtyping_basic.rs:+2:16: +2:17
+ _3 = const ConstValue(Scalar(0x0000000000000000): usize); // bb0[5]: scope 1 at $DIR/region_subtyping_basic.rs:+2:16: +2:17
+ _4 = Len(_1); // bb0[6]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
+ _5 = Lt(_3, _4); // bb0[7]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
+ assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, _3) -> [success: bb1, unwind: bb7]; // bb0[8]: scope 1 at $DIR/region_subtyping_basic.rs:+2:14: +2:18
}
bb1: {
- _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region-subtyping-basic.rs:+2:13: +2:18
- FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region-subtyping-basic.rs:+2:9: +2:10
- StorageLive(_6); // bb1[2]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
- _6 = _2; // bb1[3]: scope 2 at $DIR/region-subtyping-basic.rs:+3:13: +3:14
- FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region-subtyping-basic.rs:+3:9: +3:10
- StorageLive(_7); // bb1[5]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
- _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
- switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region-subtyping-basic.rs:+4:8: +4:12
+ _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region_subtyping_basic.rs:+2:13: +2:18
+ FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10
+ StorageLive(_6); // bb1[2]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
+ _6 = _2; // bb1[3]: scope 2 at $DIR/region_subtyping_basic.rs:+3:13: +3:14
+ FakeRead(ForLet(None), _6); // bb1[4]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10
+ StorageLive(_7); // bb1[5]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12
+ _7 = const ConstValue(Scalar(0x01): bool); // bb1[6]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12
+ switchInt(move _7) -> [ConstValue(Scalar(0x00): bool): bb4, otherwise: bb2]; // bb1[7]: scope 3 at $DIR/region_subtyping_basic.rs:+4:8: +4:12
}
bb2: {
- StorageLive(_8); // bb2[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
- StorageLive(_9); // bb2[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
- _9 = (*_6); // bb2[2]: scope 3 at $DIR/region-subtyping-basic.rs:+5:15: +5:17
- _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region-subtyping-basic.rs:+5:9: +5:18
+ StorageLive(_8); // bb2[0]: scope 3 at $DIR/region_subtyping_basic.rs:+5:9: +5:18
+ StorageLive(_9); // bb2[1]: scope 3 at $DIR/region_subtyping_basic.rs:+5:15: +5:17
+ _9 = (*_6); // bb2[2]: scope 3 at $DIR/region_subtyping_basic.rs:+5:15: +5:17
+ _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7]; // bb2[3]: scope 3 at $DIR/region_subtyping_basic.rs:+5:9: +5:18
// mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:21:9: 21:14
+ // + span: $DIR/region_subtyping_basic.rs:21:9: 21:14
// + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) }
}
bb3: {
- StorageDead(_9); // bb3[0]: scope 3 at $DIR/region-subtyping-basic.rs:+5:17: +5:18
- StorageDead(_8); // bb3[1]: scope 3 at $DIR/region-subtyping-basic.rs:+5:18: +5:19
- _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:13: +6:6
- goto -> bb6; // bb3[3]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6
+ StorageDead(_9); // bb3[0]: scope 3 at $DIR/region_subtyping_basic.rs:+5:17: +5:18
+ StorageDead(_8); // bb3[1]: scope 3 at $DIR/region_subtyping_basic.rs:+5:18: +5:19
+ _0 = const ConstValue(ZeroSized: ()); // bb3[2]: scope 3 at $DIR/region_subtyping_basic.rs:+4:13: +6:6
+ goto -> bb6; // bb3[3]: scope 3 at $DIR/region_subtyping_basic.rs:+4:5: +8:6
}
bb4: {
- StorageLive(_10); // bb4[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
- _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region-subtyping-basic.rs:+7:9: +7:18
+ StorageLive(_10); // bb4[0]: scope 3 at $DIR/region_subtyping_basic.rs:+7:9: +7:18
+ _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7]; // bb4[1]: scope 3 at $DIR/region_subtyping_basic.rs:+7:9: +7:18
// mir::Constant
- // + span: $DIR/region-subtyping-basic.rs:23:9: 23:14
+ // + span: $DIR/region_subtyping_basic.rs:23:9: 23:14
// + literal: Const { ty: fn(usize) -> bool {use_x}, val: Value(<ZST>) }
}
bb5: {
- StorageDead(_10); // bb5[0]: scope 3 at $DIR/region-subtyping-basic.rs:+7:18: +7:19
- _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region-subtyping-basic.rs:+6:12: +8:6
- goto -> bb6; // bb5[2]: scope 3 at $DIR/region-subtyping-basic.rs:+4:5: +8:6
+ StorageDead(_10); // bb5[0]: scope 3 at $DIR/region_subtyping_basic.rs:+7:18: +7:19
+ _0 = const ConstValue(ZeroSized: ()); // bb5[1]: scope 3 at $DIR/region_subtyping_basic.rs:+6:12: +8:6
+ goto -> bb6; // bb5[2]: scope 3 at $DIR/region_subtyping_basic.rs:+4:5: +8:6
}
bb6: {
- StorageDead(_7); // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:+8:5: +8:6
- StorageDead(_6); // bb6[1]: scope 2 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
- StorageDead(_3); // bb6[2]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
- StorageDead(_2); // bb6[3]: scope 1 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
- StorageDead(_1); // bb6[4]: scope 0 at $DIR/region-subtyping-basic.rs:+9:1: +9:2
- return; // bb6[5]: scope 0 at $DIR/region-subtyping-basic.rs:+9:2: +9:2
+ StorageDead(_7); // bb6[0]: scope 3 at $DIR/region_subtyping_basic.rs:+8:5: +8:6
+ StorageDead(_6); // bb6[1]: scope 2 at $DIR/region_subtyping_basic.rs:+9:1: +9:2
+ StorageDead(_3); // bb6[2]: scope 1 at $DIR/region_subtyping_basic.rs:+9:1: +9:2
+ StorageDead(_2); // bb6[3]: scope 1 at $DIR/region_subtyping_basic.rs:+9:1: +9:2
+ StorageDead(_1); // bb6[4]: scope 0 at $DIR/region_subtyping_basic.rs:+9:1: +9:2
+ return; // bb6[5]: scope 0 at $DIR/region_subtyping_basic.rs:+9:2: +9:2
}
bb7 (cleanup): {
- resume; // bb7[0]: scope 0 at $DIR/region-subtyping-basic.rs:+0:1: +9:2
+ resume; // bb7[0]: scope 0 at $DIR/region_subtyping_basic.rs:+0:1: +9:2
}
}
diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region_subtyping_basic.rs
index 64332f302..64332f302 100644
--- a/src/test/mir-opt/nll/region-subtyping-basic.rs
+++ b/src/test/mir-opt/nll/region_subtyping_basic.rs
diff --git a/src/test/mir-opt/no-drop-for-inactive-variant.rs b/src/test/mir-opt/no_drop_for_inactive_variant.rs
index 34e2b1a13..34e2b1a13 100644
--- a/src/test/mir-opt/no-drop-for-inactive-variant.rs
+++ b/src/test/mir-opt/no_drop_for_inactive_variant.rs
diff --git a/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir
index 50fd98ff1..e708255ce 100644
--- a/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir
@@ -1,21 +1,21 @@
// MIR for `unwrap` after SimplifyCfg-elaborate-drops
fn unwrap(_1: Option<T>) -> T {
- debug opt => _1; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:14: +0:17
- let mut _0: T; // return place in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:33: +0:34
- let mut _2: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:9: +2:16
- let _3: T; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15
+ debug opt => _1; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+0:14: +0:17
+ let mut _0: T; // return place in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+0:33: +0:34
+ let mut _2: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:9: +2:16
+ let _3: T; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15
let mut _4: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
- let mut _5: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2
- let mut _6: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2
- let mut _7: isize; // in scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2
+ let mut _5: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2
+ let mut _6: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2
+ let mut _7: isize; // in scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2
scope 1 {
- debug x => _3; // in scope 1 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15
+ debug x => _3; // in scope 1 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15
}
bb0: {
- _2 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:11: +1:14
- switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:5: +1:14
+ _2 = discriminant(_1); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:11: +1:14
+ switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:5: +1:14
}
bb1: {
@@ -30,20 +30,20 @@ fn unwrap(_1: Option<T>) -> T {
}
bb2: {
- unreachable; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+1:11: +1:14
+ unreachable; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+1:11: +1:14
}
bb3: {
- StorageLive(_3); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15
- _3 = move ((_1 as Some).0: T); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:14: +2:15
- _0 = move _3; // scope 1 at $DIR/no-drop-for-inactive-variant.rs:+2:20: +2:21
- StorageDead(_3); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+2:20: +2:21
- _5 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2
- return; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:2: +5:2
+ StorageLive(_3); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15
+ _3 = move ((_1 as Some).0: T); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:14: +2:15
+ _0 = move _3; // scope 1 at $DIR/no_drop_for_inactive_variant.rs:+2:20: +2:21
+ StorageDead(_3); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+2:20: +2:21
+ _5 = discriminant(_1); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:2: +5:2
}
bb4 (cleanup): {
- _7 = discriminant(_1); // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+5:1: +5:2
- resume; // scope 0 at $DIR/no-drop-for-inactive-variant.rs:+0:1: +5:2
+ _7 = discriminant(_1); // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+5:1: +5:2
+ resume; // scope 0 at $DIR/no_drop_for_inactive_variant.rs:+0:1: +5:2
}
}
diff --git a/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir
index 963e7cde6..0cb34a2f2 100644
--- a/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir
+++ b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir
@@ -1,49 +1,49 @@
// MIR for `main` before ElaborateDrops
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:11: +0:11
- let _1: (); // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35
- let mut _2: std::string::String; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
- let mut _3: &str; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
- let _4: &str; // in scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22
+ let mut _0: (); // return place in scope 0 at $DIR/no_spurious_drop_after_call.rs:+0:11: +0:11
+ let _1: (); // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:5: +1:35
+ let mut _2: std::string::String; // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34
+ let mut _3: &str; // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34
+ let _4: &str; // in scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:22
bb0: {
- StorageLive(_1); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35
- StorageLive(_2); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
- StorageLive(_3); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
- StorageLive(_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22
- _4 = const ""; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:22
+ StorageLive(_1); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:5: +1:35
+ StorageLive(_2); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34
+ StorageLive(_3); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34
+ StorageLive(_4); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:22
+ _4 = const ""; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:22
// mir::Constant
- // + span: $DIR/no-spurious-drop-after-call.rs:9:20: 9:22
+ // + span: $DIR/no_spurious_drop_after_call.rs:9:20: 9:22
// + literal: Const { ty: &str, val: Value(Slice(..)) }
- _3 = &(*_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
- _2 = <str as ToString>::to_string(move _3) -> bb1; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:20: +1:34
+ _3 = &(*_4); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34
+ _2 = <str as ToString>::to_string(move _3) -> bb1; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:20: +1:34
// mir::Constant
- // + span: $DIR/no-spurious-drop-after-call.rs:9:23: 9:32
+ // + span: $DIR/no_spurious_drop_after_call.rs:9:23: 9:32
// + literal: Const { ty: for<'a> fn(&'a str) -> String {<str as ToString>::to_string}, val: Value(<ZST>) }
}
bb1: {
- StorageDead(_3); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:33: +1:34
- _1 = std::mem::drop::<String>(move _2) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:5: +1:35
+ StorageDead(_3); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:33: +1:34
+ _1 = std::mem::drop::<String>(move _2) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:5: +1:35
// mir::Constant
- // + span: $DIR/no-spurious-drop-after-call.rs:9:5: 9:19
+ // + span: $DIR/no_spurious_drop_after_call.rs:9:5: 9:19
// + literal: Const { ty: fn(String) {std::mem::drop::<String>}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_2); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:34: +1:35
- StorageDead(_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:35: +1:36
- StorageDead(_1); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:35: +1:36
- _0 = const (); // scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:11: +2:2
- return; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+2:2: +2:2
+ StorageDead(_2); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:34: +1:35
+ StorageDead(_4); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:35: +1:36
+ StorageDead(_1); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:35: +1:36
+ _0 = const (); // scope 0 at $DIR/no_spurious_drop_after_call.rs:+0:11: +2:2
+ return; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+2:2: +2:2
}
bb3 (cleanup): {
- drop(_2) -> bb4; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+1:34: +1:35
+ drop(_2) -> bb4; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+1:34: +1:35
}
bb4 (cleanup): {
- resume; // scope 0 at $DIR/no-spurious-drop-after-call.rs:+0:1: +2:2
+ resume; // scope 0 at $DIR/no_spurious_drop_after_call.rs:+0:1: +2:2
}
}
diff --git a/src/test/mir-opt/no-spurious-drop-after-call.rs b/src/test/mir-opt/no_spurious_drop_after_call.rs
index bb5bb9aa4..bb5bb9aa4 100644
--- a/src/test/mir-opt/no-spurious-drop-after-call.rs
+++ b/src/test/mir-opt/no_spurious_drop_after_call.rs
diff --git a/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff
index ce35f920b..61a16065b 100644
--- a/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff
+++ b/src/test/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.diff
@@ -2,42 +2,42 @@
+ // MIR for `nrvo` after RenameReturnPlace
fn nrvo(_1: for<'a> fn(&'a mut [u8; 1024])) -> [u8; 1024] {
- debug init => _1; // in scope 0 at $DIR/nrvo-simple.rs:+0:9: +0:13
-- let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo-simple.rs:+0:39: +0:49
-+ let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16
- let mut _2: [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16
- let _3: (); // in scope 0 at $DIR/nrvo-simple.rs:+2:5: +2:19
- let mut _4: for<'a> fn(&'a mut [u8; 1024]); // in scope 0 at $DIR/nrvo-simple.rs:+2:5: +2:9
- let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+2:10: +2:18
- let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo-simple.rs:+2:10: +2:18
+ debug init => _1; // in scope 0 at $DIR/nrvo_simple.rs:+0:9: +0:13
+- let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo_simple.rs:+0:39: +0:49
++ let mut _0: [u8; 1024]; // return place in scope 0 at $DIR/nrvo_simple.rs:+1:9: +1:16
+ let mut _2: [u8; 1024]; // in scope 0 at $DIR/nrvo_simple.rs:+1:9: +1:16
+ let _3: (); // in scope 0 at $DIR/nrvo_simple.rs:+2:5: +2:19
+ let mut _4: for<'a> fn(&'a mut [u8; 1024]); // in scope 0 at $DIR/nrvo_simple.rs:+2:5: +2:9
+ let mut _5: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo_simple.rs:+2:10: +2:18
+ let mut _6: &mut [u8; 1024]; // in scope 0 at $DIR/nrvo_simple.rs:+2:10: +2:18
scope 1 {
-- debug buf => _2; // in scope 1 at $DIR/nrvo-simple.rs:+1:9: +1:16
-+ debug buf => _0; // in scope 1 at $DIR/nrvo-simple.rs:+1:9: +1:16
+- debug buf => _2; // in scope 1 at $DIR/nrvo_simple.rs:+1:9: +1:16
++ debug buf => _0; // in scope 1 at $DIR/nrvo_simple.rs:+1:9: +1:16
}
bb0: {
-- StorageLive(_2); // scope 0 at $DIR/nrvo-simple.rs:+1:9: +1:16
-- _2 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo-simple.rs:+1:19: +1:28
-+ _0 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo-simple.rs:+1:19: +1:28
- StorageLive(_3); // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:19
- StorageLive(_4); // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:9
- _4 = _1; // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:9
- StorageLive(_5); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18
- StorageLive(_6); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18
-- _6 = &mut _2; // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18
-+ _6 = &mut _0; // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18
- _5 = &mut (*_6); // scope 1 at $DIR/nrvo-simple.rs:+2:10: +2:18
- _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/nrvo-simple.rs:+2:5: +2:19
+- StorageLive(_2); // scope 0 at $DIR/nrvo_simple.rs:+1:9: +1:16
+- _2 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo_simple.rs:+1:19: +1:28
++ _0 = [const 0_u8; 1024]; // scope 0 at $DIR/nrvo_simple.rs:+1:19: +1:28
+ StorageLive(_3); // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:19
+ StorageLive(_4); // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:9
+ _4 = _1; // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:9
+ StorageLive(_5); // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18
+ StorageLive(_6); // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18
+- _6 = &mut _2; // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18
++ _6 = &mut _0; // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18
+ _5 = &mut (*_6); // scope 1 at $DIR/nrvo_simple.rs:+2:10: +2:18
+ _3 = move _4(move _5) -> bb1; // scope 1 at $DIR/nrvo_simple.rs:+2:5: +2:19
}
bb1: {
- StorageDead(_5); // scope 1 at $DIR/nrvo-simple.rs:+2:18: +2:19
- StorageDead(_4); // scope 1 at $DIR/nrvo-simple.rs:+2:18: +2:19
- StorageDead(_6); // scope 1 at $DIR/nrvo-simple.rs:+2:19: +2:20
- StorageDead(_3); // scope 1 at $DIR/nrvo-simple.rs:+2:19: +2:20
-- _0 = _2; // scope 1 at $DIR/nrvo-simple.rs:+3:5: +3:8
-- StorageDead(_2); // scope 0 at $DIR/nrvo-simple.rs:+4:1: +4:2
- return; // scope 0 at $DIR/nrvo-simple.rs:+4:2: +4:2
+ StorageDead(_5); // scope 1 at $DIR/nrvo_simple.rs:+2:18: +2:19
+ StorageDead(_4); // scope 1 at $DIR/nrvo_simple.rs:+2:18: +2:19
+ StorageDead(_6); // scope 1 at $DIR/nrvo_simple.rs:+2:19: +2:20
+ StorageDead(_3); // scope 1 at $DIR/nrvo_simple.rs:+2:19: +2:20
+- _0 = _2; // scope 1 at $DIR/nrvo_simple.rs:+3:5: +3:8
+- StorageDead(_2); // scope 0 at $DIR/nrvo_simple.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/nrvo_simple.rs:+4:2: +4:2
}
}
diff --git a/src/test/mir-opt/nrvo-simple.rs b/src/test/mir-opt/nrvo_simple.rs
index 5786ae621..5786ae621 100644
--- a/src/test/mir-opt/nrvo-simple.rs
+++ b/src/test/mir-opt/nrvo_simple.rs
diff --git a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
index f9ed1036f..e52253486 100644
--- a/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir
@@ -1,60 +1,60 @@
// MIR for `main` after SimplifyCfg-elaborate-drops
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +0:11
- let mut _1: Packed; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
- let mut _2: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
- let mut _3: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
- let mut _4: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
- let mut _5: Droppy; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
- let mut _6: Aligned; // in scope 0 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ let mut _0: (); // return place in scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:11: +0:11
+ let mut _1: Packed; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:9: +1:14
+ let mut _2: Aligned; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42
+ let mut _3: Droppy; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41
+ let mut _4: Aligned; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29
+ let mut _5: Droppy; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28
+ let mut _6: Aligned; // in scope 0 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8
scope 1 {
- debug x => _1; // in scope 1 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
+ debug x => _1; // in scope 1 at $DIR/packed_struct_drop_aligned.rs:+1:9: +1:14
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:9: +1:14
- StorageLive(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
- StorageLive(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
- Deinit(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
- (_3.0: usize) = const 0_usize; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:32: +1:41
- Deinit(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
- (_2.0: Droppy) = move _3; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:24: +1:42
- StorageDead(_3); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:41: +1:42
- Deinit(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43
- (_1.0: Aligned) = move _2; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:17: +1:43
- StorageDead(_2); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+1:42: +1:43
- StorageLive(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
- StorageLive(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
- Deinit(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
- (_5.0: usize) = const 0_usize; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:19: +2:28
- Deinit(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
- (_4.0: Droppy) = move _5; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:11: +2:29
- StorageDead(_5); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29
- StorageLive(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- drop(_6) -> [return: bb4, unwind: bb3]; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
+ StorageLive(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:9: +1:14
+ StorageLive(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42
+ StorageLive(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41
+ Deinit(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41
+ (_3.0: usize) = const 0_usize; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:32: +1:41
+ Deinit(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42
+ (_2.0: Droppy) = move _3; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:24: +1:42
+ StorageDead(_3); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:41: +1:42
+ Deinit(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:17: +1:43
+ (_1.0: Aligned) = move _2; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:17: +1:43
+ StorageDead(_2); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+1:42: +1:43
+ StorageLive(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29
+ StorageLive(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28
+ Deinit(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28
+ (_5.0: usize) = const 0_usize; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:19: +2:28
+ Deinit(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29
+ (_4.0: Droppy) = move _5; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:11: +2:29
+ StorageDead(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:28: +2:29
+ StorageLive(_6); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8
+ _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8
+ drop(_6) -> [return: bb4, unwind: bb3]; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8
}
bb1: {
- StorageDead(_1); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
- return; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:2: +3:2
+ StorageDead(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:2: +3:2
}
bb2 (cleanup): {
- resume; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:1: +3:2
+ resume; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:1: +3:2
}
bb3 (cleanup): {
- (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- drop(_1) -> bb2; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
+ (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8
+ drop(_1) -> bb2; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2
}
bb4: {
- StorageDead(_6); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:5: +2:8
- StorageDead(_4); // scope 1 at $DIR/packed-struct-drop-aligned.rs:+2:28: +2:29
- _0 = const (); // scope 0 at $DIR/packed-struct-drop-aligned.rs:+0:11: +3:2
- drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/packed-struct-drop-aligned.rs:+3:1: +3:2
+ StorageDead(_6); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8
+ (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8
+ StorageDead(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:28: +2:29
+ _0 = const (); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:11: +3:2
+ drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2
}
}
diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed_struct_drop_aligned.rs
index cb6524260..cb6524260 100644
--- a/src/test/mir-opt/packed-struct-drop-aligned.rs
+++ b/src/test/mir-opt/packed_struct_drop_aligned.rs
diff --git a/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir b/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir
index 76bdd23be..8eb0e9c8f 100644
--- a/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir
+++ b/src/test/mir-opt/remove_never_const.no_codegen.PreCodegen.after.mir
@@ -1,11 +1,11 @@
// MIR for `no_codegen` after PreCodegen
fn no_codegen() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/remove-never-const.rs:+0:20: +0:20
+ let mut _0: (); // return place in scope 0 at $DIR/remove_never_const.rs:+0:20: +0:20
scope 1 {
}
bb0: {
- unreachable; // scope 0 at $DIR/remove-never-const.rs:+1:13: +1:33
+ unreachable; // scope 0 at $DIR/remove_never_const.rs:+1:13: +1:33
}
}
diff --git a/src/test/mir-opt/remove-never-const.rs b/src/test/mir-opt/remove_never_const.rs
index 16095cfdd..16095cfdd 100644
--- a/src/test/mir-opt/remove-never-const.rs
+++ b/src/test/mir-opt/remove_never_const.rs
diff --git a/src/test/mir-opt/remove_zsts.get_union.PreCodegen.after.mir b/src/test/mir-opt/remove_zsts.get_union.PreCodegen.after.mir
new file mode 100644
index 000000000..12e914e25
--- /dev/null
+++ b/src/test/mir-opt/remove_zsts.get_union.PreCodegen.after.mir
@@ -0,0 +1,10 @@
+// MIR for `get_union` after PreCodegen
+
+fn get_union() -> Foo {
+ let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts.rs:+0:19: +0:22
+
+ bb0: {
+ Deinit(_0); // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
+ return; // scope 0 at $DIR/remove_zsts.rs:+2:2: +2:2
+ }
+}
diff --git a/src/test/mir-opt/remove_zsts.get_union.RemoveZsts.diff b/src/test/mir-opt/remove_zsts.get_union.RemoveZsts.diff
new file mode 100644
index 000000000..169b7b105
--- /dev/null
+++ b/src/test/mir-opt/remove_zsts.get_union.RemoveZsts.diff
@@ -0,0 +1,19 @@
+- // MIR for `get_union` before RemoveZsts
++ // MIR for `get_union` after RemoveZsts
+
+ fn get_union() -> Foo {
+ let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts.rs:+0:19: +0:22
+ let mut _1: (); // in scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
+- Deinit(_1); // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
++ nop; // scope 0 at $DIR/remove_zsts.rs:+1:14: +1:16
+ Deinit(_0); // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
+- (_0.0: ()) = move _1; // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
++ nop; // scope 0 at $DIR/remove_zsts.rs:+1:5: +1:18
+ StorageDead(_1); // scope 0 at $DIR/remove_zsts.rs:+1:17: +1:18
+ return; // scope 0 at $DIR/remove_zsts.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/remove_zsts.rs b/src/test/mir-opt/remove_zsts.rs
new file mode 100644
index 000000000..1cf7ad6e3
--- /dev/null
+++ b/src/test/mir-opt/remove_zsts.rs
@@ -0,0 +1,14 @@
+union Foo {
+ x: (),
+ y: u64,
+}
+
+// EMIT_MIR remove_zsts.get_union.RemoveZsts.diff
+// EMIT_MIR remove_zsts.get_union.PreCodegen.after.mir
+fn get_union() -> Foo {
+ Foo { x: () }
+}
+
+fn main() {
+ get_union();
+}
diff --git a/src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir b/src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir
deleted file mode 100644
index 7d9e60462..000000000
--- a/src/test/mir-opt/remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir
+++ /dev/null
@@ -1,15 +0,0 @@
-// MIR for `get_union` after RemoveZsts
-
-fn get_union() -> Foo {
- let mut _0: Foo; // return place in scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+0:19: +0:22
- let mut _1: (); // in scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:14: +1:16
-
- bb0: {
- StorageLive(_1); // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:14: +1:16
- nop; // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:14: +1:16
- Deinit(_0); // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:5: +1:18
- (_0.0: ()) = move _1; // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:5: +1:18
- StorageDead(_1); // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+1:17: +1:18
- return; // scope 0 at $DIR/remove_zsts_dont_touch_unions.rs:+2:2: +2:2
- }
-}
diff --git a/src/test/mir-opt/remove_zsts_dont_touch_unions.rs b/src/test/mir-opt/remove_zsts_dont_touch_unions.rs
deleted file mode 100644
index 8b9de9b4d..000000000
--- a/src/test/mir-opt/remove_zsts_dont_touch_unions.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// unit-test: RemoveZsts
-
-// Ensure RemoveZsts doesn't remove ZST assignments to union fields,
-// which causes problems in Miri.
-
-union Foo {
- x: (),
- y: u64,
-}
-
-// EMIT_MIR remove_zsts_dont_touch_unions.get_union.RemoveZsts.after.mir
-fn get_union() -> Foo {
- Foo { x: () }
-}
-
-
-fn main() {
- get_union();
-}
diff --git a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
index fe57e32a7..7b69b3e07 100644
--- a/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
@@ -68,9 +68,7 @@ fn array_casts() -> () {
StorageLive(_3); // scope 1 at $DIR/retag.rs:+2:13: +2:19
StorageLive(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19
_4 = &mut _1; // scope 1 at $DIR/retag.rs:+2:13: +2:19
- Retag(_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19
_3 = &raw mut (*_4); // scope 1 at $DIR/retag.rs:+2:13: +2:19
- Retag([raw] _3); // scope 1 at $DIR/retag.rs:+2:13: +2:19
_2 = move _3 as *mut usize (Pointer(ArrayToPointer)); // scope 1 at $DIR/retag.rs:+2:13: +2:33
StorageDead(_3); // scope 1 at $DIR/retag.rs:+2:32: +2:33
StorageDead(_4); // scope 1 at $DIR/retag.rs:+2:33: +2:34
@@ -96,9 +94,7 @@ fn array_casts() -> () {
StorageLive(_10); // scope 4 at $DIR/retag.rs:+6:13: +6:15
StorageLive(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15
_11 = &_8; // scope 4 at $DIR/retag.rs:+6:13: +6:15
- Retag(_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15
_10 = &raw const (*_11); // scope 4 at $DIR/retag.rs:+6:13: +6:15
- Retag([raw] _10); // scope 4 at $DIR/retag.rs:+6:13: +6:15
_9 = move _10 as *const usize (Pointer(ArrayToPointer)); // scope 4 at $DIR/retag.rs:+6:13: +6:31
StorageDead(_10); // scope 4 at $DIR/retag.rs:+6:30: +6:31
StorageDead(_11); // scope 4 at $DIR/retag.rs:+6:31: +6:32
@@ -119,7 +115,6 @@ fn array_casts() -> () {
StorageDead(_17); // scope 6 at $DIR/retag.rs:+7:33: +7:34
_15 = (*_16); // scope 6 at $DIR/retag.rs:+7:25: +7:34
_14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_35 = const _; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// mir::Constant
@@ -127,7 +122,6 @@ fn array_casts() -> () {
// + literal: Const { ty: &usize, val: Unevaluated(array_casts, [], Some(promoted[0])) }
Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Deinit(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_13.0: &usize) = move _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_13.1: &usize) = move _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -164,15 +158,11 @@ fn array_casts() -> () {
StorageLive(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_31 = &(*_20); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Retag(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_30 = &(*_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Retag(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_33 = &(*_21); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Retag(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_32 = &(*_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Deinit(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
discriminant(_34) = 0; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
diff --git a/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
index cdc413c56..14f297e94 100644
--- a/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
+++ b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
@@ -6,7 +6,6 @@ fn std::ptr::drop_in_place(_1: *mut Test) -> () {
let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
bb0: {
- Retag([raw] _1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
_2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
_3 = <Test as Drop>::drop(move _2) -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
// mir::Constant
diff --git a/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
index 96fc7e649..9e5c119a2 100644
--- a/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
@@ -15,7 +15,6 @@ fn main::{closure#0}(_1: &[closure@main::{closure#0}], _2: &i32) -> &i32 {
_3 = _2; // scope 0 at $DIR/retag.rs:+1:18: +1:19
Retag(_3); // scope 0 at $DIR/retag.rs:+1:18: +1:19
_0 = &(*_2); // scope 1 at $DIR/retag.rs:+2:9: +2:10
- Retag(_0); // scope 1 at $DIR/retag.rs:+2:9: +2:10
StorageDead(_3); // scope 0 at $DIR/retag.rs:+3:5: +3:6
return; // scope 0 at $DIR/retag.rs:+3:6: +3:6
}
diff --git a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
index 81225b44e..b853e4505 100644
--- a/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
@@ -65,13 +65,10 @@ fn main() -> () {
Deinit(_5); // scope 1 at $DIR/retag.rs:+3:17: +3:24
(_5.0: i32) = const 0_i32; // scope 1 at $DIR/retag.rs:+3:17: +3:24
_4 = &_5; // scope 1 at $DIR/retag.rs:+3:17: +3:36
- Retag(_4); // scope 1 at $DIR/retag.rs:+3:17: +3:36
StorageLive(_6); // scope 1 at $DIR/retag.rs:+3:29: +3:35
StorageLive(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35
_7 = &mut _1; // scope 1 at $DIR/retag.rs:+3:29: +3:35
- Retag(_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35
_6 = &mut (*_7); // scope 1 at $DIR/retag.rs:+3:29: +3:35
- Retag([2phase] _6); // scope 1 at $DIR/retag.rs:+3:29: +3:35
_3 = Test::foo(move _4, move _6) -> [return: bb1, unwind: bb8]; // scope 1 at $DIR/retag.rs:+3:17: +3:36
// mir::Constant
// + span: $DIR/retag.rs:33:25: 33:28
@@ -93,7 +90,6 @@ fn main() -> () {
_9 = move _3; // scope 2 at $DIR/retag.rs:+4:19: +4:20
Retag(_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20
_8 = &mut (*_9); // scope 2 at $DIR/retag.rs:+4:19: +4:20
- Retag(_8); // scope 2 at $DIR/retag.rs:+4:19: +4:20
StorageDead(_9); // scope 2 at $DIR/retag.rs:+4:22: +4:23
StorageLive(_10); // scope 3 at $DIR/retag.rs:+5:13: +5:14
_10 = move _8; // scope 3 at $DIR/retag.rs:+5:17: +5:18
@@ -101,7 +97,6 @@ fn main() -> () {
StorageLive(_11); // scope 4 at $DIR/retag.rs:+7:13: +7:15
StorageLive(_12); // scope 4 at $DIR/retag.rs:+7:18: +7:29
_12 = &raw mut (*_10); // scope 4 at $DIR/retag.rs:+7:18: +7:19
- Retag([raw] _12); // scope 4 at $DIR/retag.rs:+7:18: +7:19
_11 = _12; // scope 4 at $DIR/retag.rs:+7:18: +7:29
StorageDead(_12); // scope 4 at $DIR/retag.rs:+7:29: +7:30
_2 = const (); // scope 1 at $DIR/retag.rs:+2:5: +8:6
@@ -122,9 +117,7 @@ fn main() -> () {
StorageLive(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18
StorageLive(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18
_18 = &_1; // scope 6 at $DIR/retag.rs:+15:16: +15:18
- Retag(_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18
_17 = &(*_18); // scope 6 at $DIR/retag.rs:+15:16: +15:18
- Retag(_17); // scope 6 at $DIR/retag.rs:+15:16: +15:18
_15 = move _16(move _17) -> bb3; // scope 6 at $DIR/retag.rs:+15:14: +15:19
}
@@ -139,7 +132,6 @@ fn main() -> () {
Deinit(_21); // scope 7 at $DIR/retag.rs:+18:5: +18:12
(_21.0: i32) = const 0_i32; // scope 7 at $DIR/retag.rs:+18:5: +18:12
_20 = &_21; // scope 7 at $DIR/retag.rs:+18:5: +18:24
- Retag(_20); // scope 7 at $DIR/retag.rs:+18:5: +18:24
StorageLive(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23
StorageLive(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
_28 = const _; // scope 7 at $DIR/retag.rs:+18:21: +18:23
@@ -148,9 +140,7 @@ fn main() -> () {
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
Retag(_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23
_23 = &(*_28); // scope 7 at $DIR/retag.rs:+18:21: +18:23
- Retag(_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
_22 = &(*_23); // scope 7 at $DIR/retag.rs:+18:21: +18:23
- Retag(_22); // scope 7 at $DIR/retag.rs:+18:21: +18:23
_19 = Test::foo_shr(move _20, move _22) -> [return: bb4, unwind: bb7]; // scope 7 at $DIR/retag.rs:+18:5: +18:24
// mir::Constant
// + span: $DIR/retag.rs:48:13: 48:20
@@ -171,7 +161,6 @@ fn main() -> () {
StorageLive(_25); // scope 7 at $DIR/retag.rs:+21:9: +21:11
StorageLive(_26); // scope 7 at $DIR/retag.rs:+21:14: +21:28
_26 = &raw const (*_15); // scope 7 at $DIR/retag.rs:+21:14: +21:16
- Retag([raw] _26); // scope 7 at $DIR/retag.rs:+21:14: +21:16
_25 = _26; // scope 7 at $DIR/retag.rs:+21:14: +21:28
StorageDead(_26); // scope 7 at $DIR/retag.rs:+21:28: +21:29
StorageLive(_27); // scope 8 at $DIR/retag.rs:+23:5: +23:18
diff --git a/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
index 08fd655ae..4b50205fa 100644
--- a/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/retag.{impl#0}-foo.SimplifyCfg-elaborate-drops.after.mir
@@ -11,9 +11,7 @@ fn <impl at $DIR/retag.rs:12:1: 12:10>::foo(_1: &Test, _2: &mut i32) -> &mut i32
Retag([fn entry] _2); // scope 0 at $DIR/retag.rs:+0:23: +0:24
StorageLive(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
_3 = &mut (*_2); // scope 0 at $DIR/retag.rs:+1:9: +1:10
- Retag(_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
_0 = &mut (*_3); // scope 0 at $DIR/retag.rs:+1:9: +1:10
- Retag(_0); // scope 0 at $DIR/retag.rs:+1:9: +1:10
StorageDead(_3); // scope 0 at $DIR/retag.rs:+2:5: +2:6
return; // scope 0 at $DIR/retag.rs:+2:6: +2:6
}
diff --git a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff b/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff
deleted file mode 100644
index c3e503bf2..000000000
--- a/src/test/mir-opt/rustc.try_identity.DestinationPropagation.diff
+++ /dev/null
@@ -1,72 +0,0 @@
-- // MIR for `try_identity` before DestinationPropagation
-+ // MIR for `try_identity` after DestinationPropagation
-
- fn try_identity(_1: std::result::Result<u32, i32>) -> std::result::Result<u32, i32> {
- debug x => _1; // in scope 0 at $DIR/simplify_try.rs:6:17: 6:18
- let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:6:41: 6:57
- let _2: u32; // in scope 0 at $DIR/simplify_try.rs:7:9: 7:10
- let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15
- let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:14
- let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
- let _6: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
- let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
- let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
- let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:7:14: 7:15
- let _10: u32; // in scope 0 at $DIR/simplify_try.rs:7:13: 7:15
- let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:8:8: 8:9
- scope 1 {
- debug y => _2; // in scope 1 at $DIR/simplify_try.rs:7:9: 7:10
- }
- scope 2 {
- debug err => _6; // in scope 2 at $DIR/simplify_try.rs:7:14: 7:15
- scope 3 {
- scope 7 {
- debug t => _9; // in scope 7 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
- }
- scope 8 {
- debug v => _8; // in scope 8 at $SRC_DIR/libcore/result.rs:LL:COL
- let mut _12: i32; // in scope 8 at $DIR/simplify_try.rs:7:14: 7:15
- }
- }
- }
- scope 4 {
- debug val => _10; // in scope 4 at $DIR/simplify_try.rs:7:13: 7:15
- scope 5 {
- }
- }
- scope 6 {
-- debug self => _4; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
-+ debug self => _0; // in scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
- }
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:7:9: 7:10
-- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:7:13: 7:15
-- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
-- _4 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
-- _3 = move _4; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
-- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-+ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:15
-+ nop; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
-+ _0 = _1; // scope 0 at $DIR/simplify_try.rs:7:13: 7:14
-+ nop; // scope 6 at $SRC_DIR/libcore/result.rs:LL:COL
-+ nop; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
-+ _5 = discriminant(_0); // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
- goto -> bb1; // scope 0 at $DIR/simplify_try.rs:7:14: 7:15
- }
-
- bb1: {
-- _0 = move _3; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10
-- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:7:15: 7:16
-+ nop; // scope 1 at $DIR/simplify_try.rs:8:5: 8:10
-+ nop; // scope 0 at $DIR/simplify_try.rs:7:15: 7:16
- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:9:1: 9:2
- goto -> bb2; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2
- }
-
- bb2: {
- return; // scope 0 at $DIR/simplify_try.rs:9:2: 9:2
- }
- }
-
diff --git a/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
index f25b3ce72..b28c6f687 100644
--- a/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
+++ b/src/test/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
@@ -22,9 +22,6 @@
let mut _18: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
scope 9 {
debug e => _16; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
- debug t => _18; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- }
}
}
}
@@ -95,18 +92,11 @@
StorageLive(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
StorageLive(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
_18 = move _16; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- _17 = move _18; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- StorageDead(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- ((_0 as Err).0: i32) = move _17; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
- StorageDead(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
- StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
- StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
- return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
+- _17 = <i32 as From<i32>>::from(move _18) -> bb8; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
++ _17 = <i32 as From<i32>>::from(move _18) -> bb7; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/result.rs:LL:COL
+ // + literal: Const { ty: fn(i32) -> i32 {<i32 as From<i32>>::from}, val: Value(<ZST>) }
}
- bb5: {
@@ -152,5 +142,20 @@
+ _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+ switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
}
+
+- bb8: {
++ bb7: {
+ StorageDead(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ Deinit(_0); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ ((_0 as Err).0: i32) = move _17; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ discriminant(_0) = 1; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+ StorageDead(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+ StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
+ StorageDead(_3); // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
+ }
}
diff --git a/src/test/mir-opt/simplify-arm.rs b/src/test/mir-opt/simplify_arm.rs
index c247872e2..c247872e2 100644
--- a/src/test/mir-opt/simplify-arm.rs
+++ b/src/test/mir-opt/simplify_arm.rs
diff --git a/src/test/mir-opt/simplify-arm-identity.rs b/src/test/mir-opt/simplify_arm_identity.rs
index cf6ff57aa..cf6ff57aa 100644
--- a/src/test/mir-opt/simplify-arm-identity.rs
+++ b/src/test/mir-opt/simplify_arm_identity.rs
diff --git a/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff
index 5d7517e4e..1a5143aa0 100644
--- a/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff
@@ -2,32 +2,32 @@
+ // MIR for `c` after SimplifyLocals
fn c() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:8: +0:8
- let _1: [u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14
-- let mut _2: &[u8]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26
-- let mut _3: &[u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26
-- let _4: &[u8; 10]; // in scope 0 at $DIR/simplify-locals.rs:+3:20: +3:26
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:8: +0:8
+ let _1: [u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14
+- let mut _2: &[u8]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26
+- let mut _3: &[u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26
+- let _4: &[u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26
scope 1 {
- debug bytes => _1; // in scope 1 at $DIR/simplify-locals.rs:+1:9: +1:14
+ debug bytes => _1; // in scope 1 at $DIR/simplify_locals.rs:+1:9: +1:14
scope 2 {
}
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14
- _1 = [const 0_u8; 10]; // scope 0 at $DIR/simplify-locals.rs:+1:17: +1:26
-- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
-- StorageLive(_3); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
-- StorageLive(_4); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
-- _4 = &_1; // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
-- _3 = &(*_4); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
-- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 1 at $DIR/simplify-locals.rs:+3:20: +3:26
-- StorageDead(_3); // scope 1 at $DIR/simplify-locals.rs:+3:25: +3:26
-- StorageDead(_4); // scope 1 at $DIR/simplify-locals.rs:+3:26: +3:27
-- StorageDead(_2); // scope 1 at $DIR/simplify-locals.rs:+3:26: +3:27
- _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:8: +4:2
- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+4:1: +4:2
- return; // scope 0 at $DIR/simplify-locals.rs:+4:2: +4:2
+ StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14
+ _1 = [const 0_u8; 10]; // scope 0 at $DIR/simplify_locals.rs:+1:17: +1:26
+- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26
+- StorageLive(_3); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26
+- StorageLive(_4); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26
+- _4 = &_1; // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26
+- _3 = &(*_4); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26
+- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26
+- StorageDead(_3); // scope 1 at $DIR/simplify_locals.rs:+3:25: +3:26
+- StorageDead(_4); // scope 1 at $DIR/simplify_locals.rs:+3:26: +3:27
+- StorageDead(_2); // scope 1 at $DIR/simplify_locals.rs:+3:26: +3:27
+ _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:8: +4:2
+ StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/simplify_locals.rs:+4:2: +4:2
}
}
diff --git a/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff
index a9ea8869a..6426bf926 100644
--- a/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff
@@ -2,18 +2,18 @@
+ // MIR for `d1` after SimplifyLocals
fn d1() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9
-- let mut _1: E; // in scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9
+- let mut _1: E; // in scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17
scope 1 {
}
bb0: {
-- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17
-- Deinit(_1); // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17
-- discriminant(_1) = 0; // scope 0 at $DIR/simplify-locals.rs:+2:13: +2:17
-- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18
- _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2
- return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17
+- Deinit(_1); // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17
+- discriminant(_1) = 0; // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17
+- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18
+ _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2
+ return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff
index 6a89e4584..db5ab182d 100644
--- a/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff
@@ -2,28 +2,28 @@
+ // MIR for `d2` after SimplifyLocals
fn d2() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9
-- let mut _1: E; // in scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26
-- let mut _2: (i32, E); // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17
-- let mut _3: E; // in scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9
+- let mut _1: E; // in scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26
+- let mut _2: (i32, E); // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17
+- let mut _3: E; // in scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15
bb0: {
-- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26
-- Deinit(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26
-- discriminant(_1) = 1; // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:26
-- StorageLive(_2); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17
-- StorageLive(_3); // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15
-- Deinit(_3); // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15
-- discriminant(_3) = 0; // scope 0 at $DIR/simplify-locals.rs:+2:11: +2:15
-- Deinit(_2); // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16
-- (_2.0: i32) = const 10_i32; // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16
-- (_2.1: E) = move _3; // scope 0 at $DIR/simplify-locals.rs:+2:6: +2:16
-- StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:15: +2:16
-- (_2.1: E) = move _1; // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:26
-- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:25: +2:26
-- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:26: +2:27
- _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2
- return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26
+- Deinit(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26
+- discriminant(_1) = 1; // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26
+- StorageLive(_2); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17
+- StorageLive(_3); // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15
+- Deinit(_3); // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15
+- discriminant(_3) = 0; // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15
+- Deinit(_2); // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16
+- (_2.0: i32) = const 10_i32; // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16
+- (_2.1: E) = move _3; // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16
+- StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:15: +2:16
+- (_2.1: E) = move _1; // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:26
+- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:25: +2:26
+- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:26: +2:27
+ _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2
+ return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff
index 204a1bffc..c707b0da0 100644
--- a/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff
@@ -2,20 +2,20 @@
+ // MIR for `expose_addr` after SimplifyLocals
fn expose_addr(_1: *const usize) -> () {
- debug p => _1; // in scope 0 at $DIR/simplify-locals.rs:+0:16: +0:17
- let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:33: +0:33
- let _2: usize; // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15
- let mut _3: *const usize; // in scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6
+ debug p => _1; // in scope 0 at $DIR/simplify_locals.rs:+0:16: +0:17
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:33: +0:33
+ let _2: usize; // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15
+ let mut _3: *const usize; // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6
bb0: {
- StorageLive(_2); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15
- StorageLive(_3); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6
- _3 = _1; // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:6
- _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:15
- StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15
- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:15: +2:16
- _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:33: +3:2
- return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+ StorageLive(_2); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15
+ StorageLive(_3); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6
+ _3 = _1; // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6
+ _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15
+ StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15
+ StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:15: +2:16
+ _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:33: +3:2
+ return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff
index 329e2a65a..ff6eb2cff 100644
--- a/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff
@@ -2,12 +2,12 @@
+ // MIR for `r` after SimplifyLocals
fn r() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:8: +0:8
- let mut _1: i32; // in scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14
-- let mut _2: &i32; // in scope 0 at $DIR/simplify-locals.rs:+3:13: +3:15
-- let mut _3: &mut i32; // in scope 0 at $DIR/simplify-locals.rs:+4:13: +4:19
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:8: +0:8
+ let mut _1: i32; // in scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14
+- let mut _2: &i32; // in scope 0 at $DIR/simplify_locals.rs:+3:13: +3:15
+- let mut _3: &mut i32; // in scope 0 at $DIR/simplify_locals.rs:+4:13: +4:19
scope 1 {
- debug a => _1; // in scope 1 at $DIR/simplify-locals.rs:+1:9: +1:14
+ debug a => _1; // in scope 1 at $DIR/simplify_locals.rs:+1:9: +1:14
scope 2 {
scope 3 {
}
@@ -15,17 +15,17 @@
}
bb0: {
- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+1:9: +1:14
- _1 = const 1_i32; // scope 0 at $DIR/simplify-locals.rs:+1:17: +1:18
-- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+3:13: +3:15
-- _2 = &_1; // scope 1 at $DIR/simplify-locals.rs:+3:13: +3:15
-- StorageDead(_2); // scope 1 at $DIR/simplify-locals.rs:+3:15: +3:16
-- StorageLive(_3); // scope 2 at $DIR/simplify-locals.rs:+4:13: +4:19
-- _3 = &mut _1; // scope 2 at $DIR/simplify-locals.rs:+4:13: +4:19
-- StorageDead(_3); // scope 2 at $DIR/simplify-locals.rs:+4:19: +4:20
- _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:8: +5:2
- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+5:1: +5:2
- return; // scope 0 at $DIR/simplify-locals.rs:+5:2: +5:2
+ StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14
+ _1 = const 1_i32; // scope 0 at $DIR/simplify_locals.rs:+1:17: +1:18
+- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+3:13: +3:15
+- _2 = &_1; // scope 1 at $DIR/simplify_locals.rs:+3:13: +3:15
+- StorageDead(_2); // scope 1 at $DIR/simplify_locals.rs:+3:15: +3:16
+- StorageLive(_3); // scope 2 at $DIR/simplify_locals.rs:+4:13: +4:19
+- _3 = &mut _1; // scope 2 at $DIR/simplify_locals.rs:+4:13: +4:19
+- StorageDead(_3); // scope 2 at $DIR/simplify_locals.rs:+4:19: +4:20
+ _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:8: +5:2
+ StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/simplify_locals.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/simplify-locals.rs b/src/test/mir-opt/simplify_locals.rs
index 89d9391f8..89d9391f8 100644
--- a/src/test/mir-opt/simplify-locals.rs
+++ b/src/test/mir-opt/simplify_locals.rs
diff --git a/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff
index b31156ad6..49db77479 100644
--- a/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff
@@ -2,21 +2,21 @@
+ // MIR for `t1` after SimplifyLocals
fn t1() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9
-- let _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15
-- let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9
+- let _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15
+- let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15
scope 1 {
}
bb0: {
-- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:17
-- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
-- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
-- _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
-- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18
-- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:17: +2:18
- _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2
- return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17
+- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15
+- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15
+- _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15
+- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18
+- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18
+ _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2
+ return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff
index 66b6d8d64..e3f4ae370 100644
--- a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff
@@ -2,21 +2,21 @@
+ // MIR for `t2` after SimplifyLocals
fn t2() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9
-- let _1: &mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:20
-- let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:19: +2:20
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9
+- let _1: &mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:20
+- let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:19: +2:20
scope 1 {
}
bb0: {
-- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:22
-- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:19: +2:20
-- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:19: +2:20
-- _1 = &mut (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:20
-- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:23
-- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:22: +2:23
- _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2
- return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:22
+- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:19: +2:20
+- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:19: +2:20
+- _1 = &mut (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:20
+- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:23
+- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:23
+ _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2
+ return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff
index f6b6b78cd..f1ce7778e 100644
--- a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff
@@ -2,25 +2,25 @@
+ // MIR for `t3` after SimplifyLocals
fn t3() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:+0:9: +0:9
-- let _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:21
-- let mut _2: &mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:15: +2:21
-- let mut _3: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:20: +2:21
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9
+- let _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:21
+- let mut _2: &mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:15: +2:21
+- let mut _3: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:20: +2:21
scope 1 {
}
bb0: {
-- StorageLive(_1); // scope 0 at $DIR/simplify-locals.rs:+2:5: +2:23
-- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:15: +2:21
-- StorageLive(_3); // scope 1 at $DIR/simplify-locals.rs:+2:20: +2:21
-- _3 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:20: +2:21
-- _2 = &mut (*_3); // scope 1 at $DIR/simplify-locals.rs:+2:15: +2:21
-- _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:21
-- StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24
-- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24
-- StorageDead(_1); // scope 0 at $DIR/simplify-locals.rs:+2:23: +2:24
- _0 = const (); // scope 0 at $DIR/simplify-locals.rs:+0:9: +3:2
- return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:23
+- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:15: +2:21
+- StorageLive(_3); // scope 1 at $DIR/simplify_locals.rs:+2:20: +2:21
+- _3 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:20: +2:21
+- _2 = &mut (*_3); // scope 1 at $DIR/simplify_locals.rs:+2:15: +2:21
+- _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:21
+- StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24
+- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24
+- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24
+ _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2
+ return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff
index 1c1da29aa..71cf9594b 100644
--- a/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff
@@ -2,21 +2,21 @@
+ // MIR for `t4` after SimplifyLocals
fn t4() -> u32 {
- let mut _0: u32; // return place in scope 0 at $DIR/simplify-locals.rs:+0:12: +0:15
- let mut _1: u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15
- let mut _2: *mut u32; // in scope 0 at $DIR/simplify-locals.rs:+2:14: +2:15
+ let mut _0: u32; // return place in scope 0 at $DIR/simplify_locals.rs:+0:12: +0:15
+ let mut _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15
+ let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15
scope 1 {
}
bb0: {
- StorageLive(_1); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
- StorageLive(_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
- _1 = (*_2); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:15
- _0 = Add(move _1, const 1_u32); // scope 1 at $DIR/simplify-locals.rs:+2:14: +2:19
- StorageDead(_1); // scope 1 at $DIR/simplify-locals.rs:+2:18: +2:19
- StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:+3:1: +3:2
- return; // scope 0 at $DIR/simplify-locals.rs:+3:2: +3:2
+ StorageLive(_1); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15
+ StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15
+ _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15
+ _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15
+ _0 = Add(move _1, const 1_u32); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:19
+ StorageDead(_1); // scope 1 at $DIR/simplify_locals.rs:+2:18: +2:19
+ StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+3:1: +3:2
+ return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2
}
}
diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff
index ac7a47ba5..8feddcef2 100644
--- a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff
@@ -2,61 +2,61 @@
+ // MIR for `foo` after SimplifyLocals
fn foo() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+0:13: +0:13
- let mut _1: (std::option::Option<u8>, std::option::Option<T>); // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69
- let mut _2: std::option::Option<u8>; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49
- let mut _3: std::option::Option<T>; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68
- let mut _4: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:22: +1:26
- let mut _5: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:13: +1:20
-- let mut _7: bool; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20
-- let mut _8: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+0:13: +0:13
+ let mut _1: (std::option::Option<u8>, std::option::Option<T>); // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69
+ let mut _2: std::option::Option<u8>; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49
+ let mut _3: std::option::Option<T>; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68
+ let mut _4: isize; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:22: +1:26
+ let mut _5: isize; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:13: +1:20
+- let mut _7: bool; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20
+- let mut _8: u8; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13
scope 1 {
- debug a => _6; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19
- let _6: u8; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19
+ debug a => _6; // in scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19
+ let _6: u8; // in scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19
}
bb0: {
- StorageLive(_1); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69
- StorageLive(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49
- Deinit(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49
- discriminant(_2) = 0; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:31: +1:49
- StorageLive(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68
- Deinit(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68
- discriminant(_3) = 0; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:51: +1:68
- Deinit(_1); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69
- (_1.0: std::option::Option<u8>) = move _2; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69
- (_1.1: std::option::Option<T>) = move _3; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:30: +1:69
- StorageDead(_3); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:68: +1:69
- StorageDead(_2); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:68: +1:69
- _5 = discriminant((_1.0: std::option::Option<u8>)); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27
- switchInt(move _5) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27
+ StorageLive(_1); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69
+ StorageLive(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49
+ Deinit(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49
+ discriminant(_2) = 0; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49
+ StorageLive(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68
+ Deinit(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68
+ discriminant(_3) = 0; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68
+ Deinit(_1); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69
+ (_1.0: std::option::Option<u8>) = move _2; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69
+ (_1.1: std::option::Option<T>) = move _3; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69
+ StorageDead(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69
+ StorageDead(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69
+ _5 = discriminant((_1.0: std::option::Option<u8>)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27
+ switchInt(move _5) -> [1_isize: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27
}
bb1: {
- _4 = discriminant((_1.1: std::option::Option<T>)); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27
- switchInt(move _4) -> [0_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:12: +1:27
+ _4 = discriminant((_1.1: std::option::Option<T>)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27
+ switchInt(move _4) -> [0_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27
}
bb2: {
- StorageLive(_6); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19
- _6 = (((_1.0: std::option::Option<u8>) as Some).0: u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+1:18: +1:19
-- StorageLive(_7); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20
-- StorageLive(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13
-- _8 = _6; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:13
-- _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:12: +2:20
-- StorageDead(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+2:19: +2:20
-- StorageDead(_7); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:+4:9: +4:10
- StorageDead(_6); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+5:5: +5:6
- goto -> bb3; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+1:5: +5:6
+ StorageLive(_6); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19
+ _6 = (((_1.0: std::option::Option<u8>) as Some).0: u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19
+- StorageLive(_7); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20
+- StorageLive(_8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13
+- _8 = _6; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13
+- _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20
+- StorageDead(_8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:19: +2:20
+- StorageDead(_7); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+4:9: +4:10
+ StorageDead(_6); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+5:5: +5:6
+ goto -> bb3; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:5: +5:6
}
bb3: {
- drop(_1) -> bb4; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:1: +6:2
+ drop(_1) -> bb4; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:1: +6:2
}
bb4: {
- StorageDead(_1); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:1: +6:2
- return; // scope 0 at $DIR/simplify-locals-fixedpoint.rs:+6:2: +6:2
+ StorageDead(_1); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:2: +6:2
}
}
diff --git a/src/test/mir-opt/simplify-locals-fixedpoint.rs b/src/test/mir-opt/simplify_locals_fixedpoint.rs
index 78b1f9f55..78b1f9f55 100644
--- a/src/test/mir-opt/simplify-locals-fixedpoint.rs
+++ b/src/test/mir-opt/simplify_locals_fixedpoint.rs
diff --git a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
index b41527ba0..78272272b 100644
--- a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff
@@ -2,108 +2,108 @@
+ // MIR for `main` after SimplifyLocals
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+0:11: +0:11
-- let mut _1: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
-- let mut _2: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23
-- let mut _3: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27
-- let _4: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
-- let mut _5: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-- let mut _6: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
-- let mut _7: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
-- let _8: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
-- let mut _9: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
-- let mut _10: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
-- let mut _11: Temp; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
-+ let _1: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
-+ let mut _2: ((), ()); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-+ let mut _3: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
-+ let mut _4: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
-+ let _5: (); // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
-+ let mut _6: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
-+ let mut _7: u8; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
-+ let mut _8: Temp; // in scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
+ let mut _0: (); // return place in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +0:11
+- let mut _1: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28
+- let mut _2: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23
+- let mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27
+- let _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22
+- let mut _5: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
+- let mut _6: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
+- let mut _7: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
+- let _8: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35
+- let mut _9: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34
+- let mut _10: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30
+- let mut _11: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
++ let _1: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22
++ let mut _2: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
++ let mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
++ let mut _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
++ let _5: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35
++ let mut _6: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34
++ let mut _7: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30
++ let mut _8: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
scope 1 {
}
bb0: {
-- StorageLive(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
-- StorageLive(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23
-- Deinit(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:21: +1:23
-- StorageLive(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27
-- Deinit(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:25: +1:27
-- Deinit(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
-- (_1.0: ()) = move _2; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
-- (_1.1: ()) = move _3; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:20: +1:28
-- StorageDead(_3); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:27: +1:28
-- StorageDead(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:27: +1:28
-- StorageDead(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+1:28: +1:29
-- StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
-- StorageLive(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-- StorageLive(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
-- Deinit(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
-- StorageLive(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
-- Deinit(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
-- Deinit(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-- (_5.0: ()) = move _6; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-- (_5.1: ()) = move _7; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-- StorageDead(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21
-- StorageDead(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21
-- _4 = use_zst(move _5) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
-+ StorageLive(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
-+ StorageLive(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-+ StorageLive(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
-+ Deinit(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:14: +2:16
-+ StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
-+ Deinit(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:18: +2:20
-+ Deinit(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-+ (_2.0: ()) = move _3; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-+ (_2.1: ()) = move _4; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:13: +2:21
-+ StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21
-+ StorageDead(_3); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:20: +2:21
-+ _1 = use_zst(move _2) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:5: +2:22
+- StorageLive(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28
+- StorageLive(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23
+- Deinit(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23
+- StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27
+- Deinit(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27
+- Deinit(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28
+- (_1.0: ()) = move _2; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28
+- (_1.1: ()) = move _3; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28
+- StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28
+- StorageDead(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28
+- StorageDead(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:28: +1:29
+- StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22
+- StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
+- StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
+- Deinit(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
+- StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
+- Deinit(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
+- Deinit(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
+- (_5.0: ()) = move _6; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
+- (_5.1: ()) = move _7; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
+- StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21
+- StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21
+- _4 = use_zst(move _5) -> bb1; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22
++ StorageLive(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22
++ StorageLive(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
++ StorageLive(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
++ Deinit(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16
++ StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
++ Deinit(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20
++ Deinit(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
++ (_2.0: ()) = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
++ (_2.1: ()) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21
++ StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21
++ StorageDead(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21
++ _1 = use_zst(move _2) -> bb1; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22
// mir::Constant
- // + span: $DIR/simplify-locals-removes-unused-consts.rs:15:5: 15:12
+ // + span: $DIR/simplify_locals_removes_unused_consts.rs:15:5: 15:12
// + literal: Const { ty: fn(((), ())) {use_zst}, val: Value(<ZST>) }
}
bb1: {
-- StorageDead(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:21: +2:22
-- StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:22: +2:23
-- StorageLive(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
-- StorageLive(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
-- StorageLive(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
-- StorageLive(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
-- Deinit(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
-- (_11.0: u8) = const 40_u8; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
-- _10 = (_11.0: u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
-- _9 = Add(move _10, const 2_u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
-- StorageDead(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:33: +4:34
-- _8 = use_u8(move _9) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
-+ StorageDead(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:21: +2:22
-+ StorageDead(_1); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+2:22: +2:23
-+ StorageLive(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
-+ StorageLive(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
-+ StorageLive(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
-+ StorageLive(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
-+ Deinit(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
-+ (_8.0: u8) = const 40_u8; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:28
-+ _7 = (_8.0: u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:30
-+ _6 = Add(move _7, const 2_u8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:12: +4:34
-+ StorageDead(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:33: +4:34
-+ _5 = use_u8(move _6) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:5: +4:35
+- StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22
+- StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23
+- StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35
+- StorageLive(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34
+- StorageLive(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30
+- StorageLive(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
+- Deinit(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
+- (_11.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
+- _10 = (_11.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30
+- _9 = Add(move _10, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34
+- StorageDead(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34
+- _8 = use_u8(move _9) -> bb2; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35
++ StorageDead(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22
++ StorageDead(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23
++ StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35
++ StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34
++ StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30
++ StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
++ Deinit(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
++ (_8.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28
++ _7 = (_8.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30
++ _6 = Add(move _7, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34
++ StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34
++ _5 = use_u8(move _6) -> bb2; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35
// mir::Constant
- // + span: $DIR/simplify-locals-removes-unused-consts.rs:17:5: 17:11
+ // + span: $DIR/simplify_locals_removes_unused_consts.rs:17:5: 17:11
// + literal: Const { ty: fn(u8) {use_u8}, val: Value(<ZST>) }
}
bb2: {
-- StorageDead(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:34: +4:35
-- StorageDead(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
-+ StorageDead(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:34: +4:35
- StorageDead(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
-+ StorageDead(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:+4:35: +4:36
- _0 = const (); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+0:11: +5:2
- return; // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:+5:2: +5:2
+- StorageDead(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35
+- StorageDead(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36
++ StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35
+ StorageDead(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36
++ StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36
+ _0 = const (); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +5:2
+ return; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts.rs b/src/test/mir-opt/simplify_locals_removes_unused_consts.rs
index 39b7911d4..39b7911d4 100644
--- a/src/test/mir-opt/simplify-locals-removes-unused-consts.rs
+++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.rs
diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff
index 51d26b08b..6e7294003 100644
--- a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff
@@ -2,51 +2,51 @@
+ // MIR for `map` after SimplifyLocals
fn map(_1: Option<Box<()>>) -> Option<Box<()>> {
- debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9
- let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46
- let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13
- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
-- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
-- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
-- let mut _7: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
+ debug x => _1; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+0:8: +0:9
+ let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+0:31: +0:46
+ let mut _2: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:9: +2:13
+ let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15
+ let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26
+- let mut _5: bool; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2
+- let mut _6: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2
+- let mut _7: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2
scope 1 {
- debug x => _3; // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
+ debug x => _3; // in scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15
}
bb0: {
-- _5 = const false; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
-- _5 = const true; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
- _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
- switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12
+- _5 = const false; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12
+- _5 = const true; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12
+ _2 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12
+ switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:5: +1:12
}
bb1: {
- StorageLive(_3); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
- _3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
- StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
- _4 = move _3; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
- Deinit(_0); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
- ((_0 as Some).0: std::boxed::Box<()>) = move _4; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
- discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
- StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
- StorageDead(_3); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
- goto -> bb4; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
+ StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15
+ _3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15
+ StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26
+ _4 = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26
+ Deinit(_0); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27
+ ((_0 as Some).0: std::boxed::Box<()>) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27
+ discriminant(_0) = 1; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27
+ StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27
+ StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27
+ goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27
}
bb2: {
- unreachable; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
+ unreachable; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12
}
bb3: {
- Deinit(_0); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
- discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
- goto -> bb4; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:17: +2:21
+ Deinit(_0); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21
+ discriminant(_0) = 0; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21
+ goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21
}
bb4: {
-- _6 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
- return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:2: +5:2
+- _6 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2
+ return; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs
index d09bd92c4..d09bd92c4 100644
--- a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
+++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs
diff --git a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff b/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
deleted file mode 100644
index 83b91309b..000000000
--- a/src/test/mir-opt/simplify_try.try_identity.DestinationPropagation.diff
+++ /dev/null
@@ -1,106 +0,0 @@
-- // MIR for `try_identity` before DestinationPropagation
-+ // MIR for `try_identity` after DestinationPropagation
-
- fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
- debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
- let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
- let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
- let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
- let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
- let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
- let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
- let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
- let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
- scope 1 {
-- debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
-+ debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
- }
- scope 2 {
- debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
- scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
- debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- }
- scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
- debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
- }
- }
- scope 3 {
-- debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
-+ debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
- }
- scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
-- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
-+ debug r => _3; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
- }
-
- bb0: {
-- StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-- _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
-- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
-+ nop; // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
-+ nop; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
-+ nop; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-+ _3 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
-+ nop; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
-+ nop; // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
- }
-
- bb1: {
-- StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-- _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-- _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
-- StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
-- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-- StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-- _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-+ nop; // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-+ ((_0 as Ok).0: u32) = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
-+ nop; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
-+ nop; // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
-+ nop; // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-+ nop; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
-+ nop; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
- Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-- ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-+ nop; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
- discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
-- StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
-- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-+ nop; // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
-+ nop; // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
- return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
- }
-
- bb2: {
- unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- }
-
- bb3: {
- StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- nop; // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
- StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
- nop; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
- nop; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
- nop; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
- Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
- discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
- StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
- StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
-- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
-+ nop; // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
-+ nop; // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
- return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
- }
- }
-
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
deleted file mode 100644
index e025ae7c5..000000000
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyArmIdentity.diff
+++ /dev/null
@@ -1,85 +0,0 @@
-- // MIR for `try_identity` before SimplifyArmIdentity
-+ // MIR for `try_identity` after SimplifyArmIdentity
-
- fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
- debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
- let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
- let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
- let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
- let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
- let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
- let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
- let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
- let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
- scope 1 {
- debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
- }
- scope 2 {
- debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
- scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
- debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- }
- scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
- debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
- }
- }
- scope 3 {
- debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
- }
- scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
- }
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
- }
-
- bb1: {
- StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
- _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
- _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
- StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
- StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
- _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
- Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
- ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
- discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
- StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
- return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
- }
-
- bb2: {
- unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- }
-
- bb3: {
- StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
- StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
- _9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
- _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
- ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
- Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
- discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
- StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
- StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
- return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
- }
- }
-
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
deleted file mode 100644
index eb5af2227..000000000
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyBranchSame.after.mir
+++ /dev/null
@@ -1,83 +0,0 @@
-// MIR for `try_identity` after SimplifyBranchSame
-
-fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
- debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
- let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
- let _2: u32; // in scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
- let mut _3: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- let mut _4: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- let mut _5: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
- let _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- let mut _7: !; // in scope 0 at $DIR/simplify_try.rs:+2:19: +2:51
- let mut _8: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
- let mut _9: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
- let _10: u32; // in scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
- let mut _11: u32; // in scope 0 at $DIR/simplify_try.rs:+5:8: +5:9
- scope 1 {
- debug y => _2; // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
- }
- scope 2 {
- debug e => _6; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
- scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
- debug t => _9; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- }
- scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
- debug e => _8; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
- }
- }
- scope 3 {
- debug v => _10; // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
- }
- scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
- debug r => _4; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
- }
-
- bb0: {
- StorageLive(_2); // scope 0 at $DIR/simplify_try.rs:+1:9: +1:10
- StorageLive(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- _4 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- _3 = move _4; // scope 4 at $DIR/simplify_try.rs:9:5: 9:6
- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+1:32: +1:33
- _5 = discriminant(_3); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- switchInt(move _5) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
- }
-
- bb1: {
- StorageLive(_10); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
- _10 = ((_3 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
- _2 = _10; // scope 3 at $DIR/simplify_try.rs:+3:18: +3:19
- StorageDead(_10); // scope 0 at $DIR/simplify_try.rs:+3:18: +3:19
- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
- StorageLive(_11); // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
- _11 = _2; // scope 1 at $DIR/simplify_try.rs:+5:8: +5:9
- Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
- ((_0 as Ok).0: u32) = move _11; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
- discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
- StorageDead(_11); // scope 1 at $DIR/simplify_try.rs:+5:9: +5:10
- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
- return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
- }
-
- bb2: {
- unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- }
-
- bb3: {
- StorageLive(_6); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- _6 = ((_3 as Err).0: i32); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- StorageLive(_8); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
- StorageLive(_9); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
- _9 = _6; // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
- _8 = move _9; // scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- StorageDead(_9); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
- ((_0 as Err).0: i32) = move _8; // scope 6 at $DIR/simplify_try.rs:13:9: 13:10
- Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
- discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
- StorageDead(_8); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
- StorageDead(_6); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
- StorageDead(_3); // scope 0 at $DIR/simplify_try.rs:+4:6: +4:7
- StorageDead(_2); // scope 0 at $DIR/simplify_try.rs:+6:1: +6:2
- return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
- }
-}
diff --git a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir b/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
deleted file mode 100644
index 1efa8a67e..000000000
--- a/src/test/mir-opt/simplify_try.try_identity.SimplifyLocals.after.mir
+++ /dev/null
@@ -1,58 +0,0 @@
-// MIR for `try_identity` after SimplifyLocals
-
-fn try_identity(_1: Result<u32, i32>) -> Result<u32, i32> {
- debug x => _1; // in scope 0 at $DIR/simplify_try.rs:+0:17: +0:18
- let mut _0: std::result::Result<u32, i32>; // return place in scope 0 at $DIR/simplify_try.rs:+0:41: +0:57
- let mut _2: std::result::Result<u32, i32>; // in scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- let mut _3: isize; // in scope 0 at $DIR/simplify_try.rs:+2:9: +2:15
- let _4: i32; // in scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- let mut _5: i32; // in scope 0 at $DIR/simplify_try.rs:+2:37: +2:50
- let mut _6: i32; // in scope 0 at $DIR/simplify_try.rs:+2:48: +2:49
- scope 1 {
- debug y => ((_0 as Ok).0: u32); // in scope 1 at $DIR/simplify_try.rs:+1:9: +1:10
- }
- scope 2 {
- debug e => _4; // in scope 2 at $DIR/simplify_try.rs:+2:13: +2:14
- scope 5 (inlined <i32 as From<i32>>::from) { // at $DIR/simplify_try.rs:22:37: 22:50
- debug t => _6; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
- }
- scope 6 (inlined from_error::<u32, i32>) { // at $DIR/simplify_try.rs:22:26: 22:51
- debug e => _5; // in scope 6 at $DIR/simplify_try.rs:12:21: 12:22
- }
- }
- scope 3 {
- debug v => ((_0 as Ok).0: u32); // in scope 3 at $DIR/simplify_try.rs:+3:12: +3:13
- }
- scope 4 (inlined into_result::<u32, i32>) { // at $DIR/simplify_try.rs:21:19: 21:33
- debug r => _2; // in scope 4 at $DIR/simplify_try.rs:8:22: 8:23
- }
-
- bb0: {
- _2 = _1; // scope 0 at $DIR/simplify_try.rs:+1:31: +1:32
- _3 = discriminant(_2); // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- switchInt(move _3) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify_try.rs:+1:13: +1:33
- }
-
- bb1: {
- ((_0 as Ok).0: u32) = ((_2 as Ok).0: u32); // scope 0 at $DIR/simplify_try.rs:+3:12: +3:13
- Deinit(_0); // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
- discriminant(_0) = 0; // scope 1 at $DIR/simplify_try.rs:+5:5: +5:10
- return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
- }
-
- bb2: {
- unreachable; // scope 0 at $DIR/simplify_try.rs:+1:19: +1:33
- }
-
- bb3: {
- StorageLive(_4); // scope 0 at $DIR/simplify_try.rs:+2:13: +2:14
- StorageLive(_5); // scope 2 at $DIR/simplify_try.rs:+2:37: +2:50
- StorageLive(_6); // scope 2 at $DIR/simplify_try.rs:+2:48: +2:49
- StorageDead(_6); // scope 2 at $DIR/simplify_try.rs:+2:49: +2:50
- Deinit(_0); // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
- discriminant(_0) = 1; // scope 6 at $DIR/simplify_try.rs:13:5: 13:11
- StorageDead(_5); // scope 2 at $DIR/simplify_try.rs:+2:50: +2:51
- StorageDead(_4); // scope 0 at $DIR/simplify_try.rs:+2:50: +2:51
- return; // scope 0 at $DIR/simplify_try.rs:+6:2: +6:2
- }
-}
diff --git a/src/test/mir-opt/slice-drop-shim.rs b/src/test/mir-opt/slice_drop_shim.rs
index 344c1af2c..344c1af2c 100644
--- a/src/test/mir-opt/slice-drop-shim.rs
+++ b/src/test/mir-opt/slice_drop_shim.rs
diff --git a/src/test/mir-opt/spanview_block.main.mir_map.0.html b/src/test/mir-opt/spanview_block.main.built.after.html
index 8e5268043..b962d80c5 100644
--- a/src/test/mir-opt/spanview_block.main.mir_map.0.html
+++ b/src/test/mir-opt/spanview_block.main.built.after.html
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
-<title>spanview_block.main.mir_map.0</title>
+<title>spanview_block.main.built.after</title>
<style>
.line {
counter-increment: line;
@@ -59,7 +59,7 @@
</style>
</head>
<body>
-<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="0: $DIR/spanview-block.rs:5:11: 5:13:
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="0: $DIR/spanview_block.rs:5:11: 5:13:
5:11-5:13: Assign: _0 = const ()
5:13-5:13: Return: return"><span class="annotation">0⦊</span>{}<span class="annotation">⦉0</span></span></span></span></div>
</body>
diff --git a/src/test/mir-opt/spanview-block.rs b/src/test/mir-opt/spanview_block.rs
index fc1d6e0ed..0ecf35ad6 100644
--- a/src/test/mir-opt/spanview-block.rs
+++ b/src/test/mir-opt/spanview_block.rs
@@ -1,5 +1,5 @@
// Test spanview block output
// compile-flags: -Z dump-mir-spanview=block
-// EMIT_MIR spanview_block.main.mir_map.0.html
+// EMIT_MIR spanview_block.main.built.after.html
fn main() {}
diff --git a/src/test/mir-opt/spanview_statement.main.mir_map.0.html b/src/test/mir-opt/spanview_statement.main.built.after.html
index abbff2270..43bff7d09 100644
--- a/src/test/mir-opt/spanview_statement.main.mir_map.0.html
+++ b/src/test/mir-opt/spanview_statement.main.built.after.html
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
-<title>spanview_statement.main.mir_map.0</title>
+<title>spanview_statement.main.built.after</title>
<style>
.line {
counter-increment: line;
@@ -59,8 +59,8 @@
</style>
</head>
<body>
-<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="0[0]: $DIR/spanview-statement.rs:5:11: 5:13:
- 5:11-5:13: Assign: _0 = const ()"><span class="annotation">0[0]⦊</span>{}<span class="annotation">⦉0[0]</span></span></span><span><span class="code odd" style="--layer: 1" title="0:Return: $DIR/spanview-statement.rs:5:13: 5:13:
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() </span><span><span class="code even" style="--layer: 1" title="0[0]: $DIR/spanview_statement.rs:5:11: 5:13:
+ 5:11-5:13: Assign: _0 = const ()"><span class="annotation">0[0]⦊</span>{}<span class="annotation">⦉0[0]</span></span></span><span><span class="code odd" style="--layer: 1" title="0:Return: $DIR/spanview_statement.rs:5:13: 5:13:
5:13-5:13: Return: return"><span class="annotation">0:Return⦊</span>‸<span class="annotation">⦉0:Return</span></span></span></span></div>
</body>
</html>
diff --git a/src/test/mir-opt/spanview-statement.rs b/src/test/mir-opt/spanview_statement.rs
index a43ad5e71..457052617 100644
--- a/src/test/mir-opt/spanview-statement.rs
+++ b/src/test/mir-opt/spanview_statement.rs
@@ -1,5 +1,5 @@
// Test spanview output (the default value for `-Z dump-mir-spanview` is "statement")
// compile-flags: -Z dump-mir-spanview
-// EMIT_MIR spanview_statement.main.mir_map.0.html
+// EMIT_MIR spanview_statement.main.built.after.html
fn main() {}
diff --git a/src/test/mir-opt/spanview_terminator.main.mir_map.0.html b/src/test/mir-opt/spanview_terminator.main.built.after.html
index 55fafd90b..aa7e44c15 100644
--- a/src/test/mir-opt/spanview_terminator.main.mir_map.0.html
+++ b/src/test/mir-opt/spanview_terminator.main.built.after.html
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
-<title>spanview_terminator.main.mir_map.0</title>
+<title>spanview_terminator.main.built.after</title>
<style>
.line {
counter-increment: line;
@@ -59,7 +59,7 @@
</style>
</head>
<body>
-<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() {}</span><span><span class="code even" style="--layer: 1" title="0:Return: $DIR/spanview-terminator.rs:5:13: 5:13:
+<div class="code" style="counter-reset: line 4"><span class="line"><span class="code" style="--layer: 0">fn main() {}</span><span><span class="code even" style="--layer: 1" title="0:Return: $DIR/spanview_terminator.rs:5:13: 5:13:
5:13-5:13: Return: return"><span class="annotation">0:Return⦊</span>‸<span class="annotation">⦉0:Return</span></span></span></span></div>
</body>
</html>
diff --git a/src/test/mir-opt/spanview-terminator.rs b/src/test/mir-opt/spanview_terminator.rs
index 92e1411ea..76fced188 100644
--- a/src/test/mir-opt/spanview-terminator.rs
+++ b/src/test/mir-opt/spanview_terminator.rs
@@ -1,5 +1,5 @@
// Test spanview terminator output
// compile-flags: -Z dump-mir-spanview=terminator
-// EMIT_MIR spanview_terminator.main.mir_map.0.html
+// EMIT_MIR spanview_terminator.main.built.after.html
fn main() {}
diff --git a/src/test/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff b/src/test/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..eb8830446
--- /dev/null
+++ b/src/test/mir-opt/sroa.dropping.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,50 @@
+- // MIR for `dropping` before ScalarReplacementOfAggregates
++ // MIR for `dropping` after ScalarReplacementOfAggregates
+
+ fn dropping() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19
+ let _1: Tag; // in scope 0 at $DIR/sroa.rs:+1:5: +1:32
+ let mut _2: S; // in scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ let mut _3: Tag; // in scope 0 at $DIR/sroa.rs:+1:7: +1:13
+ let mut _4: Tag; // in scope 0 at $DIR/sroa.rs:+1:15: +1:21
+ let mut _5: Tag; // in scope 0 at $DIR/sroa.rs:+1:23: +1:29
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/sroa.rs:+1:5: +1:32
+ StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ StorageLive(_3); // scope 0 at $DIR/sroa.rs:+1:7: +1:13
+ Deinit(_3); // scope 0 at $DIR/sroa.rs:+1:7: +1:13
+ (_3.0: usize) = const 0_usize; // scope 0 at $DIR/sroa.rs:+1:7: +1:13
+ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+1:15: +1:21
+ Deinit(_4); // scope 0 at $DIR/sroa.rs:+1:15: +1:21
+ (_4.0: usize) = const 1_usize; // scope 0 at $DIR/sroa.rs:+1:15: +1:21
+ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:23: +1:29
+ Deinit(_5); // scope 0 at $DIR/sroa.rs:+1:23: +1:29
+ (_5.0: usize) = const 2_usize; // scope 0 at $DIR/sroa.rs:+1:23: +1:29
+ Deinit(_2); // scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ (_2.0: Tag) = move _3; // scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ (_2.1: Tag) = move _4; // scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ (_2.2: Tag) = move _5; // scope 0 at $DIR/sroa.rs:+1:5: +1:30
+ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:29: +1:30
+ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+1:29: +1:30
+ StorageDead(_3); // scope 0 at $DIR/sroa.rs:+1:29: +1:30
+ _1 = move (_2.1: Tag); // scope 0 at $DIR/sroa.rs:+1:5: +1:32
+ drop(_1) -> bb1; // scope 0 at $DIR/sroa.rs:+1:32: +1:33
+ }
+
+ bb1: {
+ drop((_2.0: Tag)) -> bb3; // scope 0 at $DIR/sroa.rs:+1:32: +1:33
+ }
+
+ bb2: {
+ StorageDead(_2); // scope 0 at $DIR/sroa.rs:+1:32: +1:33
+ StorageDead(_1); // scope 0 at $DIR/sroa.rs:+1:32: +1:33
+ _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +2:2
+ return; // scope 0 at $DIR/sroa.rs:+2:2: +2:2
+ }
+
+ bb3: {
+ drop((_2.2: Tag)) -> bb2; // scope 0 at $DIR/sroa.rs:+1:32: +1:33
+ }
+ }
+
diff --git a/src/test/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff b/src/test/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..7c7e87c32
--- /dev/null
+++ b/src/test/mir-opt/sroa.enums.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,45 @@
+- // MIR for `enums` before ScalarReplacementOfAggregates
++ // MIR for `enums` after ScalarReplacementOfAggregates
+
+ fn enums(_1: usize) -> usize {
+ debug a => _1; // in scope 0 at $DIR/sroa.rs:+0:14: +0:15
+ let mut _0: usize; // return place in scope 0 at $DIR/sroa.rs:+0:27: +0:32
+ let mut _2: std::option::Option<usize>; // in scope 0 at $DIR/sroa.rs:+1:22: +1:29
+ let mut _3: usize; // in scope 0 at $DIR/sroa.rs:+1:27: +1:28
+ let mut _4: isize; // in scope 0 at $DIR/sroa.rs:+1:12: +1:19
+ scope 1 {
+ debug a => _5; // in scope 1 at $DIR/sroa.rs:+1:17: +1:18
+ let _5: usize; // in scope 1 at $DIR/sroa.rs:+1:17: +1:18
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 1 at $DIR/sroa.rs:+1:22: +1:29
+ StorageLive(_3); // scope 1 at $DIR/sroa.rs:+1:27: +1:28
+ _3 = _1; // scope 1 at $DIR/sroa.rs:+1:27: +1:28
+ Deinit(_2); // scope 1 at $DIR/sroa.rs:+1:22: +1:29
+ ((_2 as Some).0: usize) = move _3; // scope 1 at $DIR/sroa.rs:+1:22: +1:29
+ discriminant(_2) = 1; // scope 1 at $DIR/sroa.rs:+1:22: +1:29
+ StorageDead(_3); // scope 1 at $DIR/sroa.rs:+1:28: +1:29
+ _4 = discriminant(_2); // scope 1 at $DIR/sroa.rs:+1:12: +1:19
+ switchInt(move _4) -> [1_isize: bb1, otherwise: bb2]; // scope 1 at $DIR/sroa.rs:+1:12: +1:19
+ }
+
+ bb1: {
+ StorageLive(_5); // scope 1 at $DIR/sroa.rs:+1:17: +1:18
+ _5 = ((_2 as Some).0: usize); // scope 1 at $DIR/sroa.rs:+1:17: +1:18
+ _0 = _5; // scope 1 at $DIR/sroa.rs:+1:32: +1:33
+ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:34: +1:35
+ goto -> bb3; // scope 0 at $DIR/sroa.rs:+1:5: +1:46
+ }
+
+ bb2: {
+ _0 = const 0_usize; // scope 0 at $DIR/sroa.rs:+1:43: +1:44
+ goto -> bb3; // scope 0 at $DIR/sroa.rs:+1:5: +1:46
+ }
+
+ bb3: {
+ StorageDead(_2); // scope 0 at $DIR/sroa.rs:+2:1: +2:2
+ return; // scope 0 at $DIR/sroa.rs:+2:2: +2:2
+ }
+ }
+
diff --git a/src/test/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff b/src/test/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..64559b58f
--- /dev/null
+++ b/src/test/mir-opt/sroa.escaping.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,47 @@
+- // MIR for `escaping` before ScalarReplacementOfAggregates
++ // MIR for `escaping` after ScalarReplacementOfAggregates
+
+ fn escaping() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19
+ let _1: (); // in scope 0 at $DIR/sroa.rs:+2:5: +2:42
+ let mut _2: *const u32; // in scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ let _3: &u32; // in scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ let _4: Escaping; // in scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ let mut _5: u32; // in scope 0 at $DIR/sroa.rs:+2:34: +2:37
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/sroa.rs:+2:5: +2:42
+ StorageLive(_2); // scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ StorageLive(_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+2:34: +2:37
+ _5 = g() -> bb1; // scope 0 at $DIR/sroa.rs:+2:34: +2:37
+ // mir::Constant
+ // + span: $DIR/sroa.rs:78:34: 78:35
+ // + literal: Const { ty: fn() -> u32 {g}, val: Value(<ZST>) }
+ }
+
+ bb1: {
+ Deinit(_4); // scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ (_4.0: u32) = const 1_u32; // scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ (_4.1: u32) = const 2_u32; // scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ (_4.2: u32) = move _5; // scope 0 at $DIR/sroa.rs:+2:8: +2:39
+ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+2:38: +2:39
+ _3 = &(_4.0: u32); // scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ _2 = &raw const (*_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41
+ _1 = f(move _2) -> bb2; // scope 0 at $DIR/sroa.rs:+2:5: +2:42
+ // mir::Constant
+ // + span: $DIR/sroa.rs:78:5: 78:6
+ // + literal: Const { ty: fn(*const u32) {f}, val: Value(<ZST>) }
+ }
+
+ bb2: {
+ StorageDead(_2); // scope 0 at $DIR/sroa.rs:+2:41: +2:42
+ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+2:42: +2:43
+ StorageDead(_3); // scope 0 at $DIR/sroa.rs:+2:42: +2:43
+ StorageDead(_1); // scope 0 at $DIR/sroa.rs:+2:42: +2:43
+ _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +3:2
+ return; // scope 0 at $DIR/sroa.rs:+3:2: +3:2
+ }
+ }
+
diff --git a/src/test/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff b/src/test/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..d4c04d5e6
--- /dev/null
+++ b/src/test/mir-opt/sroa.flat.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,87 @@
+- // MIR for `flat` before ScalarReplacementOfAggregates
++ // MIR for `flat` after ScalarReplacementOfAggregates
+
+ fn flat() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:15: +0:15
+ let _1: u8; // in scope 0 at $DIR/sroa.rs:+1:15: +1:16
+ let _2: (); // in scope 0 at $DIR/sroa.rs:+1:18: +1:19
+ let _3: &str; // in scope 0 at $DIR/sroa.rs:+1:21: +1:22
+ let _4: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:24: +1:25
+ let mut _5: Foo; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
+ let mut _6: (); // in scope 0 at $DIR/sroa.rs:+1:45: +1:47
+ let mut _7: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:60: +1:68
++ let mut _8: u8; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ let mut _9: (); // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ let mut _10: &str; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ let mut _11: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
+ scope 1 {
+ debug a => _1; // in scope 1 at $DIR/sroa.rs:+1:15: +1:16
+ debug b => _2; // in scope 1 at $DIR/sroa.rs:+1:18: +1:19
+ debug c => _3; // in scope 1 at $DIR/sroa.rs:+1:21: +1:22
+ debug d => _4; // in scope 1 at $DIR/sroa.rs:+1:24: +1:25
+ scope 2 {
+ scope 3 {
+ scope 4 {
+ scope 5 {
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+- StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ StorageLive(_8); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ StorageLive(_9); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ StorageLive(_10); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ StorageLive(_11); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+ StorageLive(_6); // scope 0 at $DIR/sroa.rs:+1:45: +1:47
+ Deinit(_6); // scope 0 at $DIR/sroa.rs:+1:45: +1:47
+ StorageLive(_7); // scope 0 at $DIR/sroa.rs:+1:60: +1:68
+ Deinit(_7); // scope 0 at $DIR/sroa.rs:+1:60: +1:68
+ ((_7 as Some).0: isize) = const -4_isize; // scope 0 at $DIR/sroa.rs:+1:60: +1:68
+ discriminant(_7) = 1; // scope 0 at $DIR/sroa.rs:+1:60: +1:68
+- Deinit(_5); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+- (_5.0: u8) = const 5_u8; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+- (_5.1: ()) = move _6; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+- (_5.2: &str) = const "a"; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ Deinit(_8); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ Deinit(_9); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ Deinit(_10); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ Deinit(_11); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ _8 = const 5_u8; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ _9 = move _6; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ _10 = const "a"; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+ // mir::Constant
+ // + span: $DIR/sroa.rs:57:52: 57:55
+ // + literal: Const { ty: &str, val: Value(Slice(..)) }
+- (_5.3: std::option::Option<isize>) = move _7; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
++ _11 = move _7; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
+ StorageDead(_7); // scope 0 at $DIR/sroa.rs:+1:69: +1:70
+ StorageDead(_6); // scope 0 at $DIR/sroa.rs:+1:69: +1:70
+ StorageLive(_1); // scope 0 at $DIR/sroa.rs:+1:15: +1:16
+- _1 = (_5.0: u8); // scope 0 at $DIR/sroa.rs:+1:15: +1:16
++ _1 = _8; // scope 0 at $DIR/sroa.rs:+1:15: +1:16
+ StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:18: +1:19
+- _2 = (_5.1: ()); // scope 0 at $DIR/sroa.rs:+1:18: +1:19
++ _2 = _9; // scope 0 at $DIR/sroa.rs:+1:18: +1:19
+ StorageLive(_3); // scope 0 at $DIR/sroa.rs:+1:21: +1:22
+- _3 = (_5.2: &str); // scope 0 at $DIR/sroa.rs:+1:21: +1:22
++ _3 = _10; // scope 0 at $DIR/sroa.rs:+1:21: +1:22
+ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+1:24: +1:25
+- _4 = (_5.3: std::option::Option<isize>); // scope 0 at $DIR/sroa.rs:+1:24: +1:25
+- StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
++ _4 = _11; // scope 0 at $DIR/sroa.rs:+1:24: +1:25
++ StorageDead(_8); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
++ StorageDead(_9); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
++ StorageDead(_10); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
++ StorageDead(_11); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
+ _0 = const (); // scope 0 at $DIR/sroa.rs:+0:15: +6:2
+ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+ StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+ StorageDead(_2); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+ StorageDead(_1); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/sroa.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/sroa.rs b/src/test/mir-opt/sroa.rs
new file mode 100644
index 000000000..ff8deb40d
--- /dev/null
+++ b/src/test/mir-opt/sroa.rs
@@ -0,0 +1,88 @@
+// unit-test: ScalarReplacementOfAggregates
+// compile-flags: -Cpanic=abort
+// no-prefer-dynamic
+
+struct Tag(usize);
+
+#[repr(C)]
+struct S(Tag, Tag, Tag);
+
+impl Drop for Tag {
+ #[inline(never)]
+ fn drop(&mut self) {}
+}
+
+// EMIT_MIR sroa.dropping.ScalarReplacementOfAggregates.diff
+pub fn dropping() {
+ S(Tag(0), Tag(1), Tag(2)).1;
+}
+
+// EMIT_MIR sroa.enums.ScalarReplacementOfAggregates.diff
+pub fn enums(a: usize) -> usize {
+ if let Some(a) = Some(a) { a } else { 0 }
+}
+
+// EMIT_MIR sroa.structs.ScalarReplacementOfAggregates.diff
+pub fn structs(a: f32) -> f32 {
+ struct U {
+ _foo: usize,
+ a: f32,
+ }
+
+ U { _foo: 0, a }.a
+}
+
+// EMIT_MIR sroa.unions.ScalarReplacementOfAggregates.diff
+pub fn unions(a: f32) -> u32 {
+ union Repr {
+ f: f32,
+ u: u32,
+ }
+ unsafe { Repr { f: a }.u }
+}
+
+struct Foo {
+ a: u8,
+ b: (),
+ c: &'static str,
+ d: Option<isize>,
+}
+
+fn g() -> u32 {
+ 3
+}
+
+// EMIT_MIR sroa.flat.ScalarReplacementOfAggregates.diff
+pub fn flat() {
+ let Foo { a, b, c, d } = Foo { a: 5, b: (), c: "a", d: Some(-4) };
+ let _ = a;
+ let _ = b;
+ let _ = c;
+ let _ = d;
+}
+
+#[repr(C)]
+struct Escaping {
+ a: u32,
+ b: u32,
+ c: u32,
+}
+
+fn f(a: *const u32) {
+ println!("{}", unsafe { *a.add(2) });
+}
+
+// EMIT_MIR sroa.escaping.ScalarReplacementOfAggregates.diff
+pub fn escaping() {
+ // Verify this struct is not flattened.
+ f(&Escaping { a: 1, b: 2, c: g() }.a);
+}
+
+fn main() {
+ dropping();
+ enums(5);
+ structs(5.);
+ unions(5.);
+ flat();
+ escaping();
+}
diff --git a/src/test/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff b/src/test/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..69d74c351
--- /dev/null
+++ b/src/test/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,34 @@
+- // MIR for `structs` before ScalarReplacementOfAggregates
++ // MIR for `structs` after ScalarReplacementOfAggregates
+
+ fn structs(_1: f32) -> f32 {
+ debug a => _1; // in scope 0 at $DIR/sroa.rs:+0:16: +0:17
+ let mut _0: f32; // return place in scope 0 at $DIR/sroa.rs:+0:27: +0:30
+ let mut _2: structs::U; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21
+ let mut _3: f32; // in scope 0 at $DIR/sroa.rs:+6:18: +6:19
++ let mut _4: usize; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ let mut _5: f32; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21
+
+ bb0: {
+- StorageLive(_2); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
+ StorageLive(_3); // scope 0 at $DIR/sroa.rs:+6:18: +6:19
+ _3 = _1; // scope 0 at $DIR/sroa.rs:+6:18: +6:19
+- Deinit(_2); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
+- (_2.0: usize) = const 0_usize; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
+- (_2.1: f32) = move _3; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ Deinit(_4); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ Deinit(_5); // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ _4 = const 0_usize; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
++ _5 = move _3; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
+ StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:20: +6:21
+- _0 = (_2.1: f32); // scope 0 at $DIR/sroa.rs:+6:5: +6:23
+- StorageDead(_2); // scope 0 at $DIR/sroa.rs:+7:1: +7:2
++ _0 = _5; // scope 0 at $DIR/sroa.rs:+6:5: +6:23
++ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+7:1: +7:2
++ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+7:1: +7:2
+ return; // scope 0 at $DIR/sroa.rs:+7:2: +7:2
+ }
+ }
+
diff --git a/src/test/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff b/src/test/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff
new file mode 100644
index 000000000..03ca976df
--- /dev/null
+++ b/src/test/mir-opt/sroa.unions.ScalarReplacementOfAggregates.diff
@@ -0,0 +1,24 @@
+- // MIR for `unions` before ScalarReplacementOfAggregates
++ // MIR for `unions` after ScalarReplacementOfAggregates
+
+ fn unions(_1: f32) -> u32 {
+ debug a => _1; // in scope 0 at $DIR/sroa.rs:+0:15: +0:16
+ let mut _0: u32; // return place in scope 0 at $DIR/sroa.rs:+0:26: +0:29
+ let mut _2: unions::Repr; // in scope 0 at $DIR/sroa.rs:+5:14: +5:27
+ let mut _3: f32; // in scope 0 at $DIR/sroa.rs:+5:24: +5:25
+ scope 1 {
+ }
+
+ bb0: {
+ StorageLive(_2); // scope 1 at $DIR/sroa.rs:+5:14: +5:27
+ StorageLive(_3); // scope 1 at $DIR/sroa.rs:+5:24: +5:25
+ _3 = _1; // scope 1 at $DIR/sroa.rs:+5:24: +5:25
+ Deinit(_2); // scope 1 at $DIR/sroa.rs:+5:14: +5:27
+ (_2.0: f32) = move _3; // scope 1 at $DIR/sroa.rs:+5:14: +5:27
+ StorageDead(_3); // scope 1 at $DIR/sroa.rs:+5:26: +5:27
+ _0 = (_2.1: u32); // scope 1 at $DIR/sroa.rs:+5:14: +5:29
+ StorageDead(_2); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
+ return; // scope 0 at $DIR/sroa.rs:+6:2: +6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/tls_access.main.PreCodegen.after.mir b/src/test/mir-opt/tls_access.main.PreCodegen.after.mir
index b6c36be2b..09453b8ba 100644
--- a/src/test/mir-opt/tls_access.main.PreCodegen.after.mir
+++ b/src/test/mir-opt/tls_access.main.PreCodegen.after.mir
@@ -1,28 +1,28 @@
// MIR for `main` after PreCodegen
fn main() -> () {
- let mut _0: (); // return place in scope 0 at $DIR/tls-access.rs:+0:11: +0:11
- let _2: *mut u8; // in scope 0 at $DIR/tls-access.rs:+2:18: +2:21
- let mut _3: *mut u8; // in scope 0 at $DIR/tls-access.rs:+3:9: +3:12
+ let mut _0: (); // return place in scope 0 at $DIR/tls_access.rs:+0:11: +0:11
+ let _2: *mut u8; // in scope 0 at $DIR/tls_access.rs:+2:18: +2:21
+ let mut _3: *mut u8; // in scope 0 at $DIR/tls_access.rs:+3:9: +3:12
scope 1 {
- let _1: &u8; // in scope 1 at $DIR/tls-access.rs:+2:13: +2:14
+ let _1: &u8; // in scope 1 at $DIR/tls_access.rs:+2:13: +2:14
scope 2 {
- debug a => _1; // in scope 2 at $DIR/tls-access.rs:+2:13: +2:14
+ debug a => _1; // in scope 2 at $DIR/tls_access.rs:+2:13: +2:14
}
}
bb0: {
- StorageLive(_1); // scope 1 at $DIR/tls-access.rs:+2:13: +2:14
- StorageLive(_2); // scope 1 at $DIR/tls-access.rs:+2:18: +2:21
- _2 = &/*tls*/ mut FOO; // scope 1 at $DIR/tls-access.rs:+2:18: +2:21
- _1 = &(*_2); // scope 1 at $DIR/tls-access.rs:+2:17: +2:21
- StorageLive(_3); // scope 2 at $DIR/tls-access.rs:+3:9: +3:12
- _3 = &/*tls*/ mut FOO; // scope 2 at $DIR/tls-access.rs:+3:9: +3:12
- (*_3) = const 42_u8; // scope 2 at $DIR/tls-access.rs:+3:9: +3:17
- StorageDead(_3); // scope 2 at $DIR/tls-access.rs:+3:17: +3:18
- _0 = const (); // scope 1 at $DIR/tls-access.rs:+1:5: +4:6
- StorageDead(_2); // scope 1 at $DIR/tls-access.rs:+4:5: +4:6
- StorageDead(_1); // scope 1 at $DIR/tls-access.rs:+4:5: +4:6
- return; // scope 0 at $DIR/tls-access.rs:+5:2: +5:2
+ StorageLive(_1); // scope 1 at $DIR/tls_access.rs:+2:13: +2:14
+ StorageLive(_2); // scope 1 at $DIR/tls_access.rs:+2:18: +2:21
+ _2 = &/*tls*/ mut FOO; // scope 1 at $DIR/tls_access.rs:+2:18: +2:21
+ _1 = &(*_2); // scope 1 at $DIR/tls_access.rs:+2:17: +2:21
+ StorageLive(_3); // scope 2 at $DIR/tls_access.rs:+3:9: +3:12
+ _3 = &/*tls*/ mut FOO; // scope 2 at $DIR/tls_access.rs:+3:9: +3:12
+ (*_3) = const 42_u8; // scope 2 at $DIR/tls_access.rs:+3:9: +3:17
+ StorageDead(_3); // scope 2 at $DIR/tls_access.rs:+3:17: +3:18
+ _0 = const (); // scope 1 at $DIR/tls_access.rs:+1:5: +4:6
+ StorageDead(_2); // scope 1 at $DIR/tls_access.rs:+4:5: +4:6
+ StorageDead(_1); // scope 1 at $DIR/tls_access.rs:+4:5: +4:6
+ return; // scope 0 at $DIR/tls_access.rs:+5:2: +5:2
}
}
diff --git a/src/test/mir-opt/tls-access.rs b/src/test/mir-opt/tls_access.rs
index 19344c868..19344c868 100644
--- a/src/test/mir-opt/tls-access.rs
+++ b/src/test/mir-opt/tls_access.rs
diff --git a/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir b/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
index 330929c58..30185f3ff 100644
--- a/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
+++ b/src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
@@ -3,77 +3,56 @@
fn new(_1: Result<T, E>) -> Result<T, E> {
debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15
let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
- let mut _2: T; // in scope 0 at $DIR/try_identity_e2e.rs:+2:9: +10:10
- let mut _3: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
- let mut _4: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:22
- let _5: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
- let mut _6: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:48: +4:49
- let _7: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
- let mut _8: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:46: +5:47
- let mut _9: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+8:13: +8:37
- let _10: T; // in scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
- let _11: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
- let mut _12: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:49: +9:50
+ let mut _2: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ let mut _3: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:22
+ let mut _4: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:48: +4:49
+ let mut _5: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:46: +5:47
+ let mut _6: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+8:13: +8:37
+ let _7: T; // in scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
+ let mut _8: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:49: +9:50
scope 1 {
- debug v => _5; // in scope 1 at $DIR/try_identity_e2e.rs:+4:20: +4:21
+ debug v => _4; // in scope 1 at $DIR/try_identity_e2e.rs:+4:20: +4:21
}
scope 2 {
- debug e => _7; // in scope 2 at $DIR/try_identity_e2e.rs:+5:21: +5:22
+ debug e => _5; // in scope 2 at $DIR/try_identity_e2e.rs:+5:21: +5:22
}
scope 3 {
- debug v => _10; // in scope 3 at $DIR/try_identity_e2e.rs:+8:35: +8:36
+ debug v => _7; // in scope 3 at $DIR/try_identity_e2e.rs:+8:35: +8:36
}
scope 4 {
- debug e => _11; // in scope 4 at $DIR/try_identity_e2e.rs:+9:32: +9:33
+ debug e => _8; // in scope 4 at $DIR/try_identity_e2e.rs:+9:32: +9:33
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +10:10
- StorageLive(_3); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
- _4 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20
- switchInt(move _4) -> [0_isize: bb2, 1_isize: bb1, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20
+ StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ _3 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20
+ switchInt(move _3) -> [0_isize: bb2, 1_isize: bb1, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20
}
bb1: {
- StorageLive(_7); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
- _7 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
- StorageLive(_8); // scope 2 at $DIR/try_identity_e2e.rs:+5:46: +5:47
- _8 = move _7; // scope 2 at $DIR/try_identity_e2e.rs:+5:46: +5:47
- Deinit(_3); // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
- ((_3 as Break).0: E) = move _8; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
- discriminant(_3) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
- StorageDead(_8); // scope 2 at $DIR/try_identity_e2e.rs:+5:47: +5:48
- StorageDead(_7); // scope 0 at $DIR/try_identity_e2e.rs:+5:47: +5:48
- _9 = discriminant(_3); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
- switchInt(move _9) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
+ _5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
+ Deinit(_2); // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
+ ((_2 as Break).0: E) = move _5; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
+ discriminant(_2) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
+ _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ switchInt(move _6) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
}
bb2: {
- StorageLive(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
- _5 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
- StorageLive(_6); // scope 1 at $DIR/try_identity_e2e.rs:+4:48: +4:49
- _6 = move _5; // scope 1 at $DIR/try_identity_e2e.rs:+4:48: +4:49
- Deinit(_3); // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
- ((_3 as Continue).0: T) = move _6; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
- discriminant(_3) = 0; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
- StorageDead(_6); // scope 1 at $DIR/try_identity_e2e.rs:+4:49: +4:50
- StorageDead(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:49: +4:50
- _9 = discriminant(_3); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
- switchInt(move _9) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
+ _4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
+ Deinit(_2); // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
+ ((_2 as Continue).0: T) = move _4; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
+ discriminant(_2) = 0; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
+ _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
+ switchInt(move _6) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
}
bb3: {
- StorageLive(_11); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
- _11 = move ((_3 as Break).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
- StorageLive(_12); // scope 4 at $DIR/try_identity_e2e.rs:+9:49: +9:50
- _12 = move _11; // scope 4 at $DIR/try_identity_e2e.rs:+9:49: +9:50
+ _8 = move ((_2 as Break).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
Deinit(_0); // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
- ((_0 as Err).0: E) = move _12; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
+ ((_0 as Err).0: E) = move _8; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
discriminant(_0) = 1; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
- StorageDead(_12); // scope 4 at $DIR/try_identity_e2e.rs:+9:50: +9:51
- StorageDead(_11); // scope 0 at $DIR/try_identity_e2e.rs:+9:50: +9:51
- StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+11:5: +11:6
- StorageDead(_3); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
+ StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
}
@@ -82,15 +61,11 @@ fn new(_1: Result<T, E>) -> Result<T, E> {
}
bb5: {
- StorageLive(_10); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
- _10 = move ((_3 as Continue).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
- _2 = move _10; // scope 3 at $DIR/try_identity_e2e.rs:+8:41: +8:42
- StorageDead(_10); // scope 0 at $DIR/try_identity_e2e.rs:+8:41: +8:42
+ _7 = move ((_2 as Continue).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
- ((_0 as Ok).0: T) = move _2; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
+ ((_0 as Ok).0: T) = move _7; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
- StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+11:5: +11:6
- StorageDead(_3); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
+ StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
}
}
diff --git a/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir b/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
index 18d3e0fb2..2a9c7408c 100644
--- a/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
+++ b/src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
@@ -3,35 +3,26 @@
fn old(_1: Result<T, E>) -> Result<T, E> {
debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15
let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
- let mut _2: T; // in scope 0 at $DIR/try_identity_e2e.rs:+2:9: +5:10
- let mut _3: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:18
- let _4: T; // in scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
- let _5: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
- let mut _6: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:34: +4:35
+ let mut _2: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:18
+ let _3: T; // in scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
+ let mut _4: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:34: +4:35
scope 1 {
- debug v => _4; // in scope 1 at $DIR/try_identity_e2e.rs:+3:16: +3:17
+ debug v => _3; // in scope 1 at $DIR/try_identity_e2e.rs:+3:16: +3:17
}
scope 2 {
- debug e => _5; // in scope 2 at $DIR/try_identity_e2e.rs:+4:17: +4:18
+ debug e => _4; // in scope 2 at $DIR/try_identity_e2e.rs:+4:17: +4:18
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +5:10
- _3 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16
- switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +2:16
+ _2 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16
+ switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +2:16
}
bb1: {
- StorageLive(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
- _5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
- StorageLive(_6); // scope 2 at $DIR/try_identity_e2e.rs:+4:34: +4:35
- _6 = move _5; // scope 2 at $DIR/try_identity_e2e.rs:+4:34: +4:35
+ _4 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
Deinit(_0); // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
- ((_0 as Err).0: E) = move _6; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
+ ((_0 as Err).0: E) = move _4; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
discriminant(_0) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
- StorageDead(_6); // scope 2 at $DIR/try_identity_e2e.rs:+4:35: +4:36
- StorageDead(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:35: +4:36
- StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+6:5: +6:6
return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2
}
@@ -40,14 +31,10 @@ fn old(_1: Result<T, E>) -> Result<T, E> {
}
bb3: {
- StorageLive(_4); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
- _4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
- _2 = move _4; // scope 1 at $DIR/try_identity_e2e.rs:+3:22: +3:23
- StorageDead(_4); // scope 0 at $DIR/try_identity_e2e.rs:+3:22: +3:23
+ _3 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
- ((_0 as Ok).0: T) = move _2; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
+ ((_0 as Ok).0: T) = move _3; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
- StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+6:5: +6:6
return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2
}
}
diff --git a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir
index 6ed53643f..2c0fcc662 100644
--- a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir
+++ b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir
@@ -1,16 +1,16 @@
// MIR for `process_never` after SimplifyLocals
fn process_never(_1: *const !) -> () {
- debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:+0:22: +0:27
- let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:+0:39: +0:39
- let _2: &!; // in scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14
+ debug input => _1; // in scope 0 at $DIR/uninhabited_enum.rs:+0:22: +0:27
+ let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum.rs:+0:39: +0:39
+ let _2: &!; // in scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14
scope 1 {
- debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:+1:8: +1:14
+ debug _input => _2; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14
}
scope 2 {
}
bb0: {
- unreachable; // scope 0 at $DIR/uninhabited-enum.rs:+0:39: +2:2
+ unreachable; // scope 0 at $DIR/uninhabited_enum.rs:+0:39: +2:2
}
}
diff --git a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir
index bbb81724c..ae341a7b9 100644
--- a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir
+++ b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir
@@ -1,18 +1,18 @@
// MIR for `process_void` after SimplifyLocals
fn process_void(_1: *const Void) -> () {
- debug input => _1; // in scope 0 at $DIR/uninhabited-enum.rs:+0:21: +0:26
- let mut _0: (); // return place in scope 0 at $DIR/uninhabited-enum.rs:+0:41: +0:41
- let _2: &Void; // in scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14
+ debug input => _1; // in scope 0 at $DIR/uninhabited_enum.rs:+0:21: +0:26
+ let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum.rs:+0:41: +0:41
+ let _2: &Void; // in scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14
scope 1 {
- debug _input => _2; // in scope 1 at $DIR/uninhabited-enum.rs:+1:8: +1:14
+ debug _input => _2; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14
}
scope 2 {
}
bb0: {
- StorageLive(_2); // scope 0 at $DIR/uninhabited-enum.rs:+1:8: +1:14
- StorageDead(_2); // scope 0 at $DIR/uninhabited-enum.rs:+4:1: +4:2
- return; // scope 0 at $DIR/uninhabited-enum.rs:+4:2: +4:2
+ StorageLive(_2); // scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14
+ StorageDead(_2); // scope 0 at $DIR/uninhabited_enum.rs:+4:1: +4:2
+ return; // scope 0 at $DIR/uninhabited_enum.rs:+4:2: +4:2
}
}
diff --git a/src/test/mir-opt/uninhabited-enum.rs b/src/test/mir-opt/uninhabited_enum.rs
index 97c6e8cd5..97c6e8cd5 100644
--- a/src/test/mir-opt/uninhabited-enum.rs
+++ b/src/test/mir-opt/uninhabited_enum.rs
diff --git a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir
index a72e00ecd..5257491f0 100644
--- a/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.mir_map.0.mir
+++ b/src/test/mir-opt/unusual_item_types.E-V-{constant#0}.built.after.mir
@@ -1,10 +1,10 @@
-// MIR for `E::V::{constant#0}` 0 mir_map
+// MIR for `E::V::{constant#0}` after built
E::V::{constant#0}: isize = {
- let mut _0: isize; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+ let mut _0: isize; // return place in scope 0 at $DIR/unusual_item_types.rs:+0:9: +0:10
bb0: {
- _0 = const 5_isize; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
- return; // scope 0 at $DIR/unusual-item-types.rs:+0:9: +0:10
+ _0 = const 5_isize; // scope 0 at $DIR/unusual_item_types.rs:+0:9: +0:10
+ return; // scope 0 at $DIR/unusual_item_types.rs:+0:9: +0:10
}
}
diff --git a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir
index 0686af46e..ee0296763 100644
--- a/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir
+++ b/src/test/mir-opt/unusual_item_types.Test-X-{constructor#0}.built.after.mir
@@ -1,12 +1,12 @@
-// MIR for `Test::X` 0 mir_map
+// MIR for `Test::X` after built
fn Test::X(_1: usize) -> Test {
- let mut _0: Test; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+ let mut _0: Test; // return place in scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:6
bb0: {
- Deinit(_0); // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
- ((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
- discriminant(_0) = 0; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
- return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:6
+ Deinit(_0); // scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:6
+ ((_0 as X).0: usize) = move _1; // scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:6
+ discriminant(_0) = 0; // scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:6
+ return; // scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:6
}
}
diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual_item_types.rs
index 9ef3d8647..6dad63641 100644
--- a/src/test/mir-opt/unusual-item-types.rs
+++ b/src/test/mir-opt/unusual_item_types.rs
@@ -5,19 +5,19 @@
struct A;
-// EMIT_MIR unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir
+// EMIT_MIR unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir
impl A {
const ASSOCIATED_CONSTANT: i32 = 2;
}
// See #59021
-// EMIT_MIR unusual_item_types.Test-X-{constructor#0}.mir_map.0.mir
+// EMIT_MIR unusual_item_types.Test-X-{constructor#0}.built.after.mir
enum Test {
X(usize),
Y { a: usize },
}
-// EMIT_MIR unusual_item_types.E-V-{constant#0}.mir_map.0.mir
+// EMIT_MIR unusual_item_types.E-V-{constant#0}.built.after.mir
enum E {
V = 5,
}
diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir
new file mode 100644
index 000000000..90444b481
--- /dev/null
+++ b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.built.after.mir
@@ -0,0 +1,10 @@
+// MIR for `<impl at $DIR/unusual_item_types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` after built
+
+const <impl at $DIR/unusual_item_types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = {
+ let mut _0: i32; // return place in scope 0 at $DIR/unusual_item_types.rs:+0:32: +0:35
+
+ bb0: {
+ _0 = const 2_i32; // scope 0 at $DIR/unusual_item_types.rs:+0:38: +0:39
+ return; // scope 0 at $DIR/unusual_item_types.rs:+0:5: +0:40
+ }
+}
diff --git a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir b/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir
deleted file mode 100644
index 5579d25a1..000000000
--- a/src/test/mir-opt/unusual_item_types.{impl#0}-ASSOCIATED_CONSTANT.mir_map.0.mir
+++ /dev/null
@@ -1,10 +0,0 @@
-// MIR for `<impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT` 0 mir_map
-
-const <impl at $DIR/unusual-item-types.rs:9:1: 9:7>::ASSOCIATED_CONSTANT: i32 = {
- let mut _0: i32; // return place in scope 0 at $DIR/unusual-item-types.rs:+0:32: +0:35
-
- bb0: {
- _0 = const 2_i32; // scope 0 at $DIR/unusual-item-types.rs:+0:38: +0:39
- return; // scope 0 at $DIR/unusual-item-types.rs:+0:5: +0:40
- }
-}
diff --git a/src/test/mir-opt/while-storage.rs b/src/test/mir-opt/while_storage.rs
index afd083acb..afd083acb 100644
--- a/src/test/mir-opt/while-storage.rs
+++ b/src/test/mir-opt/while_storage.rs
diff --git a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
index a5e7d6afd..68aa3e5db 100644
--- a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
+++ b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
@@ -1,56 +1,56 @@
// MIR for `while_loop` after PreCodegen
fn while_loop(_1: bool) -> () {
- debug c => _1; // in scope 0 at $DIR/while-storage.rs:+0:15: +0:16
- let mut _0: (); // return place in scope 0 at $DIR/while-storage.rs:+0:24: +0:24
- let mut _2: bool; // in scope 0 at $DIR/while-storage.rs:+1:11: +1:22
- let mut _3: bool; // in scope 0 at $DIR/while-storage.rs:+1:20: +1:21
- let mut _4: bool; // in scope 0 at $DIR/while-storage.rs:+2:12: +2:23
- let mut _5: bool; // in scope 0 at $DIR/while-storage.rs:+2:21: +2:22
+ debug c => _1; // in scope 0 at $DIR/while_storage.rs:+0:15: +0:16
+ let mut _0: (); // return place in scope 0 at $DIR/while_storage.rs:+0:24: +0:24
+ let mut _2: bool; // in scope 0 at $DIR/while_storage.rs:+1:11: +1:22
+ let mut _3: bool; // in scope 0 at $DIR/while_storage.rs:+1:20: +1:21
+ let mut _4: bool; // in scope 0 at $DIR/while_storage.rs:+2:12: +2:23
+ let mut _5: bool; // in scope 0 at $DIR/while_storage.rs:+2:21: +2:22
bb0: {
- goto -> bb1; // scope 0 at $DIR/while-storage.rs:+1:5: +5:6
+ goto -> bb1; // scope 0 at $DIR/while_storage.rs:+1:5: +5:6
}
bb1: {
- StorageLive(_2); // scope 0 at $DIR/while-storage.rs:+1:11: +1:22
- StorageLive(_3); // scope 0 at $DIR/while-storage.rs:+1:20: +1:21
- _3 = _1; // scope 0 at $DIR/while-storage.rs:+1:20: +1:21
- _2 = get_bool(move _3) -> bb2; // scope 0 at $DIR/while-storage.rs:+1:11: +1:22
+ StorageLive(_2); // scope 0 at $DIR/while_storage.rs:+1:11: +1:22
+ StorageLive(_3); // scope 0 at $DIR/while_storage.rs:+1:20: +1:21
+ _3 = _1; // scope 0 at $DIR/while_storage.rs:+1:20: +1:21
+ _2 = get_bool(move _3) -> bb2; // scope 0 at $DIR/while_storage.rs:+1:11: +1:22
// mir::Constant
- // + span: $DIR/while-storage.rs:10:11: 10:19
+ // + span: $DIR/while_storage.rs:10:11: 10:19
// + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(<ZST>) }
}
bb2: {
- StorageDead(_3); // scope 0 at $DIR/while-storage.rs:+1:21: +1:22
- switchInt(move _2) -> [false: bb7, otherwise: bb3]; // scope 0 at $DIR/while-storage.rs:+1:11: +1:22
+ StorageDead(_3); // scope 0 at $DIR/while_storage.rs:+1:21: +1:22
+ switchInt(move _2) -> [false: bb7, otherwise: bb3]; // scope 0 at $DIR/while_storage.rs:+1:11: +1:22
}
bb3: {
- StorageLive(_4); // scope 0 at $DIR/while-storage.rs:+2:12: +2:23
- StorageLive(_5); // scope 0 at $DIR/while-storage.rs:+2:21: +2:22
- _5 = _1; // scope 0 at $DIR/while-storage.rs:+2:21: +2:22
- _4 = get_bool(move _5) -> bb4; // scope 0 at $DIR/while-storage.rs:+2:12: +2:23
+ StorageLive(_4); // scope 0 at $DIR/while_storage.rs:+2:12: +2:23
+ StorageLive(_5); // scope 0 at $DIR/while_storage.rs:+2:21: +2:22
+ _5 = _1; // scope 0 at $DIR/while_storage.rs:+2:21: +2:22
+ _4 = get_bool(move _5) -> bb4; // scope 0 at $DIR/while_storage.rs:+2:12: +2:23
// mir::Constant
- // + span: $DIR/while-storage.rs:11:12: 11:20
+ // + span: $DIR/while_storage.rs:11:12: 11:20
// + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(<ZST>) }
}
bb4: {
- StorageDead(_5); // scope 0 at $DIR/while-storage.rs:+2:22: +2:23
- switchInt(move _4) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/while-storage.rs:+2:12: +2:23
+ StorageDead(_5); // scope 0 at $DIR/while_storage.rs:+2:22: +2:23
+ switchInt(move _4) -> [false: bb6, otherwise: bb5]; // scope 0 at $DIR/while_storage.rs:+2:12: +2:23
}
bb5: {
- StorageDead(_4); // scope 0 at $DIR/while-storage.rs:+4:9: +4:10
+ StorageDead(_4); // scope 0 at $DIR/while_storage.rs:+4:9: +4:10
goto -> bb8; // scope 0 at no-location
}
bb6: {
- StorageDead(_4); // scope 0 at $DIR/while-storage.rs:+4:9: +4:10
- StorageDead(_2); // scope 0 at $DIR/while-storage.rs:+5:5: +5:6
- goto -> bb1; // scope 0 at $DIR/while-storage.rs:+1:5: +5:6
+ StorageDead(_4); // scope 0 at $DIR/while_storage.rs:+4:9: +4:10
+ StorageDead(_2); // scope 0 at $DIR/while_storage.rs:+5:5: +5:6
+ goto -> bb1; // scope 0 at $DIR/while_storage.rs:+1:5: +5:6
}
bb7: {
@@ -58,7 +58,7 @@ fn while_loop(_1: bool) -> () {
}
bb8: {
- StorageDead(_2); // scope 0 at $DIR/while-storage.rs:+5:5: +5:6
- return; // scope 0 at $DIR/while-storage.rs:+6:2: +6:2
+ StorageDead(_2); // scope 0 at $DIR/while_storage.rs:+5:5: +5:6
+ return; // scope 0 at $DIR/while_storage.rs:+6:2: +6:2
}
}
diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
index 2c4309fbe..3aa57d589 100644
--- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
+++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
@@ -67,7 +67,7 @@ impl CodegenBackend for TheBackend {
if crate_type != CrateType::Rlib {
sess.fatal(&format!("Crate type is {:?}", crate_type));
}
- let output_name = out_filename(sess, crate_type, &outputs, &*crate_name.as_str());
+ let output_name = out_filename(sess, crate_type, &outputs, crate_name);
let mut out_file = ::std::fs::File::create(output_name).unwrap();
write!(out_file, "This has been \"compiled\" successfully.").unwrap();
}
diff --git a/src/test/run-make-fulldeps/issue-51671/Makefile b/src/test/run-make-fulldeps/issue-51671/Makefile
index 1d1d370d3..c93645369 100644
--- a/src/test/run-make-fulldeps/issue-51671/Makefile
+++ b/src/test/run-make-fulldeps/issue-51671/Makefile
@@ -6,4 +6,4 @@ all:
$(RUSTC) --emit=obj app.rs
nm $(TMPDIR)/app.o | $(CGREP) rust_begin_unwind
nm $(TMPDIR)/app.o | $(CGREP) rust_eh_personality
- nm $(TMPDIR)/app.o | $(CGREP) rust_oom
+ nm $(TMPDIR)/app.o | $(CGREP) __rg_oom
diff --git a/src/test/run-make-fulldeps/issue-51671/app.rs b/src/test/run-make-fulldeps/issue-51671/app.rs
index c13937dcf..e9dc1e974 100644
--- a/src/test/run-make-fulldeps/issue-51671/app.rs
+++ b/src/test/run-make-fulldeps/issue-51671/app.rs
@@ -1,5 +1,5 @@
#![crate_type = "bin"]
-#![feature(lang_items)]
+#![feature(lang_items, alloc_error_handler)]
#![no_main]
#![no_std]
@@ -14,7 +14,7 @@ fn panic(_: &PanicInfo) -> ! {
#[lang = "eh_personality"]
fn eh() {}
-#[lang = "oom"]
+#[alloc_error_handler]
fn oom(_: Layout) -> ! {
loop {}
}
diff --git a/src/test/run-make-fulldeps/libtest-json/output-default.json b/src/test/run-make-fulldeps/libtest-json/output-default.json
index 63342abc6..ad22b66ed 100644
--- a/src/test/run-make-fulldeps/libtest-json/output-default.json
+++ b/src/test/run-make-fulldeps/libtest-json/output-default.json
@@ -2,7 +2,7 @@
{ "type": "test", "event": "started", "name": "a" }
{ "type": "test", "name": "a", "event": "ok" }
{ "type": "test", "event": "started", "name": "b" }
-{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
+{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'b' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
{ "type": "test", "event": "started", "name": "c" }
{ "type": "test", "name": "c", "event": "ok" }
{ "type": "test", "event": "started", "name": "d" }
diff --git a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
index 8f1911446..ec98172eb 100644
--- a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
+++ b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
@@ -2,9 +2,9 @@
{ "type": "test", "event": "started", "name": "a" }
{ "type": "test", "name": "a", "event": "ok", "stdout": "print from successful test\n" }
{ "type": "test", "event": "started", "name": "b" }
-{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
+{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'b' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
{ "type": "test", "event": "started", "name": "c" }
-{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" }
+{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'c' panicked at 'assertion failed: false', f.rs:15:5\n" }
{ "type": "test", "event": "started", "name": "d" }
{ "type": "test", "name": "d", "event": "ignored", "message": "msg" }
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
diff --git a/src/test/run-make-fulldeps/link-dedup/Makefile b/src/test/run-make-fulldeps/link-dedup/Makefile
index 5c9603352..eff18ab48 100644
--- a/src/test/run-make-fulldeps/link-dedup/Makefile
+++ b/src/test/run-make-fulldeps/link-dedup/Makefile
@@ -9,4 +9,4 @@ all:
$(RUSTC) empty.rs --cfg bar 2>&1 | $(CGREP) '"-ltesta" "-ltestb" "-ltesta"'
$(RUSTC) empty.rs 2>&1 | $(CGREP) '"-ltesta"'
$(RUSTC) empty.rs 2>&1 | $(CGREP) -v '"-ltestb"'
- $(RUSTC) empty.rs 2>&1 | $(CGREP) -v '"-ltesta" "-ltesta"'
+ $(RUSTC) empty.rs 2>&1 | $(CGREP) -v '"-ltesta" "-ltesta" "-ltesta"'
diff --git a/src/test/run-make-fulldeps/link-dedup/depa.rs b/src/test/run-make-fulldeps/link-dedup/depa.rs
index e48ffd641..19178c5bd 100644
--- a/src/test/run-make-fulldeps/link-dedup/depa.rs
+++ b/src/test/run-make-fulldeps/link-dedup/depa.rs
@@ -5,3 +5,6 @@ extern "C" {}
#[link(name = "testa")]
extern "C" {}
+
+#[link(name = "testa")]
+extern "C" {}
diff --git a/src/test/run-make-fulldeps/split-debuginfo/Makefile b/src/test/run-make-fulldeps/split-debuginfo/Makefile
index 1032f3408..1831ab38f 100644
--- a/src/test/run-make-fulldeps/split-debuginfo/Makefile
+++ b/src/test/run-make-fulldeps/split-debuginfo/Makefile
@@ -3,7 +3,7 @@ include ../tools.mk
all: off packed unpacked
ifeq ($(UNAME),Darwin)
-# If disabled, don't run dsymutil
+# If disabled, don't run `dsymutil`.
off:
rm -rf $(TMPDIR)/*.dSYM
$(RUSTC) foo.rs -g -C split-debuginfo=off
@@ -29,98 +29,280 @@ unpacked:
[ ! -d $(TMPDIR)/foo.dSYM ]
else
ifdef IS_WINDOWS
-# Windows only supports =packed
+# Windows only supports packed debuginfo - nothing to test.
off:
packed:
unpacked:
else
+# Some non-Windows, non-Darwin platforms are not stable, and some are.
ifeq ($(UNAME),Linux)
UNSTABLEOPTS :=
else
UNSTABLEOPTS := -Zunstable-options
endif
+# - Debuginfo in `.o` files
+# - `.o` deleted
+# - `.dwo` never created
+# - `.dwp` never created
off:
$(RUSTC) foo.rs -g -C $(UNSTABLEOPTS) split-debuginfo=off
[ ! -f $(TMPDIR)/*.dwp ]
[ ! -f $(TMPDIR)/*.dwo ]
-
$(RUSTC) foo.rs -g
[ ! -f $(TMPDIR)/*.dwp ]
[ ! -f $(TMPDIR)/*.dwo ]
-packed: packed-split packed-single
+packed: packed-split packed-single packed-lto packed-remapped packed-crosscrate
+# - Debuginfo in `.dwo` files
+# - `.o` deleted
+# - `.dwo` deleted
+# - `.dwp` present
packed-split:
$(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=split
- ls $(TMPDIR)/*.dwp
- rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+ rm $(TMPDIR)/foo.dwp
+ rm $(TMPDIR)/$(call BIN,foo)
+# - Debuginfo in `.o` files
+# - `.o` deleted
+# - `.dwo` never created
+# - `.dwp` present
packed-single:
$(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=single
- ls $(TMPDIR)/*.dwp
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+ rm $(TMPDIR)/foo.dwp
+ rm $(TMPDIR)/$(call BIN,foo)
+
+packed-lto: packed-lto-split packed-lto-single
+
+# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated
+# - `.o` never created
+# - `.dwo` never created
+# - `.dwp` never created
+packed-lto-split:
+ $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split \
+ --crate-type=rlib -Clinker-plugin-lto
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ rm $(TMPDIR)/libbaz.rlib
+
+# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated
+# - `.o` never created
+# - `.dwo` never created
+# - `.dwp` never created
+packed-lto-single:
+ $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single \
+ --crate-type=rlib -Clinker-plugin-lto
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
- rm -rf $(TMPDIR)/*.dwp
+ ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ rm $(TMPDIR)/libbaz.rlib
packed-remapped: packed-remapped-split packed-remapped-single
+# - Debuginfo in `.dwo` files
+# - `.o` and binary refer to remapped `.dwo` paths which do not exist
+# - `.o` deleted
+# - `.dwo` deleted
+# - `.dwp` present
packed-remapped-split:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
-Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+ rm $(TMPDIR)/foo.dwp
+ rm $(TMPDIR)/$(call BIN,foo)
+# - Debuginfo in `.o` files
+# - `.o` and binary refer to remapped `.o` paths which do not exist
+# - `.o` deleted
+# - `.dwo` never created
+# - `.dwp` present
packed-remapped-single:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+ rm $(TMPDIR)/foo.dwp
+ rm $(TMPDIR)/$(call BIN,foo)
packed-crosscrate: packed-crosscrate-split packed-crosscrate-single
+# - Debuginfo in `.dwo` files
+# - (bar) `.rlib` file created, contains `.dwo`
+# - (bar) `.o` deleted
+# - (bar) `.dwo` deleted
+# - (bar) `.dwp` never created
+# - (main) `.o` deleted
+# - (main) `.dwo` deleted
+# - (main) `.dwp` present
packed-crosscrate-split:
$(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \
-Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs
ls $(TMPDIR)/*.rlib
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
- $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS) \
+ $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \
-C split-debuginfo=packed -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs
- rm $(TMPDIR)/*.dwo
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
rm $(TMPDIR)/main.dwp
rm $(TMPDIR)/$(call BIN,main)
+# - Debuginfo in `.o` files
+# - (bar) `.rlib` file created, contains `.o`
+# - (bar) `.o` deleted
+# - (bar) `.dwo` never created
+# - (bar) `.dwp` never created
+# - (main) `.o` deleted
+# - (main) `.dwo` never created
+# - (main) `.dwp` present
packed-crosscrate-single:
$(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \
-Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs
ls $(TMPDIR)/*.rlib
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
- $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS) \
+ $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \
-C split-debuginfo=packed -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
rm $(TMPDIR)/main.dwp
rm $(TMPDIR)/$(call BIN,main)
-unpacked: unpacked-split unpacked-single unpacked-remapped-split unpacked-remapped-single
+unpacked: unpacked-split unpacked-single unpacked-lto unpacked-remapped unpacked-crosscrate
+# - Debuginfo in `.dwo` files
+# - `.o` deleted
+# - `.dwo` present
+# - `.dwp` never created
unpacked-split:
$(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ rm $(TMPDIR)/*.dwo
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
- ls $(TMPDIR)/*.dwo
- rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo
+ rm $(TMPDIR)/$(call BIN,foo)
+# - Debuginfo in `.o` files
+# - `.o` present
+# - `.dwo` never created
+# - `.dwp` never created
unpacked-single:
$(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single
+ ls $(TMPDIR)/*.o
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ rm $(TMPDIR)/$(call BIN,foo)
+
+unpacked-lto: packed-lto-split packed-lto-single
+
+# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated
+# - `.o` never created
+# - `.dwo` never created
+# - `.dwp` never created
+unpacked-lto-split:
+ $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=split \
+ --crate-type=rlib -Clinker-plugin-lto
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ rm $(TMPDIR)/libbaz.rlib
+
+# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated
+# - `.o` never created
+# - `.dwo` never created
+# - `.dwp` never created
+unpacked-lto-single:
+ $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single \
+ --crate-type=rlib -Clinker-plugin-lto
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ rm $(TMPDIR)/libbaz.rlib
+
+unpacked-remapped: unpacked-remapped-split unpacked-remapped-single
+# - Debuginfo in `.dwo` files
+# - `.o` and binary refer to remapped `.dwo` paths which do not exist
+# - `.o` deleted
+# - `.dwo` present
+# - `.dwp` never created
unpacked-remapped-split:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
-Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ rm $(TMPDIR)/*.dwo
+ ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ rm $(TMPDIR)/$(call BIN,foo)
+# - Debuginfo in `.o` files
+# - `.o` and binary refer to remapped `.o` paths which do not exist
+# - `.o` present
+# - `.dwo` never created
+# - `.dwp` never created
unpacked-remapped-single:
$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g
objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
+ ls $(TMPDIR)/*.o
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ rm $(TMPDIR)/$(call BIN,foo)
+
+unpacked-crosscrate: packed-crosscrate-split packed-crosscrate-single
+
+# - Debuginfo in `.dwo` files
+# - (bar) `.rlib` file created, contains `.dwo`
+# - (bar) `.o` deleted
+# - (bar) `.dwo` present
+# - (bar) `.dwp` never created
+# - (main) `.o` deleted
+# - (main) `.dwo` present
+# - (main) `.dwp` never created
+unpacked-crosscrate-split:
+ $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked \
+ -Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs
+ ls $(TMPDIR)/*.rlib
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwo
+ ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \
+ -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs
+ ls $(TMPDIR)/*.o && exit 1 || exit 0
+ rm $(TMPDIR)/*.dwo
+ ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ rm $(TMPDIR)/$(call BIN,main)
+
+# - Debuginfo in `.o` files
+# - (bar) `.rlib` file created, contains `.o`
+# - (bar) `.o` present
+# - (bar) `.dwo` never created
+# - (bar) `.dwp` never created
+# - (main) `.o` present
+# - (main) `.dwo` never created
+# - (main) `.dwp` never created
+unpacked-crosscrate-single:
+ $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked \
+ -Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs
+ ls $(TMPDIR)/*.rlib
+ ls $(TMPDIR)/*.o
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \
+ -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs
+ ls $(TMPDIR)/*.o
+ ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+ ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+ rm $(TMPDIR)/$(call BIN,main)
endif
endif
diff --git a/src/test/run-make-fulldeps/split-debuginfo/baz.rs b/src/test/run-make-fulldeps/split-debuginfo/baz.rs
new file mode 100644
index 000000000..8b1a39374
--- /dev/null
+++ b/src/test/run-make-fulldeps/split-debuginfo/baz.rs
@@ -0,0 +1 @@
+// empty
diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk
index 33bf95ac1..0f5425daa 100644
--- a/src/test/run-make-fulldeps/tools.mk
+++ b/src/test/run-make-fulldeps/tools.mk
@@ -40,6 +40,17 @@ endif
# e.g. for `$(CC) -o $(RUN_BINFILE)`.
RUN_BINFILE = $(TMPDIR)/$(1)
+# Invoke the generated binary on the remote machine if compiletest was
+# configured to use a remote test device, otherwise run it on the current host.
+ifdef REMOTE_TEST_CLIENT
+# FIXME: if a test requires additional files, this will need to be changed to
+# also push them (by changing the 0 to the number of additional files, and
+# providing the path of the additional files as the last arguments).
+EXECUTE = $(REMOTE_TEST_CLIENT) run 0 $(RUN_BINFILE)
+else
+EXECUTE = $(RUN_BINFILE)
+endif
+
# RUN and FAIL are basic way we will invoke the generated binary. On
# non-windows platforms, they set the LD_LIBRARY_PATH environment
# variable before running the binary.
@@ -50,16 +61,16 @@ BIN = $(1)
UNAME = $(shell uname)
ifeq ($(UNAME),Darwin)
-RUN = $(TARGET_RPATH_ENV) $(RUN_BINFILE)
-FAIL = $(TARGET_RPATH_ENV) $(RUN_BINFILE) && exit 1 || exit 0
+RUN = $(TARGET_RPATH_ENV) $(EXECUTE)
+FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0
DYLIB_GLOB = lib$(1)*.dylib
DYLIB = $(TMPDIR)/lib$(1).dylib
STATICLIB = $(TMPDIR)/lib$(1).a
STATICLIB_GLOB = lib$(1)*.a
else
ifdef IS_WINDOWS
-RUN = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(RUN_BINFILE)
-FAIL = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(RUN_BINFILE) && exit 1 || exit 0
+RUN = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE)
+FAIL = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE) && exit 1 || exit 0
DYLIB_GLOB = $(1)*.dll
DYLIB = $(TMPDIR)/$(1).dll
ifdef IS_MSVC
@@ -73,8 +84,8 @@ endif
BIN = $(1).exe
LLVM_FILECHECK := $(shell cygpath -u "$(LLVM_FILECHECK)")
else
-RUN = $(TARGET_RPATH_ENV) $(RUN_BINFILE)
-FAIL = $(TARGET_RPATH_ENV) $(RUN_BINFILE) && exit 1 || exit 0
+RUN = $(TARGET_RPATH_ENV) $(EXECUTE)
+FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0
DYLIB_GLOB = lib$(1)*.so
DYLIB = $(TMPDIR)/lib$(1).so
STATICLIB = $(TMPDIR)/lib$(1).a
diff --git a/src/test/run-make/coverage-reports/Makefile b/src/test/run-make/coverage-reports/Makefile
index 64b2f75ef..d06cd9c6a 100644
--- a/src/test/run-make/coverage-reports/Makefile
+++ b/src/test/run-make/coverage-reports/Makefile
@@ -132,7 +132,7 @@ endif
--instr-profile="$(TMPDIR)"/$@.profdata \
$(call BIN,"$(TMPDIR)"/$@) \
$$( \
- for file in $(TMPDIR)/rustdoc-$@/*/rust_out; do \
+ for file in $(TMPDIR)/rustdoc-$@/*/rust_out*; do \
[ -x "$$file" ] && printf "%s %s " -object $$file; \
done \
) \
diff --git a/src/test/run-make/coverage-reports/expected_show_coverage.async2.txt b/src/test/run-make/coverage-reports/expected_show_coverage.async2.txt
index dc06a485a..500dde1f2 100644
--- a/src/test/run-make/coverage-reports/expected_show_coverage.async2.txt
+++ b/src/test/run-make/coverage-reports/expected_show_coverage.async2.txt
@@ -72,7 +72,7 @@
67| | }
68| 2| }
------------------
- | async2::executor::block_on::<core::future::from_generator::GenFuture<async2::async_func::{closure#0}>>:
+ | async2::executor::block_on::<async2::async_func::{closure#0}>:
| 51| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output {
| 52| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
| 53| 1| use std::hint::unreachable_unchecked;
@@ -92,7 +92,7 @@
| 67| | }
| 68| 1| }
------------------
- | async2::executor::block_on::<core::future::from_generator::GenFuture<async2::async_func_just_println::{closure#0}>>:
+ | async2::executor::block_on::<async2::async_func_just_println::{closure#0}>:
| 51| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output {
| 52| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
| 53| 1| use std::hint::unreachable_unchecked;
diff --git a/src/test/run-make/emit-shared-files/Makefile b/src/test/run-make/emit-shared-files/Makefile
index 09b4c29c1..cad0c9e5b 100644
--- a/src/test/run-make/emit-shared-files/Makefile
+++ b/src/test/run-make/emit-shared-files/Makefile
@@ -23,24 +23,24 @@ invocation-only:
toolchain-only:
$(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx --extend-css z.css x.rs
- [ -e $(TOOLCHAIN_ONLY)/storage-xxx.js ]
- ! [ -e $(TOOLCHAIN_ONLY)/SourceSerif4-It.ttf.woff2 ]
+ [ -e $(TOOLCHAIN_ONLY)/static.files/storage-*.js ]
+ [ -e $(TOOLCHAIN_ONLY)/static.files/SourceSerif4-It-*.ttf.woff2 ]
! [ -e $(TOOLCHAIN_ONLY)/search-index-xxx.js ]
! [ -e $(TOOLCHAIN_ONLY)/x/index.html ]
! [ -e $(TOOLCHAIN_ONLY)/theme.css ]
- [ -e $(TOOLCHAIN_ONLY)/main-xxx.js ]
+ [ -e $(TOOLCHAIN_ONLY)/static.files/main-*.js ]
! [ -e $(TOOLCHAIN_ONLY)/y-xxx.css ]
all-shared:
$(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources,unversioned-shared-resources --output $(ALL_SHARED) --resource-suffix=-xxx --extend-css z.css x.rs
- [ -e $(ALL_SHARED)/storage-xxx.js ]
- [ -e $(ALL_SHARED)/SourceSerif4-It.ttf.woff2 ]
+ [ -e $(ALL_SHARED)/static.files/storage-*.js ]
+ [ -e $(ALL_SHARED)/static.files/SourceSerif4-It-*.ttf.woff2 ]
! [ -e $(ALL_SHARED)/search-index-xxx.js ]
! [ -e $(ALL_SHARED)/settings.html ]
! [ -e $(ALL_SHARED)/x ]
! [ -e $(ALL_SHARED)/src ]
! [ -e $(ALL_SHARED)/theme.css ]
- [ -e $(ALL_SHARED)/main-xxx.js ]
+ [ -e $(ALL_SHARED)/static.files/main-*.js ]
! [ -e $(ALL_SHARED)/y-xxx.css ]
diff --git a/src/test/run-make/issue-36710/Makefile b/src/test/run-make/issue-36710/Makefile
index 986a3f4e6..d6145c071 100644
--- a/src/test/run-make/issue-36710/Makefile
+++ b/src/test/run-make/issue-36710/Makefile
@@ -1,6 +1,7 @@
-# ignore-cross-compile $(call RUN,foo) expects to run the target executable natively
-# so it won't work with remote-test-server
# ignore-none no-std is not supported
+# ignore-wasm32 FIXME: don't attempt to compile C++ to WASM
+# ignore-wasm64 FIXME: don't attempt to compile C++ to WASM
+# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for `std`
# ignore-musl FIXME: this makefile needs teaching how to use a musl toolchain
# (see dist-i586-gnu-i586-i686-musl Dockerfile)
diff --git a/src/test/run-make/issue-88756-default-output/output-default.stdout b/src/test/run-make/issue-88756-default-output/output-default.stdout
index 80cd08ee1..b28069823 100644
--- a/src/test/run-make/issue-88756-default-output/output-default.stdout
+++ b/src/test/run-make/issue-88756-default-output/output-default.stdout
@@ -115,8 +115,6 @@ Options:
Provide width of the output for truncated error
messages
--json CONFIG Configure the structure of JSON diagnostics
- --disable-minification
- Disable minification applied on JS files
-A, --allow LINT Set lint allowed
-W, --warn LINT Set lint warnings
--force-warn LINT
@@ -173,6 +171,8 @@ Options:
--scrape-tests Include test code when scraping examples
--with-examples path to function call information (for displaying examples in the documentation)
+ --disable-minification
+ removed
--plugin-path DIR
removed, see issue #44136
<https://github.com/rust-lang/rust/issues/44136> for
diff --git a/src/test/run-make/macos-deployment-target/Makefile b/src/test/run-make/macos-deployment-target/Makefile
new file mode 100644
index 000000000..70fca0436
--- /dev/null
+++ b/src/test/run-make/macos-deployment-target/Makefile
@@ -0,0 +1,21 @@
+# only-macos
+#
+# Check that a set deployment target actually makes it to the linker.
+# This is important since its a compatibility hazard. The linker will
+# generate load commands differently based on what minimum OS it can assume.
+
+include ../../run-make-fulldeps/tools.mk
+
+ifeq ($(strip $(shell uname -m)),arm64)
+ GREP_PATTERN = "minos 11.0"
+else
+ GREP_PATTERN = "version 10.9"
+endif
+
+OUT_FILE=$(TMPDIR)/with_deployment_target.dylib
+all:
+ env MACOSX_DEPLOYMENT_TARGET=10.9 $(RUSTC) with_deployment_target.rs -o $(OUT_FILE)
+# XXX: The check is for either the x86_64 minimum OR the aarch64 minimum (M1 starts at macOS 11).
+# They also use different load commands, so we let that change with each too. The aarch64 check
+# isn't as robust as the x86 one, but testing both seems unneeded.
+ vtool -show-build $(OUT_FILE) | $(CGREP) -e $(GREP_PATTERN)
diff --git a/src/test/run-make/macos-deployment-target/with_deployment_target.rs b/src/test/run-make/macos-deployment-target/with_deployment_target.rs
new file mode 100644
index 000000000..342fe0ecb
--- /dev/null
+++ b/src/test/run-make/macos-deployment-target/with_deployment_target.rs
@@ -0,0 +1,4 @@
+#![crate_type = "cdylib"]
+
+#[allow(dead_code)]
+fn something_and_nothing() {}
diff --git a/src/test/run-make/native-link-modifier-verbatim-linker/Makefile b/src/test/run-make/native-link-modifier-verbatim-linker/Makefile
index e56e1e94e..666e4084c 100644
--- a/src/test/run-make/native-link-modifier-verbatim-linker/Makefile
+++ b/src/test/run-make/native-link-modifier-verbatim-linker/Makefile
@@ -6,10 +6,10 @@ include ../../run-make-fulldeps/tools.mk
all:
# Verbatim allows specify precise name.
$(RUSTC) local_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/local_some_strange_name.ext
- $(RUSTC) main.rs -Zunstable-options -l static:+verbatim=local_some_strange_name.ext
+ $(RUSTC) main.rs -l static:+verbatim=local_some_strange_name.ext
# With verbatim any other name cannot be used (local).
$(RUSTC) local_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/liblocal_native_dep.a
$(RUSTC) local_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/local_native_dep.a
$(RUSTC) local_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/local_native_dep.lib
- $(RUSTC) main.rs -Zunstable-options -l static:+verbatim=local_native_dep 2>&1 | $(CGREP) "local_native_dep"
+ $(RUSTC) main.rs -l static:+verbatim=local_native_dep 2>&1 | $(CGREP) "local_native_dep"
diff --git a/src/test/run-make/native-link-modifier-verbatim-rustc/Makefile b/src/test/run-make/native-link-modifier-verbatim-rustc/Makefile
index 1093b1cd3..6f01f3780 100644
--- a/src/test/run-make/native-link-modifier-verbatim-rustc/Makefile
+++ b/src/test/run-make/native-link-modifier-verbatim-rustc/Makefile
@@ -3,10 +3,10 @@ include ../../run-make-fulldeps/tools.mk
all:
# Verbatim allows specify precise name.
$(RUSTC) upstream_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/upstream_some_strange_name.ext
- $(RUSTC) rust_dep.rs -Zunstable-options -l static:+verbatim=upstream_some_strange_name.ext --crate-type rlib
+ $(RUSTC) rust_dep.rs -l static:+verbatim=upstream_some_strange_name.ext --crate-type rlib
# With verbatim any other name cannot be used (upstream).
$(RUSTC) upstream_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/libupstream_native_dep.a
$(RUSTC) upstream_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/upstream_native_dep.a
$(RUSTC) upstream_native_dep.rs --crate-type=staticlib -o $(TMPDIR)/upstream_native_dep.lib
- $(RUSTC) rust_dep.rs -Zunstable-options -l static:+verbatim=upstream_native_dep --crate-type rlib 2>&1 | $(CGREP) "upstream_native_dep"
+ $(RUSTC) rust_dep.rs -l static:+verbatim=upstream_native_dep --crate-type rlib 2>&1 | $(CGREP) "upstream_native_dep"
diff --git a/src/test/run-make/raw-dylib-c/lib.rs b/src/test/run-make/raw-dylib-c/lib.rs
index 005ffcdda..5fb120403 100644
--- a/src/test/run-make/raw-dylib-c/lib.rs
+++ b/src/test/run-make/raw-dylib-c/lib.rs
@@ -1,4 +1,4 @@
-#![feature(raw_dylib, native_link_modifiers_verbatim)]
+#![feature(raw_dylib)]
#[link(name = "extern_1.dll", kind = "raw-dylib", modifiers = "+verbatim")]
extern {
diff --git a/src/test/run-make/raw-dylib-import-name-type/driver.rs b/src/test/run-make/raw-dylib-import-name-type/driver.rs
index a38849fc8..9a3cd9ebe 100644
--- a/src/test/run-make/raw-dylib-import-name-type/driver.rs
+++ b/src/test/run-make/raw-dylib-import-name-type/driver.rs
@@ -3,6 +3,7 @@
#[link(name = "extern", kind = "raw-dylib", import_name_type = "undecorated")]
extern "C" {
+ fn LooksLikeAPrivateGlobal(i: i32);
fn cdecl_fn_undecorated(i: i32);
#[link_name = "cdecl_fn_undecorated2"]
fn cdecl_fn_undecorated_renamed(i: i32);
@@ -84,6 +85,13 @@ extern {
pub fn main() {
unsafe {
+ // Regression test for #104453
+ // On x86 LLVM uses 'L' as the prefix for private globals (PrivateGlobalPrefix), which
+ // causes it to believe that undecorated functions starting with 'L' are actually temporary
+ // symbols that it generated, which causes a later check to fail as the symbols we are
+ // creating don't have definitions (whereas all temporary symbols do).
+ LooksLikeAPrivateGlobal(13);
+
cdecl_fn_undecorated(1);
cdecl_fn_undecorated_renamed(10);
cdecl_fn_noprefix(2);
diff --git a/src/test/run-make/raw-dylib-import-name-type/extern.c b/src/test/run-make/raw-dylib-import-name-type/extern.c
index 195126d51..23c1e489e 100644
--- a/src/test/run-make/raw-dylib-import-name-type/extern.c
+++ b/src/test/run-make/raw-dylib-import-name-type/extern.c
@@ -1,6 +1,11 @@
#include <stdio.h>
#include <stdint.h>
+void _cdecl LooksLikeAPrivateGlobal(int i) {
+ printf("LooksLikeAPrivateGlobal(%d)\n", i);
+ fflush(stdout);
+}
+
void _cdecl cdecl_fn_undecorated(int i) {
printf("cdecl_fn_undecorated(%d)\n", i);
fflush(stdout);
diff --git a/src/test/run-make/raw-dylib-import-name-type/extern.gnu.def b/src/test/run-make/raw-dylib-import-name-type/extern.gnu.def
index a523c959a..498e90e86 100644
--- a/src/test/run-make/raw-dylib-import-name-type/extern.gnu.def
+++ b/src/test/run-make/raw-dylib-import-name-type/extern.gnu.def
@@ -1,5 +1,6 @@
LIBRARY extern
EXPORTS
+ LooksLikeAPrivateGlobal
cdecl_fn_undecorated
cdecl_fn_undecorated2
cdecl_fn_noprefix
diff --git a/src/test/run-make/raw-dylib-import-name-type/extern.msvc.def b/src/test/run-make/raw-dylib-import-name-type/extern.msvc.def
index dbff32d4c..cddb88bb8 100644
--- a/src/test/run-make/raw-dylib-import-name-type/extern.msvc.def
+++ b/src/test/run-make/raw-dylib-import-name-type/extern.msvc.def
@@ -1,5 +1,6 @@
LIBRARY extern
EXPORTS
+ LooksLikeAPrivateGlobal
cdecl_fn_undecorated
cdecl_fn_undecorated2
cdecl_fn_noprefix
diff --git a/src/test/run-make/raw-dylib-import-name-type/output.txt b/src/test/run-make/raw-dylib-import-name-type/output.txt
index 707faf403..a2a2bfeec 100644
--- a/src/test/run-make/raw-dylib-import-name-type/output.txt
+++ b/src/test/run-make/raw-dylib-import-name-type/output.txt
@@ -1,3 +1,4 @@
+LooksLikeAPrivateGlobal(13)
cdecl_fn_undecorated(1)
cdecl_fn_undecorated2(10)
cdecl_fn_noprefix(2)
diff --git a/src/test/run-make/repr128-dwarf/Makefile b/src/test/run-make/repr128-dwarf/Makefile
new file mode 100644
index 000000000..a840e3ee6
--- /dev/null
+++ b/src/test/run-make/repr128-dwarf/Makefile
@@ -0,0 +1,16 @@
+# ignore-windows
+# This test should be replaced with one in src/test/debuginfo once GDB or LLDB support 128-bit
+# enums.
+
+include ../../run-make-fulldeps/tools.mk
+
+all:
+ $(RUSTC) -Cdebuginfo=2 lib.rs -o $(TMPDIR)/repr128.rlib
+ "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
+ "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
+ "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 )"
+ "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )"
+ "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
+ "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )"
+ "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 )"
+ "$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 7f )"
diff --git a/src/test/run-make/repr128-dwarf/lib.rs b/src/test/run-make/repr128-dwarf/lib.rs
new file mode 100644
index 000000000..63675441d
--- /dev/null
+++ b/src/test/run-make/repr128-dwarf/lib.rs
@@ -0,0 +1,23 @@
+#![crate_type = "lib"]
+#![feature(repr128)]
+
+// Use .to_le() to ensure that the bytes are in the same order on both little- and big-endian
+// platforms.
+
+#[repr(u128)]
+pub enum U128Enum {
+ U128A = 0_u128.to_le(),
+ U128B = 1_u128.to_le(),
+ U128C = (u64::MAX as u128 + 1).to_le(),
+ U128D = u128::MAX.to_le(),
+}
+
+#[repr(i128)]
+pub enum I128Enum {
+ I128A = 0_i128.to_le(),
+ I128B = (-1_i128).to_le(),
+ I128C = i128::MIN.to_le(),
+ I128D = i128::MAX.to_le(),
+}
+
+pub fn f(_: U128Enum, _: I128Enum) {}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile b/src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile
new file mode 100644
index 000000000..4574cf17f
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile
@@ -0,0 +1,22 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# ignore-cross-compile
+
+# Make sure -Zpacked_bundled_libs is compatible with verbatim.
+
+# We're using the llvm-nm instead of the system nm to ensure it is compatible
+# with the LLVM bitcode generated by rustc.
+NM = "$(LLVM_BIN_DIR)"/llvm-nm
+
+all:
+ # Build strange-named dep.
+ $(RUSTC) native_dep.rs --crate-type=staticlib -o $(TMPDIR)/native_dep.ext
+
+ $(RUSTC) rust_dep.rs --crate-type=rlib -Zpacked_bundled_libs
+ $(NM) $(TMPDIR)/librust_dep.rlib | $(CGREP) -e "U.*native_f1"
+ $(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) "native_dep.ext"
+
+ # Make sure compiler doesn't use files, that it shouldn't know about.
+ rm $(TMPDIR)/native_dep.ext
+
+ $(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep.rlib -Zpacked_bundled_libs
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs b/src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs
new file mode 100644
index 000000000..8d2b8a285
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/main.rs
@@ -0,0 +1,5 @@
+extern crate rust_dep;
+
+pub fn main() {
+ rust_dep::rust_dep();
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs b/src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs
new file mode 100644
index 000000000..321a8237e
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/native_dep.rs
@@ -0,0 +1,4 @@
+#[no_mangle]
+pub fn native_f1() -> i32 {
+ return 1;
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs b/src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs
new file mode 100644
index 000000000..77e41e237
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs-2/rust_dep.rs
@@ -0,0 +1,10 @@
+#[link(name = "native_dep.ext", kind = "static", modifiers = "+verbatim")]
+extern "C" {
+ fn native_f1() -> i32;
+}
+
+pub fn rust_dep() {
+ unsafe {
+ assert!(native_f1() == 1);
+ }
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/Makefile b/src/test/run-make/rlib-format-packed-bundled-libs/Makefile
new file mode 100644
index 000000000..0b991ac42
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/Makefile
@@ -0,0 +1,34 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# ignore-cross-compile
+
+# Make sure rlib format with -Zpacked_bundled_libs is correct.
+
+# We're using the llvm-nm instead of the system nm to ensure it is compatible
+# with the LLVM bitcode generated by rustc.
+NM = "$(LLVM_BIN_DIR)"/llvm-nm
+
+all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3)
+ $(RUSTC) rust_dep_up.rs --crate-type=rlib -Zpacked_bundled_libs
+ $(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f2"
+ $(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f3"
+ $(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "T.*rust_dep_up"
+ $(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_2"
+ $(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_3"
+ $(RUSTC) rust_dep_local.rs --extern rlib=$(TMPDIR)/librust_dep_up.rlib -Zpacked_bundled_libs --crate-type=rlib
+ $(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "U.*native_f1"
+ $(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "T.*rust_dep_local"
+ $(AR) t $(TMPDIR)/librust_dep_local.rlib | $(CGREP) "native_dep_1"
+
+ # Make sure compiler doesn't use files, that it shouldn't know about.
+ rm $(TMPDIR)/*native_dep_*
+
+ $(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_local.rlib -o $(TMPDIR)/main.exe -Zpacked_bundled_libs --print link-args | $(CGREP) -e "native_dep_1.*native_dep_2.*native_dep_3"
+
+ifndef IS_MSVC
+ $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f1"
+ $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f2"
+ $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f3"
+ $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_local"
+ $(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_up"
+endif
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/main.rs b/src/test/run-make/rlib-format-packed-bundled-libs/main.rs
new file mode 100644
index 000000000..042a4879f
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/main.rs
@@ -0,0 +1,4 @@
+extern crate rust_dep_local;
+pub fn main() {
+ rust_dep_local::rust_dep_local();
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c
new file mode 100644
index 000000000..07be8562c
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_1.c
@@ -0,0 +1 @@
+int native_f1() { return 1; }
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c
new file mode 100644
index 000000000..a1b94e40d
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_2.c
@@ -0,0 +1 @@
+int native_f2() { return 2; }
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c
new file mode 100644
index 000000000..f81f397a4
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/native_dep_3.c
@@ -0,0 +1 @@
+int native_f3() { return 3; }
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs
new file mode 100644
index 000000000..8280c7d6c
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_local.rs
@@ -0,0 +1,13 @@
+#[link(name = "native_dep_1", kind = "static")]
+extern "C" {
+ fn native_f1() -> i32;
+}
+
+extern crate rust_dep_up;
+
+pub fn rust_dep_local() {
+ unsafe {
+ assert!(native_f1() == 1);
+ }
+ rust_dep_up::rust_dep_up();
+}
diff --git a/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs
new file mode 100644
index 000000000..edcd7c521
--- /dev/null
+++ b/src/test/run-make/rlib-format-packed-bundled-libs/rust_dep_up.rs
@@ -0,0 +1,13 @@
+#[link(name = "native_dep_2", kind = "static")]
+#[link(name = "native_dep_3", kind = "static")]
+extern "C" {
+ fn native_f2() -> i32;
+ fn native_f3() -> i32;
+}
+
+pub fn rust_dep_up() {
+ unsafe {
+ assert!(native_f2() == 2);
+ assert!(native_f3() == 3);
+ }
+}
diff --git a/src/test/run-make/rustdoc-verify-output-files/Makefile b/src/test/run-make/rustdoc-verify-output-files/Makefile
new file mode 100644
index 000000000..bfabbbc65
--- /dev/null
+++ b/src/test/run-make/rustdoc-verify-output-files/Makefile
@@ -0,0 +1,36 @@
+include ../../run-make-fulldeps/tools.mk
+
+OUTPUT_DIR := "$(TMPDIR)/rustdoc"
+TMP_OUTPUT_DIR := "$(TMPDIR)/tmp-rustdoc"
+
+all:
+ # Generate html docs
+ $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR)
+
+ # Copy first output for to check if it's exactly same after second compilation
+ cp -R $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)
+
+ # Generate html docs once again on same output
+ $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR)
+
+ # Check if everything exactly same
+ $(DIFF) -r -q $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)
+
+ # Generate json doc on the same output
+ $(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --out-dir $(OUTPUT_DIR) -Z unstable-options --output-format json
+
+ # Check if expected json file is generated
+ [ -e $(OUTPUT_DIR)/foobar.json ]
+
+ # TODO
+ # We should re-generate json doc once again and compare the diff with previously
+ # generated one. Because layout of json docs changes in each compilation, we can't
+ # do that currently.
+ #
+ # See https://github.com/rust-lang/rust/issues/103785#issuecomment-1307425590 for details.
+
+ # remove generated json doc
+ rm $(OUTPUT_DIR)/foobar.json
+
+ # Check if json doc compilation broke any of the html files generated previously
+ $(DIFF) -r -q $(OUTPUT_DIR) $(TMP_OUTPUT_DIR)
diff --git a/src/test/run-make/rustdoc-verify-output-files/src/lib.rs b/src/test/run-make/rustdoc-verify-output-files/src/lib.rs
new file mode 100644
index 000000000..5df757613
--- /dev/null
+++ b/src/test/run-make/rustdoc-verify-output-files/src/lib.rs
@@ -0,0 +1 @@
+// nothing to see here
diff --git a/src/test/run-make/test-benches/Makefile b/src/test/run-make/test-benches/Makefile
new file mode 100644
index 000000000..8fc122515
--- /dev/null
+++ b/src/test/run-make/test-benches/Makefile
@@ -0,0 +1,11 @@
+include ../../run-make-fulldeps/tools.mk
+
+# ignore-cross-compile
+
+all:
+ # Smoke-test that `#[bench]` isn't entirely broken.
+ $(RUSTC) --test smokebench.rs -O
+ $(call RUN,smokebench --bench)
+ $(call RUN,smokebench --bench noiter)
+ $(call RUN,smokebench --bench yesiter)
+ $(call RUN,smokebench)
diff --git a/src/test/run-make/test-benches/smokebench.rs b/src/test/run-make/test-benches/smokebench.rs
new file mode 100644
index 000000000..ef5e5a620
--- /dev/null
+++ b/src/test/run-make/test-benches/smokebench.rs
@@ -0,0 +1,14 @@
+#![feature(test)]
+extern crate test;
+
+#[bench]
+fn smoke_yesiter(b: &mut test::Bencher) {
+ let mut i = 0usize;
+ b.iter(|| {
+ i = i.wrapping_add(1);
+ i
+ })
+}
+
+#[bench]
+fn smoke_noiter(_: &mut test::Bencher) {}
diff --git a/src/test/run-make/translation/broken.ftl b/src/test/run-make/translation/broken.ftl
index 4e3585835..f1dd6ff0b 100644
--- a/src/test/run-make/translation/broken.ftl
+++ b/src/test/run-make/translation/broken.ftl
@@ -1,3 +1,3 @@
# `foo` isn't provided by this diagnostic so it is expected that the fallback message is used.
-parser_struct_literal_body_without_path = this is a {$foo} message
+parse_struct_literal_body_without_path = this is a {$foo} message
.suggestion = this is a test suggestion
diff --git a/src/test/run-make/translation/missing.ftl b/src/test/run-make/translation/missing.ftl
index 77bbda357..6be24dc7b 100644
--- a/src/test/run-make/translation/missing.ftl
+++ b/src/test/run-make/translation/missing.ftl
@@ -1,3 +1,3 @@
-# `parser_struct_literal_body_without_path` isn't provided by this resource at all, so the
+# `parse_struct_literal_body_without_path` isn't provided by this resource at all, so the
# fallback should be used.
foo = bar
diff --git a/src/test/run-make/translation/working.ftl b/src/test/run-make/translation/working.ftl
index d5ea86738..50d126e3f 100644
--- a/src/test/run-make/translation/working.ftl
+++ b/src/test/run-make/translation/working.ftl
@@ -1,2 +1,2 @@
-parser_struct_literal_body_without_path = this is a test message
+parse_struct_literal_body_without_path = this is a test message
.suggestion = this is a test suggestion
diff --git a/src/test/run-make/valid-print-requests/Makefile b/src/test/run-make/valid-print-requests/Makefile
new file mode 100644
index 000000000..c325e536e
--- /dev/null
+++ b/src/test/run-make/valid-print-requests/Makefile
@@ -0,0 +1,4 @@
+include ../../run-make-fulldeps/tools.mk
+
+all:
+ $(RUSTC) --print uwu 2>&1 | diff - valid-print-requests.stderr
diff --git a/src/test/run-make/valid-print-requests/valid-print-requests.stderr b/src/test/run-make/valid-print-requests/valid-print-requests.stderr
new file mode 100644
index 000000000..5191e4676
--- /dev/null
+++ b/src/test/run-make/valid-print-requests/valid-print-requests.stderr
@@ -0,0 +1,2 @@
+error: unknown print request `uwu`. Valid print requests are: `crate-name`, `file-names`, `sysroot`, `target-libdir`, `cfg`, `calling-conventions`, `target-list`, `target-cpus`, `target-features`, `relocation-models`, `code-models`, `tls-models`, `native-static-libs`, `stack-protector-strategies`, `target-spec-json`, `link-args`, `split-debuginfo`
+
diff --git a/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs b/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs
index 7f365ce2b..ece4dea9a 100644
--- a/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs
+++ b/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call.rs
@@ -1,7 +1,8 @@
#![feature(unsized_locals)]
#![feature(unboxed_closures)]
+#![feature(tuple_trait)]
-pub trait FnOnce<Args> {
+pub trait FnOnce<Args: std::marker::Tuple> {
type Output;
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}
diff --git a/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs b/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs
index a78b897d1..94df2b0b8 100644
--- a/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs
+++ b/src/test/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs
@@ -1,7 +1,8 @@
#![feature(unsized_locals)]
#![feature(unboxed_closures)]
+#![feature(tuple_trait)]
-pub trait FnOnce<Args> {
+pub trait FnOnce<Args: std::marker::Tuple> {
type Output;
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}
diff --git a/src/test/rustdoc-gui/basic.goml b/src/test/rustdoc-gui/basic.goml
deleted file mode 100644
index 60292835b..000000000
--- a/src/test/rustdoc-gui/basic.goml
+++ /dev/null
@@ -1,4 +0,0 @@
-goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
-assert: ("#functions")
-goto: "./struct.Foo.html"
-assert: ("div.item-decl")
diff --git a/src/test/rustdoc-gui/code-tags.goml b/src/test/rustdoc-gui/code-tags.goml
index 837a2c1d5..94c1a6525 100644
--- a/src/test/rustdoc-gui/code-tags.goml
+++ b/src/test/rustdoc-gui/code-tags.goml
@@ -1,4 +1,8 @@
// This test ensures that items and documentation code blocks are wrapped in <pre><code>
+
+// We need to disable this check because `implementors/test_docs/trait.AnotherOne.js`
+// doesn't exist.
+fail-on-request-error: false
goto: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
size: (1080, 600)
// There should be four doc codeblocks.
diff --git a/src/test/rustdoc-gui/codeblock-tooltip.goml b/src/test/rustdoc-gui/codeblock-tooltip.goml
index 8e681a2a0..4d923be3e 100644
--- a/src/test/rustdoc-gui/codeblock-tooltip.goml
+++ b/src/test/rustdoc-gui/codeblock-tooltip.goml
@@ -4,7 +4,7 @@ show-text: true
define-function: (
"check-colors",
- (theme),
+ (theme, background, color, border),
[
// Setting the theme.
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
@@ -30,6 +30,25 @@ define-function: (
".docblock .example-wrap.compile_fail",
{"border-left": "2px solid rgb(255, 0, 0)"},
)),
+ ("assert-css", (
+ ".docblock .example-wrap.compile_fail .tooltip::after",
+ {
+ "content": '"This example deliberately fails to compile"',
+ "text-align": "center",
+ "padding": "5px 3px 3px",
+ "background-color": |background|,
+ "color": |color|,
+ "border": "1px solid " + |border|,
+ },
+ )),
+ ("assert-css", (
+ ".docblock .example-wrap.compile_fail .tooltip::before",
+ {
+ "border-width": "5px",
+ "border-style": "solid",
+ "border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)",
+ },
+ )),
// should_panic block
("assert-css", (
@@ -51,6 +70,25 @@ define-function: (
".docblock .example-wrap.should_panic",
{"border-left": "2px solid rgb(255, 0, 0)"},
)),
+ ("assert-css", (
+ ".docblock .example-wrap.should_panic .tooltip::after",
+ {
+ "content": '"This example panics"',
+ "text-align": "center",
+ "padding": "5px 3px 3px",
+ "background-color": |background|,
+ "color": |color|,
+ "border": "1px solid " + |border|,
+ },
+ )),
+ ("assert-css", (
+ ".docblock .example-wrap.should_panic .tooltip::before",
+ {
+ "border-width": "5px",
+ "border-style": "solid",
+ "border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)",
+ },
+ )),
// ignore block
("assert-css", (
@@ -72,9 +110,43 @@ define-function: (
".docblock .example-wrap.ignore",
{"border-left": "2px solid rgb(255, 142, 0)"},
)),
+ ("assert-css", (
+ ".docblock .example-wrap.ignore .tooltip::after",
+ {
+ "content": '"This example is not tested"',
+ "text-align": "center",
+ "padding": "5px 3px 3px",
+ "background-color": |background|,
+ "color": |color|,
+ "border": "1px solid " + |border|,
+ },
+ )),
+ ("assert-css", (
+ ".docblock .example-wrap.ignore .tooltip::before",
+ {
+ "border-width": "5px",
+ "border-style": "solid",
+ "border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)",
+ },
+ )),
],
)
-call-function: ("check-colors", ("ayu"))
-call-function: ("check-colors", ("dark"))
-call-function: ("check-colors", ("light"))
+call-function: ("check-colors", {
+ "theme": "ayu",
+ "background": "rgb(49, 69, 89)",
+ "color": "rgb(197, 197, 197)",
+ "border": "rgb(92, 103, 115)",
+})
+call-function: ("check-colors", {
+ "theme": "dark",
+ "background": "rgb(0, 0, 0)",
+ "color": "rgb(255, 255, 255)",
+ "border": "rgb(224, 224, 224)",
+})
+call-function: ("check-colors", {
+ "theme": "light",
+ "background": "rgb(0, 0, 0)",
+ "color": "rgb(255, 255, 255)",
+ "border": "rgb(224, 224, 224)",
+})
diff --git a/src/test/rustdoc-gui/cursor.goml b/src/test/rustdoc-gui/cursor.goml
new file mode 100644
index 000000000..b2e91cb81
--- /dev/null
+++ b/src/test/rustdoc-gui/cursor.goml
@@ -0,0 +1,24 @@
+// This test ensures that several clickable items actually have the pointer cursor.
+goto: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html"
+
+// the `[+]/[-]` button
+assert-css: ("#toggle-all-docs", {"cursor": "pointer"})
+
+// the button next to the path header
+assert-css: ("#copy-path", {"cursor": "pointer"})
+
+// the search tabs
+write: (".search-input", "Foo")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+// Waiting for the search results to appear...
+wait-for: "#titles"
+assert-css: ("#titles > button", {"cursor": "pointer"})
+
+// mobile sidebar toggle button
+size: (500, 700)
+assert-css: (".sidebar-menu-toggle", {"cursor": "pointer"})
+
+// the sidebar toggle button on the source code pages
+goto: "file://" + |DOC_PATH| + "/src/lib2/lib.rs.html"
+assert-css: ("#sidebar-toggle > button", {"cursor": "pointer"})
diff --git a/src/test/rustdoc-gui/docblock-code-block-line-number.goml b/src/test/rustdoc-gui/docblock-code-block-line-number.goml
index 911ee34be..fec21ad35 100644
--- a/src/test/rustdoc-gui/docblock-code-block-line-number.goml
+++ b/src/test/rustdoc-gui/docblock-code-block-line-number.goml
@@ -30,10 +30,10 @@ wait-for: "#settings"
assert-css: ("#settings", {"display": "block"})
// Then, click the toggle button.
-click: "input#line-numbers + .slider"
+click: "input#line-numbers"
wait-for: 100 // wait-for-false does not exist
assert-false: "pre.example-line-numbers"
// Finally, turn it on again.
-click: "input#line-numbers + .slider"
+click: "input#line-numbers"
wait-for: "pre.example-line-numbers"
diff --git a/src/test/rustdoc-gui/docblock-table.goml b/src/test/rustdoc-gui/docblock-table.goml
index 4e316ce0b..8645c1b19 100644
--- a/src/test/rustdoc-gui/docblock-table.goml
+++ b/src/test/rustdoc-gui/docblock-table.goml
@@ -2,3 +2,50 @@ goto: "file://" + |DOC_PATH| + "/test_docs/doc_block_table/struct.DocBlockTable.
compare-elements-css: (".impl-items .docblock table th", ".top-doc .docblock table th", ["border"])
compare-elements-css: (".impl-items .docblock table td", ".top-doc .docblock table td", ["border"])
+
+define-function: (
+ "check-colors",
+ (theme, border_color, zebra_stripe_color),
+ [
+ ("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}),
+ ("reload"),
+ ("assert-css", (".top-doc .docblock table tbody tr:nth-child(1)", {
+ "background-color": "rgba(0, 0, 0, 0)",
+ })),
+ ("assert-css", (".top-doc .docblock table tbody tr:nth-child(2)", {
+ "background-color": |zebra_stripe_color|,
+ })),
+ ("assert-css", (".top-doc .docblock table tbody tr:nth-child(3)", {
+ "background-color": "rgba(0, 0, 0, 0)",
+ })),
+ ("assert-css", (".top-doc .docblock table tbody tr:nth-child(4)", {
+ "background-color": |zebra_stripe_color|,
+ })),
+ ("assert-css", (".top-doc .docblock table td", {
+ "border-style": "solid",
+ "border-width": "1px",
+ "border-color": |border_color|,
+ })),
+ ("assert-css", (".top-doc .docblock table th", {
+ "border-style": "solid",
+ "border-width": "1px",
+ "border-color": |border_color|,
+ })),
+ ]
+)
+
+call-function: ("check-colors", {
+ "theme": "dark",
+ "border_color": "rgb(224, 224, 224)",
+ "zebra_stripe_color": "rgb(42, 42, 42)",
+})
+call-function: ("check-colors", {
+ "theme": "ayu",
+ "border_color": "rgb(92, 103, 115)",
+ "zebra_stripe_color": "rgb(25, 31, 38)",
+})
+call-function: ("check-colors", {
+ "theme": "light",
+ "border_color": "rgb(224, 224, 224)",
+ "zebra_stripe_color": "rgb(245, 245, 245)",
+})
diff --git a/src/test/rustdoc-gui/enum-variants.goml b/src/test/rustdoc-gui/enum-variants.goml
new file mode 100644
index 000000000..8dfc49285
--- /dev/null
+++ b/src/test/rustdoc-gui/enum-variants.goml
@@ -0,0 +1,10 @@
+// Verifies that there is non-zero margin on variants and their docblocks.
+goto: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
+
+assert-css: (".variants > .variant", {"margin": "0px 0px 12px"})
+assert-css: (".variants > .docblock", {"margin": "0px 0px 32px 24px"})
+
+assert-css: (
+ "details.non-exhaustive > summary",
+ {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
+)
diff --git a/src/test/rustdoc-gui/help-page.goml b/src/test/rustdoc-gui/help-page.goml
index 521e14748..799ba851c 100644
--- a/src/test/rustdoc-gui/help-page.goml
+++ b/src/test/rustdoc-gui/help-page.goml
@@ -3,6 +3,7 @@ goto: "file://" + |DOC_PATH| + "/help.html"
size: (1000, 1000) // Try desktop size first.
wait-for: "#help"
assert-css: ("#help", {"display": "block"})
+assert-css: ("#help dd", {"font-size": "16px"})
click: "#help-button > a"
assert-css: ("#help", {"display": "block"})
compare-elements-property: (".sub", "#help", ["offsetWidth"])
@@ -12,12 +13,51 @@ assert-css: ("#help", {"display": "block"})
compare-elements-property: (".sub", "#help", ["offsetWidth"])
compare-elements-position: (".sub", "#help", ("x"))
+// Checking the color of the elements of the help menu.
+show-text: true
+define-function: (
+ "check-colors",
+ (theme, color, background, box_shadow),
+ [
+ // Setting the theme.
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ // We reload the page so the local storage settings are being used.
+ ("reload"),
+ ("assert-css", ("#help kbd", {
+ "color": |color|,
+ "background-color": |background|,
+ "box-shadow": |box_shadow| + " 0px -1px 0px 0px inset",
+ "cursor": "default",
+ }, ALL)),
+ ],
+)
+
+call-function: ("check-colors", {
+ "theme": "ayu",
+ "color": "rgb(197, 197, 197)",
+ "background": "rgb(49, 69, 89)",
+ "box_shadow": "rgb(92, 103, 115)",
+})
+call-function: ("check-colors", {
+ "theme": "dark",
+ "color": "rgb(221, 221, 221)",
+ "background": "rgb(250, 251, 252)",
+ "box_shadow": "rgb(198, 203, 209)",
+})
+call-function: ("check-colors", {
+ "theme": "light",
+ "color": "rgb(0, 0, 0)",
+ "background": "rgb(250, 251, 252)",
+ "box_shadow": "rgb(198, 203, 209)",
+})
+
// This test ensures that opening the help popover without switching pages works.
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
size: (1000, 1000) // Only supported on desktop.
assert-false: "#help"
click: "#help-button > a"
assert-css: ("#help", {"display": "block"})
+assert-css: ("#help dd", {"font-size": "16px"})
click: "#help-button > a"
assert-css: ("#help", {"display": "none"})
compare-elements-property-false: (".sub", "#help", ["offsetWidth"])
diff --git a/src/test/rustdoc-gui/highlight-colors.goml b/src/test/rustdoc-gui/highlight-colors.goml
index 51693314e..ff1be389d 100644
--- a/src/test/rustdoc-gui/highlight-colors.goml
+++ b/src/test/rustdoc-gui/highlight-colors.goml
@@ -15,7 +15,7 @@ define-function: (
string,
bool_val,
self,
- attribute,
+ attr,
macro,
question_mark,
comment,
@@ -33,7 +33,7 @@ define-function: (
("assert-css", ("pre.rust .string", {"color": |string|}, ALL)),
("assert-css", ("pre.rust .bool-val", {"color": |bool_val|}, ALL)),
("assert-css", ("pre.rust .self", {"color": |self|}, ALL)),
- ("assert-css", ("pre.rust .attribute", {"color": |attribute|}, ALL)),
+ ("assert-css", ("pre.rust .attr", {"color": |attr|}, ALL)),
("assert-css", ("pre.rust .macro", {"color": |macro|}, ALL)),
("assert-css", ("pre.rust .question-mark", {"color": |question_mark|}, ALL)),
("assert-css", ("pre.rust .comment", {"color": |comment|}, ALL)),
@@ -52,7 +52,7 @@ call-function: ("check-colors", {
"string": "rgb(184, 204, 82)",
"bool_val": "rgb(255, 119, 51)",
"self": "rgb(54, 163, 217)",
- "attribute": "rgb(230, 225, 207)",
+ "attr": "rgb(230, 225, 207)",
"macro": "rgb(163, 122, 204)",
"question_mark": "rgb(255, 144, 17)",
"comment": "rgb(120, 135, 151)",
@@ -69,7 +69,7 @@ call-function: ("check-colors", {
"string": "rgb(131, 163, 0)",
"bool_val": "rgb(238, 104, 104)",
"self": "rgb(238, 104, 104)",
- "attribute": "rgb(238, 104, 104)",
+ "attr": "rgb(238, 104, 104)",
"macro": "rgb(62, 153, 159)",
"question_mark": "rgb(255, 144, 17)",
"comment": "rgb(141, 141, 139)",
@@ -86,7 +86,7 @@ call-function: ("check-colors", {
"string": "rgb(113, 140, 0)",
"bool_val": "rgb(200, 40, 41)",
"self": "rgb(200, 40, 41)",
- "attribute": "rgb(200, 40, 41)",
+ "attr": "rgb(200, 40, 41)",
"macro": "rgb(62, 153, 159)",
"question_mark": "rgb(255, 144, 17)",
"comment": "rgb(142, 144, 140)",
diff --git a/src/test/rustdoc-gui/huge-logo.goml b/src/test/rustdoc-gui/huge-logo.goml
new file mode 100644
index 000000000..01f06771c
--- /dev/null
+++ b/src/test/rustdoc-gui/huge-logo.goml
@@ -0,0 +1,21 @@
+// huge_logo crate has a custom 712x860 logo
+// test to ensure the maximum size in the layout works correctly
+goto: "file://" + |DOC_PATH| + "/huge_logo/index.html"
+
+size: (1280, 1024)
+// offsetWidth = width of sidebar
+assert-property: (".sidebar .logo-container", {"offsetWidth": "200", "offsetHeight": 100})
+assert-property: (".sidebar .logo-container img", {"offsetWidth": "100", "offsetHeight": 100})
+
+size: (400, 600)
+// offset = size + margin
+assert-property: (".mobile-topbar .logo-container", {"offsetWidth": "55", "offsetHeight": 45})
+assert-property: (".mobile-topbar .logo-container img", {"offsetWidth": "35", "offsetHeight": 35})
+
+goto: "file://" + |DOC_PATH| + "/src/huge_logo/lib.rs.html"
+
+size: (1280, 1024)
+assert-property: (".sub-logo-container", {"offsetWidth": "60", "offsetHeight": 60})
+
+size: (400, 600)
+assert-property: (".sub-logo-container", {"offsetWidth": "35", "offsetHeight": 35})
diff --git a/src/test/rustdoc-gui/item-decl-colors.goml b/src/test/rustdoc-gui/item-decl-colors.goml
index ce688287a..2e07f19b1 100644
--- a/src/test/rustdoc-gui/item-decl-colors.goml
+++ b/src/test/rustdoc-gui/item-decl-colors.goml
@@ -1,4 +1,9 @@
// This test ensures that the color of the items in the type decl are working as expected.
+
+// We need to disable this check because `implementors/test_docs/trait.TraitWithoutGenerics.js`
+// doesn't exist.
+fail-on-request-error: false
+
define-function: (
"check-colors",
(
@@ -25,7 +30,7 @@ define-function: (
("assert-css", (".item-decl .primitive", {"color": |primitive_color|}, ALL)),
("goto", "file://" + |DOC_PATH| + "/test_docs/trait.TraitWithoutGenerics.html"),
("assert-css", (".item-decl .constant", {"color": |constant_color|}, ALL)),
- ("assert-css", (".item-decl .fnname", {"color": |fn_color|}, ALL)),
+ ("assert-css", (".item-decl .fn", {"color": |fn_color|}, ALL)),
("assert-css", (".item-decl .associatedtype", {"color": |assoc_type_color|}, ALL)),
],
)
diff --git a/src/test/rustdoc-gui/method-margins.goml b/src/test/rustdoc-gui/method-margins.goml
new file mode 100644
index 000000000..ed36bcdec
--- /dev/null
+++ b/src/test/rustdoc-gui/method-margins.goml
@@ -0,0 +1,18 @@
+// This test ensures that the margins on methods are coherent inside an impl block.
+goto: "file://" + |DOC_PATH| + "/test_docs/trait_members/struct.HasTrait.html#impl-TraitMembers-for-HasTrait"
+
+assert-count: ("#trait-implementations-list > .rustdoc-toggle", 1)
+
+compare-elements-css: (
+ // compare margin on type with margin on method
+ "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(1) > summary",
+ "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(2) > summary",
+ ["margin"]
+)
+
+compare-elements-css: (
+ // compare margin on type with margin on method
+ "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(1)",
+ "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(2)",
+ ["margin"]
+)
diff --git a/src/test/rustdoc-gui/no-docblock.goml b/src/test/rustdoc-gui/no-docblock.goml
index 2366a60f5..17a955064 100644
--- a/src/test/rustdoc-gui/no-docblock.goml
+++ b/src/test/rustdoc-gui/no-docblock.goml
@@ -1,4 +1,9 @@
// This test checks that there are margins applied to methods with no docblocks.
+
+// We need to disable this check because `implementors/test_docs/trait.TraitWithNoDocblock.js`
+// doesn't exist.
+fail-on-request-error: false
+
goto: "file://" + |DOC_PATH| + "/test_docs/trait.TraitWithNoDocblocks.html"
// Check that the two methods are more than 24px apart.
compare-elements-position-near-false: ("//*[@id='tymethod.first_fn']", "//*[@id='tymethod.second_fn']", {"y": 24})
diff --git a/src/test/rustdoc-gui/notable-trait.goml b/src/test/rustdoc-gui/notable-trait.goml
index efe0cb15f..7d4bd27d4 100644
--- a/src/test/rustdoc-gui/notable-trait.goml
+++ b/src/test/rustdoc-gui/notable-trait.goml
@@ -22,25 +22,26 @@ assert-position: (
)
assert-position: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- {"x": 951},
+ {"x": 955},
)
-// The tooltip should be beside the `i`
+// The tooltip should be below the `i`
+// Also, clicking the tooltip should bring its text into the DOM
+assert-count: ("//*[@class='notable popover']", 0)
click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+assert-count: ("//*[@class='notable popover']", 1)
compare-elements-position-near: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
- {"y": 2}
+ "//*[@class='notable popover']",
+ {"y": 30}
)
compare-elements-position-false: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
+ "//*[@class='notable popover']",
("x")
)
-// The docblock should be flush with the border.
-assert-css: (
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']/*[@class='docblock']",
- {"margin-left": "0px"}
-)
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+move-cursor-to: "//h1"
+assert-count: ("//*[@class='notable popover']", 0)
// Now only the `i` should be on the next line.
size: (1055, 600)
@@ -71,7 +72,7 @@ assert-position: (
)
assert-position: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- {"x": 519},
+ {"x": 523},
)
// Checking on mobile now.
@@ -95,34 +96,181 @@ assert-position: (
)
assert-position: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- {"x": 289},
+ {"x": 293},
)
-// The tooltip should be below `i`
-compare-elements-position-near-false: (
+// The tooltip should STILL be below `i`
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+assert-count: ("//*[@class='notable popover']", 1)
+compare-elements-position-near: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
- {"y": 2}
+ "//*[@class='notable popover']",
+ {"y": 30}
)
compare-elements-position-false: (
"//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
+ "//*[@class='notable popover']",
("x")
)
-compare-elements-position-near: (
- "//*[@id='method.create_an_iterator_from_read']/parent::*",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']",
- {"x": 5}
+assert-position: (
+ "//*[@class='notable popover']",
+ {"x": 0}
)
-// The docblock should be flush with the border.
-assert-css: (
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits-tooltiptext force-tooltip']/*[@class='docblock']",
- {"margin-left": "0px"}
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+move-cursor-to: "//h1"
+assert-count: ("//*[@class='notable popover']", 0)
+
+// Now check the colors.
+define-function: (
+ "check-colors",
+ (theme, header_color, content_color, type_color, trait_color),
+ [
+ ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html"),
+ // This is needed to ensure that the text color is computed.
+ ("show-text", true),
+
+ // Setting the theme.
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ // We reload the page so the local storage settings are being used.
+ ("reload"),
+
+ ("move-cursor-to", "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"),
+ ("assert-count", (".notable.popover", 1)),
+
+ ("assert-css", (
+ ".notable.popover h3",
+ {"color": |header_color|},
+ ALL,
+ )),
+ ("assert-css", (
+ ".notable.popover pre",
+ {"color": |content_color|},
+ ALL,
+ )),
+ ("assert-css", (
+ ".notable.popover pre a.struct",
+ {"color": |type_color|},
+ ALL,
+ )),
+ ("assert-css", (
+ ".notable.popover pre a.trait",
+ {"color": |trait_color|},
+ ALL,
+ )),
+ ]
)
-// Checking on very small mobile. The `i` should be on its own line.
-size: (365, 600)
-compare-elements-position-false: (
- "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']",
- "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']",
- ("y", "x"),
+call-function: (
+ "check-colors",
+ {
+ "theme": "ayu",
+ "content_color": "rgb(230, 225, 207)",
+ "header_color": "rgb(255, 255, 255)",
+ "type_color": "rgb(255, 160, 165)",
+ "trait_color": "rgb(57, 175, 215)",
+ },
+)
+
+call-function: (
+ "check-colors",
+ {
+ "theme": "dark",
+ "content_color": "rgb(221, 221, 221)",
+ "header_color": "rgb(221, 221, 221)",
+ "type_color": "rgb(45, 191, 184)",
+ "trait_color": "rgb(183, 140, 242)",
+ },
+)
+
+call-function: (
+ "check-colors",
+ {
+ "theme": "light",
+ "content_color": "rgb(0, 0, 0)",
+ "header_color": "rgb(0, 0, 0)",
+ "type_color": "rgb(173, 55, 138)",
+ "trait_color": "rgb(110, 79, 201)",
+ },
)
+
+reload:
+
+// Check that pressing escape works
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+move-cursor-to: "//*[@class='notable popover']"
+assert-count: ("//*[@class='notable popover']", 1)
+press-key: "Escape"
+assert-count: ("//*[@class='notable popover']", 0)
+assert: "#method\.create_an_iterator_from_read .notable-traits:focus"
+
+// Check that clicking outside works.
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+assert-count: ("//*[@class='notable popover']", 1)
+click: ".search-input"
+assert-count: ("//*[@class='notable popover']", 0)
+assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus"
+
+// Check that pressing tab over and over works.
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+move-cursor-to: "//*[@class='notable popover']"
+assert-count: ("//*[@class='notable popover']", 1)
+press-key: "Tab"
+press-key: "Tab"
+press-key: "Tab"
+press-key: "Tab"
+press-key: "Tab"
+press-key: "Tab"
+press-key: "Tab"
+assert-count: ("//*[@class='notable popover']", 0)
+assert: "#method\.create_an_iterator_from_read .notable-traits:focus"
+
+// Now we check that the focus isn't given back to the wrong item when opening
+// another popover.
+store-window-property: (scroll, "scrollY")
+click: "#method\.create_an_iterator_from_read .fn"
+// We ensure that the scroll position changed.
+assert-window-property-false: {"scrollY": |scroll|}
+// Store the new position.
+store-window-property: (scroll, "scrollY")
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+wait-for: "//*[@class='notable popover']"
+click: "#settings-menu a"
+click: ".search-input"
+// We ensure we didn't come back to the previous focused item.
+assert-window-property-false: {"scrollY": |scroll|}
+
+// Same but with Escape handling.
+store-window-property: (scroll, "scrollY")
+click: "#method\.create_an_iterator_from_read .fn"
+// We ensure that the scroll position changed.
+assert-window-property-false: {"scrollY": |scroll|}
+// Store the new position.
+store-window-property: (scroll, "scrollY")
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+wait-for: "//*[@class='notable popover']"
+click: "#settings-menu a"
+press-key: "Escape"
+// We ensure we didn't come back to the previous focused item.
+assert-window-property-false: {"scrollY": |scroll|}
+
+// Opening the mobile sidebar should close the popover.
+size: (650, 600)
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+assert-count: ("//*[@class='notable popover']", 1)
+click: ".sidebar-menu-toggle"
+assert: "//*[@class='sidebar shown']"
+assert-count: ("//*[@class='notable popover']", 0)
+assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus"
+// Clicking a notable popover should close the sidebar.
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+assert-count: ("//*[@class='notable popover']", 1)
+assert-false: "//*[@class='sidebar shown']"
+
+// Also check the focus handling for the help button.
+size: (1100, 600)
+reload:
+assert-count: ("//*[@class='notable popover']", 0)
+click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"
+assert-count: ("//*[@class='notable popover']", 1)
+click: "#help-button a"
+assert-count: ("//*[@class='notable popover']", 0)
+assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus"
diff --git a/src/test/rustdoc-gui/pocket-menu.goml b/src/test/rustdoc-gui/pocket-menu.goml
index fb63ea62a..c3649dc7b 100644
--- a/src/test/rustdoc-gui/pocket-menu.goml
+++ b/src/test/rustdoc-gui/pocket-menu.goml
@@ -75,3 +75,24 @@ assert-css: (
)
compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
+
+// Opening the mobile sidebar should close the settings popover.
+size: (650, 600)
+click: "#settings-menu a"
+assert-css: ("#settings-menu .popover", {"display": "block"})
+click: ".sidebar-menu-toggle"
+assert: "//*[@class='sidebar shown']"
+assert-css: ("#settings-menu .popover", {"display": "none"})
+// Opening the settings popover should close the sidebar.
+click: "#settings-menu a"
+assert-css: ("#settings-menu .popover", {"display": "block"})
+assert-false: "//*[@class='sidebar shown']"
+
+// Opening the settings popover at start (which async loads stuff) should also close.
+reload:
+click: ".sidebar-menu-toggle"
+assert: "//*[@class='sidebar shown']"
+assert-false: "#settings-menu .popover"
+click: "#settings-menu a"
+assert-false: "//*[@class='sidebar shown']"
+wait-for: "#settings-menu .popover"
diff --git a/src/test/rustdoc-gui/run-on-hover.goml b/src/test/rustdoc-gui/run-on-hover.goml
index 6c785e1c4..57d63049f 100644
--- a/src/test/rustdoc-gui/run-on-hover.goml
+++ b/src/test/rustdoc-gui/run-on-hover.goml
@@ -1,7 +1,54 @@
// Example code blocks sometimes have a "Run" button to run them on the
// Playground. That button is hidden until the user hovers over the code block.
-// This test checks that it is hidden, and that it shows on hover.
+// This test checks that it is hidden, and that it shows on hover. It also
+// checks for its color.
goto: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
-assert-css: (".test-arrow", {"visibility": "hidden"})
-move-cursor-to: ".example-wrap"
-assert-css: (".test-arrow", {"visibility": "visible"})
+show-text: true
+
+define-function: (
+ "check-run-button",
+ (theme, color, background, hover_color, hover_background),
+ [
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ ("reload"),
+ ("assert-css", (".test-arrow", {"visibility": "hidden"})),
+ ("move-cursor-to", ".example-wrap"),
+ ("assert-css", (".test-arrow", {
+ "visibility": "visible",
+ "color": |color|,
+ "background-color": |background|,
+ "font-size": "22px",
+ "border-radius": "5px",
+ })),
+ ("move-cursor-to", ".test-arrow"),
+ ("assert-css", (".test-arrow:hover", {
+ "visibility": "visible",
+ "color": |hover_color|,
+ "background-color": |hover_background|,
+ "font-size": "22px",
+ "border-radius": "5px",
+ })),
+ ],
+)
+
+call-function: ("check-run-button", {
+ "theme": "ayu",
+ "color": "rgb(120, 135, 151)",
+ "background": "rgba(57, 175, 215, 0.09)",
+ "hover_color": "rgb(197, 197, 197)",
+ "hover_background": "rgba(57, 175, 215, 0.37)",
+})
+call-function: ("check-run-button", {
+ "theme": "dark",
+ "color": "rgb(222, 222, 222)",
+ "background": "rgba(78, 139, 202, 0.2)",
+ "hover_color": "rgb(222, 222, 222)",
+ "hover_background": "rgb(78, 139, 202)",
+})
+call-function: ("check-run-button", {
+ "theme": "light",
+ "color": "rgb(245, 245, 245)",
+ "background": "rgba(78, 139, 202, 0.2)",
+ "hover_color": "rgb(245, 245, 245)",
+ "hover_background": "rgb(78, 139, 202)",
+})
diff --git a/src/test/rustdoc-gui/rust-logo.goml b/src/test/rustdoc-gui/rust-logo.goml
index 6c8dc8594..816cc9abd 100644
--- a/src/test/rustdoc-gui/rust-logo.goml
+++ b/src/test/rustdoc-gui/rust-logo.goml
@@ -17,6 +17,15 @@ define-function: (
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
("reload"),
("assert-css", (".rust-logo", {"filter": |filter|})),
+ // Now we check that the non-rust logos don't have a CSS filter set.
+ ("goto", "file://" + |DOC_PATH| + "/huge_logo/index.html"),
+ // Changing theme on the new page (again...).
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ ("reload"),
+ // Check there is no rust logo
+ ("assert-false", ".rust-logo"),
+ // Check there is no filter.
+ ("assert-css", (".sidebar .logo-container img", {"filter": "none"})),
],
)
diff --git a/src/test/rustdoc-gui/scrape-examples-button-focus.goml b/src/test/rustdoc-gui/scrape-examples-button-focus.goml
new file mode 100644
index 000000000..bba518db0
--- /dev/null
+++ b/src/test/rustdoc-gui/scrape-examples-button-focus.goml
@@ -0,0 +1,29 @@
+goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html"
+
+// The next/prev buttons vertically scroll the code viewport between examples
+store-property: (initialScrollTop, ".scraped-example-list > .scraped-example pre", "scrollTop")
+focus: ".scraped-example-list > .scraped-example .next"
+press-key: "Enter"
+assert-property-false: (".scraped-example-list > .scraped-example pre", {
+ "scrollTop": |initialScrollTop|
+})
+focus: ".scraped-example-list > .scraped-example .prev"
+press-key: "Enter"
+assert-property: (".scraped-example-list > .scraped-example pre", {
+ "scrollTop": |initialScrollTop|
+})
+
+// The expand button increases the scrollHeight of the minimized code viewport
+store-property: (smallOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
+assert-property-false: (".scraped-example-list > .scraped-example pre", {
+ "scrollHeight": |smallOffsetHeight|
+})
+focus: ".scraped-example-list > .scraped-example .expand"
+press-key: "Enter"
+assert-property-false: (".scraped-example-list > .scraped-example pre", {
+ "offsetHeight": |smallOffsetHeight|
+})
+store-property: (fullOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
+assert-property: (".scraped-example-list > .scraped-example pre", {
+ "scrollHeight": |fullOffsetHeight|
+})
diff --git a/src/test/rustdoc-gui/scrape-examples-fonts.goml b/src/test/rustdoc-gui/scrape-examples-fonts.goml
new file mode 100644
index 000000000..b7d7f4ccb
--- /dev/null
+++ b/src/test/rustdoc-gui/scrape-examples-fonts.goml
@@ -0,0 +1,8 @@
+goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
+
+store-value: (font, '"Fira Sans", Arial, NanumBarunGothic, sans-serif')
+
+wait-for-css: (".scraped-example-title", {"font-family": |font|})
+wait-for-css: (".more-examples-toggle summary", {"font-family": |font|})
+wait-for-css: (".more-examples-toggle .hide-more", {"font-family": |font|})
+wait-for-css: (".example-links a", {"font-family": |font|})
diff --git a/src/test/rustdoc-gui/scrape-examples-toggle.goml b/src/test/rustdoc-gui/scrape-examples-toggle.goml
new file mode 100644
index 000000000..ee720afb7
--- /dev/null
+++ b/src/test/rustdoc-gui/scrape-examples-toggle.goml
@@ -0,0 +1,14 @@
+goto: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
+
+// Clicking "More examples..." will open additional examples
+assert-attribute-false: (".more-examples-toggle", {"open": ""})
+click: ".more-examples-toggle"
+assert-attribute: (".more-examples-toggle", {"open": ""})
+
+// Toggling all docs will close additional examples
+click: "#toggle-all-docs"
+assert-attribute-false: (".more-examples-toggle", {"open": ""})
+
+// After re-opening the docs, the additional examples should stay closed
+click: "#toggle-all-docs"
+assert-attribute-false: (".more-examples-toggle", {"open": ""})
diff --git a/src/test/rustdoc-gui/search-filter.goml b/src/test/rustdoc-gui/search-filter.goml
index 27db816e6..e0228694e 100644
--- a/src/test/rustdoc-gui/search-filter.goml
+++ b/src/test/rustdoc-gui/search-filter.goml
@@ -14,6 +14,7 @@ click: "#crate-search"
// We select "lib2" option then press enter to change the filter.
press-key: "ArrowDown"
press-key: "ArrowDown"
+press-key: "ArrowDown"
press-key: "Enter"
// Waiting for the search results to appear...
wait-for: "#titles"
@@ -37,6 +38,7 @@ assert-property: ("#crate-search", {"value": "lib2"})
click: "#crate-search"
press-key: "ArrowUp"
press-key: "ArrowUp"
+press-key: "ArrowUp"
press-key: "Enter"
// Waiting for the search results to appear...
wait-for: "#titles"
diff --git a/src/test/rustdoc-gui/search-keyboard.goml b/src/test/rustdoc-gui/search-keyboard.goml
new file mode 100644
index 000000000..be642fc49
--- /dev/null
+++ b/src/test/rustdoc-gui/search-keyboard.goml
@@ -0,0 +1,28 @@
+// Checks that the search tab results work correctly with function signature syntax
+// First, try a search-by-name
+goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
+write: (".search-input", "Foo")
+// To be SURE that the search will be run.
+press-key: 'Enter'
+// Waiting for the search results to appear...
+wait-for: "#titles"
+
+// Now use the keyboard commands to switch to the third result.
+press-key: "ArrowDown"
+press-key: "ArrowDown"
+press-key: "ArrowDown"
+assert: ".search-results.active > a:focus:nth-of-type(3)"
+
+// Now switch to the second tab, then back to the first one, then arrow back up.
+press-key: "ArrowRight"
+assert: ".search-results.active:nth-of-type(2) > a:focus:nth-of-type(1)"
+press-key: "ArrowLeft"
+assert: ".search-results.active:nth-of-type(1) > a:focus:nth-of-type(3)"
+press-key: "ArrowUp"
+assert: ".search-results.active > a:focus:nth-of-type(2)"
+press-key: "ArrowUp"
+assert: ".search-results.active > a:focus:nth-of-type(1)"
+press-key: "ArrowUp"
+assert: ".search-input:focus"
+press-key: "ArrowDown"
+assert: ".search-results.active > a:focus:nth-of-type(1)"
diff --git a/src/test/rustdoc-gui/search-no-result.goml b/src/test/rustdoc-gui/search-no-result.goml
new file mode 100644
index 000000000..b88be32c9
--- /dev/null
+++ b/src/test/rustdoc-gui/search-no-result.goml
@@ -0,0 +1,36 @@
+// The goal of this test is to check the color of the "no result" links.
+goto: "file://" + |DOC_PATH| + "/lib2/index.html?search=sdkfskjfsdks"
+show-text: true
+
+define-function: (
+ "check-no-result",
+ (theme, link, link_hover),
+ [
+ // Changing theme.
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ ("reload"),
+ ("wait-for", "#results"),
+ ("assert", ".search-failed.active"),
+ ("assert-css", ("#results a", {"color": |link|}, ALL)),
+ ("move-cursor-to", "#results a"),
+ ("assert-css", ("#results a:hover", {"color": |link_hover|})),
+ // Moving the cursor to some other place to not create issues with next function run.
+ ("move-cursor-to", ".search-input"),
+ ]
+)
+
+call-function: ("check-no-result", {
+ "theme": "ayu",
+ "link": "rgb(57, 175, 215)",
+ "link_hover": "rgb(57, 175, 215)",
+})
+call-function: ("check-no-result", {
+ "theme": "dark",
+ "link": "rgb(210, 153, 29)",
+ "link_hover": "rgb(210, 153, 29)",
+})
+call-function: ("check-no-result", {
+ "theme": "light",
+ "link": "rgb(56, 115, 173)",
+ "link_hover": "rgb(56, 115, 173)",
+})
diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml
index 69bb30df9..dde43b1c9 100644
--- a/src/test/rustdoc-gui/search-result-color.goml
+++ b/src/test/rustdoc-gui/search-result-color.goml
@@ -67,7 +67,7 @@ reload:
// Waiting for the search results to appear...
wait-for: "#titles"
assert-css: (
- "//*[@class='desc']//*[text()='Just a normal struct.']",
+ "//*[@class='desc'][text()='Just a normal struct.']",
{"color": "rgb(197, 197, 197)"},
)
assert-css: (
@@ -75,6 +75,12 @@ assert-css: (
{"color": "rgb(0, 150, 207)"},
)
+// Checking the color of the bottom border.
+assert-css: (
+ ".search-results > a",
+ {"border-bottom-color": "rgba(170, 170, 170, 0.2)"}
+)
+
// Checking the color of "keyword" text.
assert-css: (
"//*[@class='result-name']//*[text()='(keyword)']",
@@ -153,7 +159,7 @@ assert-css: (
)
// Checking color and background on hover.
-move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']"
+move-cursor-to: "//*[@class='desc'][text()='Just a normal struct.']"
assert-css: (
"//*[@class='result-name']/*[text()='test_docs::']",
{"color": "rgb(255, 255, 255)"},
@@ -173,7 +179,7 @@ reload:
// Waiting for the search results to appear...
wait-for: "#titles"
assert-css: (
- "//*[@class='desc']//*[text()='Just a normal struct.']",
+ "//*[@class='desc'][text()='Just a normal struct.']",
{"color": "rgb(221, 221, 221)"},
)
assert-css: (
@@ -181,6 +187,12 @@ assert-css: (
{"color": "rgb(221, 221, 221)"},
)
+// Checking the color of the bottom border.
+assert-css: (
+ ".search-results > a",
+ {"border-bottom-color": "rgba(170, 170, 170, 0.2)"}
+)
+
// Checking the color for "keyword" text.
assert-css: (
"//*[@class='result-name']//*[text()='(keyword)']",
@@ -264,7 +276,7 @@ reload:
// Waiting for the search results to appear...
wait-for: "#titles"
assert-css: (
- "//*[@class='desc']//*[text()='Just a normal struct.']",
+ "//*[@class='desc'][text()='Just a normal struct.']",
{"color": "rgb(0, 0, 0)"},
)
assert-css: (
@@ -272,6 +284,12 @@ assert-css: (
{"color": "rgb(0, 0, 0)"},
)
+// Checking the color of the bottom border.
+assert-css: (
+ ".search-results > a",
+ {"border-bottom-color": "rgba(170, 170, 170, 0.2)"}
+)
+
// Checking the color for "keyword" text.
assert-css: (
"//*[@class='result-name']//*[text()='(keyword)']",
@@ -348,23 +366,42 @@ assert-css: (
{"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
)
-// Check the alias more specifically in the dark theme.
+// Check the alias.
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
-// We set the theme so we're sure that the correct values will be used, whatever the computer
-// this test is running on.
-local-storage: {
- "rustdoc-theme": "dark",
- "rustdoc-use-system-theme": "false",
-}
// If the text isn't displayed, the browser doesn't compute color style correctly...
show-text: true
-// We reload the page so the local storage settings are being used.
-reload:
-write: (".search-input", "thisisanalias")
-// To be SURE that the search will be run.
-press-key: 'Enter'
-// Waiting for the search results to appear...
-wait-for: "#titles"
-// Checking that the colors for the alias element are the ones expected.
-assert-css: (".result-name > .alias", {"color": "rgb(255, 255, 255)"})
-assert-css: (".result-name > .alias > .grey", {"color": "rgb(204, 204, 204)"})
+
+define-function: (
+ "check-alias",
+ (theme, alias, grey),
+ [
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ ("reload"),
+ ("write", (".search-input", "thisisanalias")),
+ // To be SURE that the search will be run.
+ ("press-key", 'Enter'),
+ // Waiting for the search results to appear...
+ ("wait-for", "#titles"),
+ // Checking that the colors for the alias element are the ones expected.
+ ("assert-css", (".result-name > .alias", {"color": |alias|})),
+ ("assert-css", (".result-name > .alias > .grey", {"color": |grey|})),
+ // Leave the search results to prevent reloading with an already filled search input.
+ ("press-key", "Escape"),
+ ],
+)
+
+call-function: ("check-alias", {
+ "theme": "ayu",
+ "alias": "rgb(197, 197, 197)",
+ "grey": "rgb(153, 153, 153)",
+})
+call-function: ("check-alias", {
+ "theme": "dark",
+ "alias": "rgb(255, 255, 255)",
+ "grey": "rgb(204, 204, 204)",
+})
+call-function: ("check-alias", {
+ "theme": "light",
+ "alias": "rgb(0, 0, 0)",
+ "grey": "rgb(153, 153, 153)",
+})
diff --git a/src/test/rustdoc-gui/search-result-display.goml b/src/test/rustdoc-gui/search-result-display.goml
index 053bfd8c9..13a5e4c71 100644
--- a/src/test/rustdoc-gui/search-result-display.goml
+++ b/src/test/rustdoc-gui/search-result-display.goml
@@ -7,7 +7,7 @@ press-key: 'Enter'
wait-for: "#crate-search"
// The width is returned by "getComputedStyle" which returns the exact number instead of the
// CSS rule which is "50%"...
-assert-css: (".search-results div.desc", {"width": "318px"})
+assert-css: (".search-results div.desc", {"width": "310px"})
size: (600, 100)
// As counter-intuitive as it may seem, in this width, the width is "100%", which is why
// when computed it's larger.
@@ -22,7 +22,8 @@ size: (900, 900)
// First we check the current width, height and position.
assert-css: ("#crate-search", {"width": "223px"})
-assert-css: (".search-results-title", {"height": "44px", "width": "336px"})
+assert-css: (".search-results-title", {"height": "44px", "width": "640px"})
+assert-css: ("#search", {"width": "640px"})
// Then we update the text of one of the `<option>`.
text: (
@@ -35,3 +36,43 @@ assert-css: ("#crate-search", {"width": "527px"})
assert-css: (".search-results-title", {"height": "44px", "width": "640px"})
// And we check that the `<select>` isn't bigger than its container (".search-results-title").
assert-css: ("#search", {"width": "640px"})
+
+// Now checking that the crate filter is working as expected too.
+show-text: true
+define-function: (
+ "check-filter",
+ (theme, border, filter, hover_border, hover_filter),
+ [
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ ("reload"),
+ ("wait-for", "#crate-search"),
+ ("assert-css", ("#crate-search", {"border": "1px solid " + |border|})),
+ ("assert-css", ("#crate-search-div::after", {"filter": |filter|})),
+ ("move-cursor-to", "#crate-search"),
+ ("assert-css", ("#crate-search", {"border": "1px solid " + |hover_border|})),
+ ("assert-css", ("#crate-search-div::after", {"filter": |hover_filter|})),
+ ("move-cursor-to", ".search-input"),
+ ],
+)
+
+call-function: ("check-filter", {
+ "theme": "ayu",
+ "border": "rgb(92, 103, 115)",
+ "filter": "invert(0.41) sepia(0.12) saturate(4.87) hue-rotate(171deg) brightness(0.94) contrast(0.94)",
+ "hover_border": "rgb(224, 224, 224)",
+ "hover_filter": "invert(0.98) sepia(0.12) saturate(0.81) hue-rotate(343deg) brightness(1.13) contrast(0.76)",
+})
+call-function: ("check-filter", {
+ "theme": "dark",
+ "border": "rgb(224, 224, 224)",
+ "filter": "invert(0.94) sepia(0) saturate(7.21) hue-rotate(255deg) brightness(0.9) contrast(0.9)",
+ "hover_border": "rgb(33, 150, 243)",
+ "hover_filter": "invert(0.69) sepia(0.6) saturate(66.13) hue-rotate(184deg) brightness(1) contrast(0.91)",
+})
+call-function: ("check-filter", {
+ "theme": "light",
+ "border": "rgb(224, 224, 224)",
+ "filter": "invert(1) sepia(0) saturate(42.23) hue-rotate(289deg) brightness(1.14) contrast(0.76)",
+ "hover_border": "rgb(113, 113, 113)",
+ "hover_filter": "invert(0.44) sepia(0.18) saturate(0.23) hue-rotate(317deg) brightness(0.96) contrast(0.93)",
+})
diff --git a/src/test/rustdoc-gui/settings.goml b/src/test/rustdoc-gui/settings.goml
index f258f4d2a..fc3beaa53 100644
--- a/src/test/rustdoc-gui/settings.goml
+++ b/src/test/rustdoc-gui/settings.goml
@@ -37,8 +37,7 @@ click: "#settings-menu"
wait-for: "#settings"
// We check that the "Use system theme" is disabled.
-assert-property: ("#use-system-theme", {"checked": "false"})
-assert: "//*[@class='setting-line']//span[text()='Use system theme']"
+assert-property: ("#theme-system-preference", {"checked": "false"})
// Meaning that only the "theme" menu is showing up.
assert: ".setting-line:not(.hidden) #theme"
assert: ".setting-line.hidden #preferred-dark-theme"
@@ -48,7 +47,8 @@ assert: ".setting-line.hidden #preferred-light-theme"
assert-property: ("#theme .choices #theme-dark", {"checked": "true"})
// Some style checks...
-// First we check the "default" display.
+move-cursor-to: "#settings-menu > a"
+// First we check the "default" display for radio buttons.
assert-css: (
"#theme-dark",
{
@@ -57,7 +57,7 @@ assert-css: (
},
)
assert-css: ("#theme-light", {"border-color": "rgb(221, 221, 221)", "box-shadow": "none"})
-// Let's start with the hover.
+// Let's start with the hover for radio buttons.
move-cursor-to: "#theme-dark"
assert-css: (
"#theme-dark",
@@ -69,7 +69,7 @@ assert-css: (
move-cursor-to: "#theme-light"
assert-css: ("#theme-light", {"border-color": "rgb(33, 150, 243)", "box-shadow": "none"})
move-cursor-to: "#theme-ayu"
-// Let's now check with the focus.
+// Let's now check with the focus for radio buttons.
focus: "#theme-dark"
assert-css: (
"#theme-dark",
@@ -86,7 +86,7 @@ assert-css: (
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
},
)
-// Now we check we both focus and hover.
+// Now we check we both focus and hover for radio buttons.
move-cursor-to: "#theme-dark"
focus: "#theme-dark"
assert-css: (
@@ -106,19 +106,57 @@ assert-css: (
},
)
+// First we check the "default" display for toggles.
+assert-css: (
+ "#auto-hide-large-items",
+ {
+ "background-color": "rgb(33, 150, 243)",
+ "border-color": "rgb(221, 221, 221)",
+ },
+)
+// Let's start with the hover for toggles.
+move-cursor-to: "#auto-hide-large-items"
+assert-css: (
+ "#auto-hide-large-items",
+ {
+ "background-color": "rgb(33, 150, 243)",
+ "border-color": "rgb(33, 150, 243)",
+ },
+)
+move-cursor-to: "#settings-menu > a"
+// Let's now check with the focus for toggles.
+focus: "#auto-hide-large-items"
+assert-css: (
+ "#auto-hide-large-items",
+ {
+ "background-color": "rgb(33, 150, 243)",
+ "border-color": "rgb(221, 221, 221)",
+ "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
+ },
+)
+// Now we check we both focus and hover for toggles.
+move-cursor-to: "#auto-hide-large-items"
+focus: "#auto-hide-large-items"
+assert-css: (
+ "#auto-hide-large-items",
+ {
+ "background-color": "rgb(33, 150, 243)",
+ "border-color": "rgb(33, 150, 243)",
+ "box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
+ },
+)
+
// We now switch the display.
-click: "#use-system-theme"
+click: "#theme-system-preference"
// Wait for the hidden element to show up.
wait-for: ".setting-line:not(.hidden) #preferred-dark-theme"
assert: ".setting-line:not(.hidden) #preferred-light-theme"
-// Check that the theme picking is hidden.
-assert: ".setting-line.hidden #theme"
// We check their text as well.
assert-text: ("#preferred-dark-theme .setting-name", "Preferred dark theme")
assert-text: ("#preferred-light-theme .setting-name", "Preferred light theme")
-// We now check that clicking on the "sliders"' text is like clicking on the slider.
+// We now check that clicking on the toggles' text is like clicking on the checkbox.
// To test it, we use the "Disable keyboard shortcuts".
local-storage: {"rustdoc-disable-shortcuts": "false"}
click: ".setting-line:last-child .toggle .label"
@@ -141,10 +179,7 @@ assert-css: ("#settings-menu .popover", {"display": "none"})
// Now we go to the settings page to check that the CSS is loaded as expected.
goto: "file://" + |DOC_PATH| + "/settings.html"
wait-for: "#settings"
-assert-css: (
- ".setting-line .toggle .slider",
- {"width": "45px", "margin-right": "20px", "border": "0px none rgb(0, 0, 0)"},
-)
+assert-css: (".setting-line", {"position": "relative"})
assert-attribute-false: ("#settings", {"class": "popover"}, CONTAINS)
compare-elements-position: (".sub form", "#settings", ("x"))
@@ -162,4 +197,4 @@ reload:
size: (300, 1000)
click: "#settings-menu"
wait-for: "#settings"
-assert-css: ("#settings .slider", {"width": "45px"}, ALL)
+assert-css: (".setting-line", {"position": "relative"})
diff --git a/src/test/rustdoc-gui/sidebar-links-color.goml b/src/test/rustdoc-gui/sidebar-links-color.goml
index 18a1a3fad..7ef7ec90c 100644
--- a/src/test/rustdoc-gui/sidebar-links-color.goml
+++ b/src/test/rustdoc-gui/sidebar-links-color.goml
@@ -4,230 +4,168 @@ goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
// This is needed so that the text color is computed.
show-text: true
-// Ayu theme
-local-storage: {
- "rustdoc-theme": "ayu",
- "rustdoc-use-system-theme": "false",
-}
-reload:
-
-// Struct
-assert-css: (
- ".sidebar .block.struct a:not(.current)",
- {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.struct a:not(.current)"
-assert-css: (
- ".sidebar .block.struct a:hover",
- {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Enum
-assert-css: (
- ".sidebar .block.enum a",
- {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.enum a"
-assert-css: (
- ".sidebar .block.enum a:hover",
- {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Union
-assert-css: (
- ".sidebar .block.union a",
- {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.union a"
-assert-css: (
- ".sidebar .block.union a:hover",
- {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Trait
-assert-css: (
- ".sidebar .block.trait a",
- {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.trait a"
-assert-css: (
- ".sidebar .block.trait a:hover",
- {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Function
-assert-css: (
- ".sidebar .block.fn a",
- {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.fn a"
-assert-css: (
- ".sidebar .block.fn a:hover",
- {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Type definition
-assert-css: (
- ".sidebar .block.type a",
- {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.type a"
-assert-css: (
- ".sidebar .block.type a:hover",
- {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// Keyword
-assert-css: (
- ".sidebar .block.keyword a",
- {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.keyword a"
-assert-css: (
- ".sidebar .block.keyword a:hover",
- {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-
-// Dark theme
-local-storage: {"rustdoc-theme": "dark"}
-reload:
-
-// Struct
-assert-css: (
- ".sidebar .block.struct a:not(.current)",
- {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.struct a:not(.current)"
-assert-css: (
- ".sidebar .block.struct a:hover",
- {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-// Enum
-assert-css: (
- ".sidebar .block.enum a",
- {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.enum a"
-assert-css: (
- ".sidebar .block.enum a:hover",
- {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-// Union
-assert-css: (
- ".sidebar .block.union a",
- {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.union a"
-assert-css: (
- ".sidebar .block.union a:hover",
- {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
+define-function: (
+ "check-colors",
+ (
+ theme, struct, struct_hover, struct_hover_background, enum, enum_hover,
+ enum_hover_background, union, union_hover, union_hover_background, trait, trait_hover,
+ trait_hover_background, fn, fn_hover, fn_hover_background, type, type_hover,
+ type_hover_background, keyword, keyword_hover, keyword_hover_background,
+ ),
+ [
+ ("local-storage", { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }),
+ ("reload"),
+ // Struct
+ ("assert-css", (
+ ".sidebar .block.struct a:not(.current)",
+ {"color": |struct|, "background-color": "rgba(0, 0, 0, 0)"},
+ )),
+ ("move-cursor-to", ".sidebar .block.struct a:not(.current)"),
+ ("assert-css", (
+ ".sidebar .block.struct a:hover",
+ {"color": |struct_hover|, "background-color": |struct_hover_background|},
+ )),
+ // Enum
+ ("assert-css", (
+ ".sidebar .block.enum a",
+ {"color": |enum|, "background-color": "rgba(0, 0, 0, 0)"},
+ )),
+ ("move-cursor-to", ".sidebar .block.enum a"),
+ ("assert-css", (
+ ".sidebar .block.enum a:hover",
+ {"color": |enum_hover|, "background-color": |enum_hover_background|},
+ )),
+ // Union
+ ("assert-css", (
+ ".sidebar .block.union a",
+ {"color": |union|, "background-color": "rgba(0, 0, 0, 0)"},
+ )),
+ ("move-cursor-to", ".sidebar .block.union a"),
+ ("assert-css", (
+ ".sidebar .block.union a:hover",
+ {"color": |union_hover|, "background-color": |union_hover_background|},
+ )),
+ // Trait
+ ("assert-css", (
+ ".sidebar .block.trait a",
+ {"color": |trait|, "background-color": "rgba(0, 0, 0, 0)"},
+ )),
+ ("move-cursor-to", ".sidebar .block.trait a"),
+ ("assert-css", (
+ ".sidebar .block.trait a:hover",
+ {"color": |trait_hover|, "background-color": |trait_hover_background|},
+ )),
+ // Function
+ ("assert-css", (
+ ".sidebar .block.fn a",
+ {"color": |fn|, "background-color": "rgba(0, 0, 0, 0)"},
+ )),
+ ("move-cursor-to", ".sidebar .block.fn a"),
+ ("assert-css", (
+ ".sidebar .block.fn a:hover",
+ {"color": |fn_hover|, "background-color": |fn_hover_background|},
+ )),
+ // Type definition
+ ("assert-css", (
+ ".sidebar .block.type a",
+ {"color": |type|, "background-color": "rgba(0, 0, 0, 0)"},
+ )),
+ ("move-cursor-to", ".sidebar .block.type a"),
+ ("assert-css", (
+ ".sidebar .block.type a:hover",
+ {"color": |type_hover|, "background-color": |type_hover_background|},
+ )),
+ // Keyword
+ ("assert-css", (
+ ".sidebar .block.keyword a",
+ {"color": |keyword|, "background-color": "rgba(0, 0, 0, 0)"},
+ )),
+ ("move-cursor-to", ".sidebar .block.keyword a"),
+ ("assert-css", (
+ ".sidebar .block.keyword a:hover",
+ {"color": |keyword_hover|, "background-color": |keyword_hover_background|},
+ )),
+ ]
)
-// Trait
-assert-css: (
- ".sidebar .block.trait a",
- {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.trait a"
-assert-css: (
- ".sidebar .block.trait a:hover",
- {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-// Function
-assert-css: (
- ".sidebar .block.fn a",
- {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.fn a"
-assert-css: (
- ".sidebar .block.fn a:hover",
- {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-// Type definition
-assert-css: (
- ".sidebar .block.type a",
- {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.type a"
-assert-css: (
- ".sidebar .block.type a:hover",
- {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-// Keyword
-assert-css: (
- ".sidebar .block.keyword a",
- {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.keyword a"
-assert-css: (
- ".sidebar .block.keyword a:hover",
- {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"},
-)
-
-// Light theme
-local-storage: {"rustdoc-theme": "light"}
-reload:
-// Struct
-assert-css: (
- ".sidebar .block.struct a:not(.current)",
- {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.struct a:not(.current)"
-assert-css: (
- ".sidebar .block.struct a:hover",
- {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Enum
-assert-css: (
- ".sidebar .block.enum a",
- {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.enum a"
-assert-css: (
- ".sidebar .block.enum a:hover",
- {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Union
-assert-css: (
- ".sidebar .block.union a",
- {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.union a"
-assert-css: (
- ".sidebar .block.union a:hover",
- {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Trait
-assert-css: (
- ".sidebar .block.trait a",
- {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.trait a"
-assert-css: (
- ".sidebar .block.trait a:hover",
- {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Function
-assert-css: (
- ".sidebar .block.fn a",
- {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.fn a"
-assert-css: (
- ".sidebar .block.fn a:hover",
- {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Type definition
-assert-css: (
- ".sidebar .block.type a",
- {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.type a"
-assert-css: (
- ".sidebar .block.type a:hover",
- {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
-)
-// Keyword
-assert-css: (
- ".sidebar .block.keyword a",
- {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-move-cursor-to: ".sidebar .block.keyword a"
-assert-css: (
- ".sidebar .block.keyword a:hover",
- {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"},
+call-function: (
+ "check-colors",
+ {
+ "theme": "ayu",
+ "struct": "rgb(83, 177, 219)",
+ "struct_hover": "rgb(255, 180, 76)",
+ "struct_hover_background": "rgba(0, 0, 0, 0)",
+ "enum": "rgb(83, 177, 219)",
+ "enum_hover": "rgb(255, 180, 76)",
+ "enum_hover_background": "rgba(0, 0, 0, 0)",
+ "union": "rgb(83, 177, 219)",
+ "union_hover": "rgb(255, 180, 76)",
+ "union_hover_background": "rgba(0, 0, 0, 0)",
+ "trait": "rgb(83, 177, 219)",
+ "trait_hover": "rgb(255, 180, 76)",
+ "trait_hover_background": "rgba(0, 0, 0, 0)",
+ "fn": "rgb(83, 177, 219)",
+ "fn_hover": "rgb(255, 180, 76)",
+ "fn_hover_background": "rgba(0, 0, 0, 0)",
+ "type": "rgb(83, 177, 219)",
+ "type_hover": "rgb(255, 180, 76)",
+ "type_hover_background": "rgba(0, 0, 0, 0)",
+ "keyword": "rgb(83, 177, 219)",
+ "keyword_hover": "rgb(255, 180, 76)",
+ "keyword_hover_background": "rgba(0, 0, 0, 0)",
+ }
+)
+call-function: (
+ "check-colors",
+ {
+ "theme": "dark",
+ "struct": "rgb(253, 191, 53)",
+ "struct_hover": "rgb(253, 191, 53)",
+ "struct_hover_background": "rgb(68, 68, 68)",
+ "enum": "rgb(253, 191, 53)",
+ "enum_hover": "rgb(253, 191, 53)",
+ "enum_hover_background": "rgb(68, 68, 68)",
+ "union": "rgb(253, 191, 53)",
+ "union_hover": "rgb(253, 191, 53)",
+ "union_hover_background": "rgb(68, 68, 68)",
+ "trait": "rgb(253, 191, 53)",
+ "trait_hover": "rgb(253, 191, 53)",
+ "trait_hover_background": "rgb(68, 68, 68)",
+ "fn": "rgb(253, 191, 53)",
+ "fn_hover": "rgb(253, 191, 53)",
+ "fn_hover_background": "rgb(68, 68, 68)",
+ "type": "rgb(253, 191, 53)",
+ "type_hover": "rgb(253, 191, 53)",
+ "type_hover_background": "rgb(68, 68, 68)",
+ "keyword": "rgb(253, 191, 53)",
+ "keyword_hover": "rgb(253, 191, 53)",
+ "keyword_hover_background": "rgb(68, 68, 68)",
+ }
+)
+call-function: (
+ "check-colors",
+ {
+ "theme": "light",
+ "struct": "rgb(53, 109, 164)",
+ "struct_hover": "rgb(53, 109, 164)",
+ "struct_hover_background": "rgb(255, 255, 255)",
+ "enum": "rgb(53, 109, 164)",
+ "enum_hover": "rgb(53, 109, 164)",
+ "enum_hover_background": "rgb(255, 255, 255)",
+ "union": "rgb(53, 109, 164)",
+ "union_hover": "rgb(53, 109, 164)",
+ "union_hover_background": "rgb(255, 255, 255)",
+ "trait": "rgb(53, 109, 164)",
+ "trait_hover": "rgb(53, 109, 164)",
+ "trait_hover_background": "rgb(255, 255, 255)",
+ "fn": "rgb(53, 109, 164)",
+ "fn_hover": "rgb(53, 109, 164)",
+ "fn_hover_background": "rgb(255, 255, 255)",
+ "type": "rgb(53, 109, 164)",
+ "type_hover": "rgb(53, 109, 164)",
+ "type_hover_background": "rgb(255, 255, 255)",
+ "keyword": "rgb(53, 109, 164)",
+ "keyword_hover": "rgb(53, 109, 164)",
+ "keyword_hover_background": "rgb(255, 255, 255)",
+ }
)
diff --git a/src/test/rustdoc-gui/sidebar-mobile.goml b/src/test/rustdoc-gui/sidebar-mobile.goml
index 453873f1b..38d01f7f6 100644
--- a/src/test/rustdoc-gui/sidebar-mobile.goml
+++ b/src/test/rustdoc-gui/sidebar-mobile.goml
@@ -32,6 +32,12 @@ assert-css: ("//nav[contains(@class, 'sidebar')]//h2/a[text()='In test_docs']/pa
click: "body"
assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
+// Open the sidebar menu, and make sure pressing Escape closes it.
+click: ".sidebar-menu-toggle"
+assert-css: (".sidebar", {"left": "0px"})
+press-key: "Escape"
+assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
+
// Check that the topbar is visible
assert-property: (".mobile-topbar", {"clientHeight": "45"})
@@ -48,23 +54,35 @@ compare-elements-position-near: (".block.keyword li:nth-child(1)", ".mobile-topb
// Now checking the background color of the sidebar.
show-text: true
-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
-reload:
-
-// Open the sidebar menu.
-click: ".sidebar-menu-toggle"
-assert-css: (".sidebar", {"background-color": "rgb(80, 80, 80)", "color": "rgb(221, 221, 221)"})
-
-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "ayu"}
-reload:
-// Open the sidebar menu.
-click: ".sidebar-menu-toggle"
-assert-css: (".sidebar", {"background-color": "rgb(20, 25, 31)", "color": "rgb(197, 197, 197)"})
+define-function: (
+ "check-colors",
+ (theme, color, background),
+ [
+ ("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}),
+ ("reload"),
-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "light"}
-reload:
+ // Open the sidebar menu.
+ ("click", ".sidebar-menu-toggle"),
+ ("assert-css", (".sidebar", {
+ "background-color": |background|,
+ "color": |color|,
+ })),
+ ],
+)
-// Open the sidebar menu.
-click: ".sidebar-menu-toggle"
-assert-css: (".sidebar", {"background-color": "rgb(245, 245, 245)", "color": "rgb(0, 0, 0)"})
+call-function: ("check-colors", {
+ "theme": "ayu",
+ "color": "rgb(197, 197, 197)",
+ "background": "rgb(20, 25, 31)",
+})
+call-function: ("check-colors", {
+ "theme": "dark",
+ "color": "rgb(221, 221, 221)",
+ "background": "rgb(80, 80, 80)",
+})
+call-function: ("check-colors", {
+ "theme": "light",
+ "color": "rgb(0, 0, 0)",
+ "background": "rgb(245, 245, 245)",
+})
diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml
index 4155dab64..40ae4af81 100644
--- a/src/test/rustdoc-gui/sidebar-source-code-display.goml
+++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml
@@ -29,171 +29,124 @@ assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
// Now we check the display of the sidebar items.
show-text: true
-// First we start with the light theme.
-local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
-reload:
-// Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
-assert-css: (
- "#source-sidebar details[open] > .files a.selected",
- {"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"},
-)
-// Without hover or focus.
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
-// With focus.
-focus: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .files a:not(.selected)"
-wait-for-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
-assert-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
-)
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .folders > details > summary"
-wait-for-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
-)
+define-function: (
+ "check-colors",
+ (
+ theme, color, color_hover, background, background_hover, background_toggle,
+ background_toggle_hover,
+ ),
+ [
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ ("reload"),
+ ("wait-for-css", ("#sidebar-toggle", {"visibility": "visible"})),
+ ("assert-css", (
+ "#source-sidebar details[open] > .files a.selected",
+ {"color": |color_hover|, "background-color": |background|},
+ )),
-// Now with the dark theme.
-local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
-reload:
-// Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
-assert-css: (
- "#source-sidebar details[open] > .files > a.selected",
- {"color": "rgb(221, 221, 221)", "background-color": "rgb(51, 51, 51)"},
-)
-// Without hover or focus.
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
-// With focus.
-focus: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .files > a:not(.selected)",
- {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .files a:not(.selected)"
-wait-for-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
-assert-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .folders > details > summary"
-wait-for-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
-)
+ // Without hover or focus.
+ ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle|})),
+ // With focus.
+ ("focus", "#sidebar-toggle > button"),
+ ("assert-css", (
+ "#sidebar-toggle > button:focus",
+ {"background-color": |background_toggle_hover|},
+ )),
+ ("focus", ".search-input"),
+ // With hover.
+ ("move-cursor-to", "#sidebar-toggle > button"),
+ ("assert-css", (
+ "#sidebar-toggle > button:hover",
+ {"background-color": |background_toggle_hover|},
+ )),
-// And finally with the ayu theme.
-local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"}
-reload:
-// Waiting for the sidebar to be displayed...
-wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
-assert-css: (
- "#source-sidebar details[open] > .files a.selected",
- {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-// Without hover or focus.
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
-// With focus.
-focus: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#sidebar-toggle > button"
-assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .files a:not(.selected)"
-wait-for-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
-assert-css: (
- "#source-sidebar details[open] > .files a:not(.selected)",
- {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-// Without hover.
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
-)
-// With focus.
-focus: "#source-sidebar details[open] > .folders > details > summary"
-wait-for-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
-)
-focus: ".search-input"
-// With hover.
-move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
-assert-css: (
- "#source-sidebar details[open] > .folders > details > summary",
- {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
+ // Without hover or focus.
+ ("assert-css", (
+ "#source-sidebar details[open] > .files a:not(.selected)",
+ {"color": |color|, "background-color": |background_toggle|},
+ )),
+ // With focus.
+ ("focus", "#source-sidebar details[open] > .files a:not(.selected)"),
+ ("wait-for-css", (
+ "#source-sidebar details[open] > .files a:not(.selected):focus",
+ {"color": |color_hover|, "background-color": |background_hover|},
+ )),
+ ("focus", ".search-input"),
+ // With hover.
+ ("move-cursor-to", "#source-sidebar details[open] > .files a:not(.selected)"),
+ ("assert-css", (
+ "#source-sidebar details[open] > .files a:not(.selected):hover",
+ {"color": |color_hover|, "background-color": |background_hover|},
+ )),
+
+ // Without hover or focus.
+ ("assert-css", (
+ "#source-sidebar .dir-entry summary",
+ {"color": |color|, "background-color": |background_toggle|},
+ )),
+ // With focus.
+ ("focus", "#source-sidebar .dir-entry summary"),
+ ("wait-for-css", (
+ "#source-sidebar .dir-entry summary:focus",
+ {"color": |color_hover|, "background-color": |background_hover|},
+ )),
+ ("focus", ".search-input"),
+ // With hover.
+ ("move-cursor-to", "#source-sidebar .dir-entry summary"),
+ ("assert-css", (
+ "#source-sidebar .dir-entry summary:hover",
+ {"color": |color_hover|, "background-color": |background_hover|},
+ )),
+
+ // Without hover or focus.
+ ("assert-css", (
+ "#source-sidebar details[open] > .folders > details > summary",
+ {"color": |color|, "background-color": |background_toggle|},
+ )),
+ // With focus.
+ ("focus", "#source-sidebar details[open] > .folders > details > summary"),
+ ("wait-for-css", (
+ "#source-sidebar details[open] > .folders > details > summary:focus",
+ {"color": |color_hover|, "background-color": |background_hover|},
+ )),
+ ("focus", ".search-input"),
+ // With hover.
+ ("move-cursor-to", "#source-sidebar details[open] > .folders > details > summary"),
+ ("assert-css", (
+ "#source-sidebar details[open] > .folders > details > summary:hover",
+ {"color": |color_hover|, "background-color": |background_hover|},
+ )),
+ ],
)
+call-function: ("check-colors", {
+ "theme": "light",
+ "color": "rgb(0, 0, 0)",
+ "color_hover": "rgb(0, 0, 0)",
+ "background": "rgb(255, 255, 255)",
+ "background_hover": "rgb(224, 224, 224)",
+ "background_toggle": "rgba(0, 0, 0, 0)",
+ "background_toggle_hover": "rgb(224, 224, 224)",
+})
+call-function: ("check-colors", {
+ "theme": "dark",
+ "color": "rgb(221, 221, 221)",
+ "color_hover": "rgb(221, 221, 221)",
+ "background": "rgb(51, 51, 51)",
+ "background_hover": "rgb(68, 68, 68)",
+ "background_toggle": "rgba(0, 0, 0, 0)",
+ "background_toggle_hover": "rgb(103, 103, 103)",
+})
+call-function: ("check-colors", {
+ "theme": "ayu",
+ "color": "rgb(197, 197, 197)",
+ "color_hover": "rgb(255, 180, 76)",
+ "background": "rgb(20, 25, 31)",
+ "background_hover": "rgb(20, 25, 31)",
+ "background_toggle": "rgba(0, 0, 0, 0)",
+ "background_toggle_hover": "rgba(70, 70, 70, 0.33)",
+})
+
// Now checking on mobile devices.
size: (500, 700)
reload:
diff --git a/src/test/rustdoc-gui/sidebar-source-code.goml b/src/test/rustdoc-gui/sidebar-source-code.goml
index 9ba663687..36e4d555b 100644
--- a/src/test/rustdoc-gui/sidebar-source-code.goml
+++ b/src/test/rustdoc-gui/sidebar-source-code.goml
@@ -28,7 +28,7 @@ assert: "//*[@class='dir-entry' and @open]/*[text()='sub_mod']"
// Only "another_folder" should be "open" in "lib2".
assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']"
// All other trees should be collapsed.
-assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 5)
+assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 7)
// We now switch to mobile mode.
size: (600, 600)
diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml
index a2dac2aa6..b3b837ad3 100644
--- a/src/test/rustdoc-gui/source-code-page.goml
+++ b/src/test/rustdoc-gui/source-code-page.goml
@@ -2,17 +2,22 @@
goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
show-text: true
// Check that we can click on the line number.
-click: ".src-line-numbers > span:nth-child(4)" // This is the span for line 4.
+click: ".src-line-numbers > a:nth-child(4)" // This is the anchor for line 4.
// Ensure that the page URL was updated.
assert-document-property: ({"URL": "lib.rs.html#4"}, ENDS_WITH)
assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"})
-// We now check that the good spans are highlighted
+// Ensure that the default style, with the right border, isn't used.
+assert-css: ("//*[@id='4']", {"border-right-width": "0px"})
+reload:
+assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"})
+assert-css: ("//*[@id='4']", {"border-right-width": "0px"})
+// We now check that the good anchors are highlighted
goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4-6"
-assert-attribute-false: (".src-line-numbers > span:nth-child(3)", {"class": "line-highlighted"})
-assert-attribute: (".src-line-numbers > span:nth-child(4)", {"class": "line-highlighted"})
-assert-attribute: (".src-line-numbers > span:nth-child(5)", {"class": "line-highlighted"})
-assert-attribute: (".src-line-numbers > span:nth-child(6)", {"class": "line-highlighted"})
-assert-attribute-false: (".src-line-numbers > span:nth-child(7)", {"class": "line-highlighted"})
+assert-attribute-false: (".src-line-numbers > a:nth-child(3)", {"class": "line-highlighted"})
+assert-attribute: (".src-line-numbers > a:nth-child(4)", {"class": "line-highlighted"})
+assert-attribute: (".src-line-numbers > a:nth-child(5)", {"class": "line-highlighted"})
+assert-attribute: (".src-line-numbers > a:nth-child(6)", {"class": "line-highlighted"})
+assert-attribute-false: (".src-line-numbers > a:nth-child(7)", {"class": "line-highlighted"})
define-function: (
"check-colors",
@@ -21,12 +26,12 @@ define-function: (
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
("reload"),
("assert-css", (
- ".src-line-numbers > span:not(.line-highlighted)",
+ ".src-line-numbers > a:not(.line-highlighted)",
{"color": |color|, "background-color": |background_color|},
ALL,
)),
("assert-css", (
- ".src-line-numbers > span.line-highlighted",
+ ".src-line-numbers > a.line-highlighted",
{"color": |highlight_color|, "background-color": |highlight_background_color|},
ALL,
)),
@@ -57,6 +62,25 @@ call-function: ("check-colors", {
// This is to ensure that the content is correctly align with the line numbers.
compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y"))
+// Check the `href` property so that users can treat anchors as links.
+assert-property: (".src-line-numbers > a:nth-child(1)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#1"
+})
+assert-property: (".src-line-numbers > a:nth-child(2)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#2"
+})
+assert-property: (".src-line-numbers > a:nth-child(3)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#3"
+})
+assert-property: (".src-line-numbers > a:nth-child(4)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4"
+})
+assert-property: (".src-line-numbers > a:nth-child(5)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#5"
+})
+assert-property: (".src-line-numbers > a:nth-child(6)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#6"
+})
// Assert that the line numbers text is aligned to the right.
assert-css: (".src-line-numbers", {"text-align": "right"})
@@ -66,7 +90,7 @@ assert-css: (".src-line-numbers", {"text-align": "right"})
goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
// We use this assert-position to know where we will click.
assert-position: ("//*[@id='1']", {"x": 104, "y": 112})
-// We click on the left of the "1" span but still in the "src-line-number" `<pre>`.
+// We click on the left of the "1" anchor but still in the "src-line-number" `<pre>`.
click: (103, 103)
assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH)
@@ -78,7 +102,7 @@ assert: ".source-sidebar-expanded"
// We check that the first entry of the sidebar is collapsed
assert-property: ("#source-sidebar details:first-of-type", {"open": "false"})
-assert-text: ("#source-sidebar details:first-of-type > summary", "implementors")
+assert-text: ("#source-sidebar details:first-of-type > summary", "huge_logo")
// We now click on it.
click: "#source-sidebar details:first-of-type > summary"
assert-property: ("#source-sidebar details:first-of-type", {"open": "true"})
diff --git a/src/test/rustdoc-gui/src-font-size.goml b/src/test/rustdoc-gui/src-font-size.goml
index b17dfd94c..9233f3744 100644
--- a/src/test/rustdoc-gui/src-font-size.goml
+++ b/src/test/rustdoc-gui/src-font-size.goml
@@ -9,3 +9,8 @@ assert-css: (".impl.has-srclink .code-header", {"font-size": "18px", "font-weigh
// Check the impl items.
assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL)
assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px", "font-weight": 600}, ALL)
+
+// Check that we can click on source link
+store-document-property: (url, "URL")
+click: ".impl-items .has-srclink .srclink"
+assert-document-property-false: {"URL": |url|}
diff --git a/src/test/rustdoc-gui/src/huge_logo/Cargo.lock b/src/test/rustdoc-gui/src/huge_logo/Cargo.lock
new file mode 100644
index 000000000..142805750
--- /dev/null
+++ b/src/test/rustdoc-gui/src/huge_logo/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "huge_logo"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/huge_logo/Cargo.toml b/src/test/rustdoc-gui/src/huge_logo/Cargo.toml
new file mode 100644
index 000000000..3f10d09c8
--- /dev/null
+++ b/src/test/rustdoc-gui/src/huge_logo/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "huge_logo"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/src/test/rustdoc-gui/src/huge_logo/src/lib.rs b/src/test/rustdoc-gui/src/huge_logo/src/lib.rs
new file mode 100644
index 000000000..ec137fb9a
--- /dev/null
+++ b/src/test/rustdoc-gui/src/huge_logo/src/lib.rs
@@ -0,0 +1,17 @@
+// ignore-tidy-linelength
+#![doc(html_logo_url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsgAAANcCAQAAADoIpEcAAAAAmJLR0QA/4ePzL8AAHSISURBVHja7Z15vFbT/sefzNflXtzr+qHOXvs5p051KtVJIg1IhqRoQlHKVKbKUBkaRQiRpEhKkqIQkURyJJUkQxNKs4bTPJ7h8/uj5Ax772fvZ6+999r7+bzXP14vPXufs9b3+znr+a7v+n5jMUIIIYQQ95zxTz1Tr6e10Dpp3bX+4nkxRrwnZonvxW/iN/Gb2CpyRa7YIyAgIHaLXJErcsVqsUxfoM0QU7Sx+ouij9ZFuyZ+oZ6ZeTLnkxBCbJJ1XLy8uEx01p4Wb4vZYrnYfVhqZY1csVC8qz+j3y0u1zXONyGEFCPt1PiF4nZtqJgpVol8yQJsObRdYp4YrT+gXZTxL64DISRlySirXSsGielirZ8SbDoKxBJtrH63qB47imtDCEkJxAnaRdrD4j2xXgkZNg5qvCe6UpgJIdHlmLRs0UObIfYpK8QlwxmbxUT9pvi/uXSEkMig6frdYnp4hLjE2C+m67ee/R+uIyEkzBwVv1AMEj+FVIiLj4PiI/0mHvwRQkJIWpboK36LhBQXHfvExHijWBmuLyEkFIiK+sAISnHR8YvolnYqV5oQojAZx+uttBmiMNJi/Hf+8ghRkWtOCFFyXyyeF7mpIMXFMpenaBdw7QkhChG/UEz0936dSkPPEQ1pA4SQwMk+Vr9RfJ+qUlxkTIufS2sghAQpxjdpKyjGh0ehmKjptApCiP8cpbcSyynDJcYB8Tzv9RFCfEW7Riyj/JqM9XprWgghxB8xriG+oOwmGJ/HK9BSCCGeIv5PvCYKKLg2xh6tO2vFEUK8oox+k9hCqXUwvk7PoNkQQqSjZ4ovKbGOxw5xM22HECKTo7WHQls6M/gxPuskmhAhRM7eWOPe2OVYGq9KOyKEuEa0Fzsoqa7Hbq0tbYkQ4oKsk8QEiqm08QSzLgghSRKvoP1IGZU6PmK/EUJIEmgtxE5KqPSxqNxZtC1CiBPK6I+lRpH5AMbv8fI0MEKITTKO18dROD0cW0QdWhkhxAYV/qvnUDS9vi6i16OlEUISIARLavrTj4+STAixJF5BrKZY+lZ86CJaHCHETI6rig0USj93ydr5tDpCiAFaTVZy833kpleh5RFCSqBnio0UyADGOnbhI4QUD1aUZ7AisLE843RaICHkMELwKC/IoedkHE8rJITEYrGyp4mlFMWAx4RYGVoiISlPxvGsdaxExsXDtEVCUp0y2liKoRKjUDSnORKS0oi+lEJ1UuCYb0FICqM3FQUUQpVKc551Iq2SkJQkXkFspwgqNkbQLglJQbJOYjcQJVPgWtM2CUm96PEYip+akeR4Gq2TkNSS4zaUPmXHTLZCJSSFyCgrtlL4FA5b3EUbJSRVOErMpugpXpaTCXCEpEi4ohslT/nxOa9SE5ICpMXFbgpeCHbJnWirhESdMuJTil0oxtYK/6W5EhJp9FsodaHZI79CeyUkyuGKU8UmCl1oRgE77hES5f3xMMpcqPbI85mRTEhESa+i5VHkQpaRfCPtlpBIwkL0IRyry/6DlktI5IhfRXljJxFCiAocLX6iuIVybE87leZLSKTQOlLaQjv60H4JiRBZx4k/KGyhHdvi/6YNExIZ9Fspa6EevWnDhEQnfrycohbuOLI4hWZMSCQQ7Slpoc9HfoR2TEgUKCN+oaCFv9RQxr9oyoSEHq0J5SwS+cgP0ZYJCX/AYibFLBJjffaxtGZCQk28qiikmEVktKE9ExLu/fFrFLLIBC2+oj0TEub98b/FHgpZdEZaNm2akNCi300RYw8RQogSaD9SxCI19p79H1o1IeGU4wsoYZHbI99HuyYklIiXKWCRG7+xqRMhISTrOLGFAhbB0ZC2TUj4AhYtKF482COEqBGwmELximZ1ZHECrZuQUJF5sthH8Ypo5beWtG9CwhWwuIHCFdkxhfZNSKjQ36FwRXYcYDYyISHirBPFbgpXhMfttHFCwrM/vpqiFekxmzZOSHgEeRhFK9KjsOzZtHJCQoL4laLFoAUhRAE0nYIV+dS3D2nnhIRjf9yZghX5sT/rJFo6IWEQZN7RS4XRjJZOiPocI7ZTrlIgaPEqTZ0Q5dHrUaxSYvzJQpyEKI82gGKVIuM8WjshqkeQZ1OqUiRo8RitnRClyT6WfaZTZsylvROidsCiJoUqZUrV52X8ixZPiMoBC+Ygp5IkN6HFE6KyIL9OmUqhKPJgWjwhKgvyUspUCo3vaPGEqCvHp4gCylQKjYK0U2n1hKgqyJdRpHiBmhCihiD3pkSl2BhCqydEVUGeTIlKsbGIVk+IqoK8jBKValHkzJNp94QoSMbxWh4lKuVGA1o+IQqin0N5SsFc5Ado+YQoiHYD5SkFx0RaPiEq7pAfozyl4FhFyydEQdi6KUWDFmfQ9glRT5CZY5GagtyUtk+IanJ8gsinOKVkzbf+tH5CFCMti9KUouNjWj8hiqFdSWlK0bGW1k+IaiELlqZP2XH2f2j/hKglyIMoTCl7rFef9k+IWoL8FoUpZY/1utD+CVFLkOdQmFJ2vET7J0QtQV5HYUrZHfJXtH9CFCLrODZvSuGxPVaGPkCIMpRLpyyl8sgoSx8gRJ2ARQOKUkoHLa6gDxCiDHprilJKj3voA4Qog3YnRSlhti7qoAXaojO6oAs6oA0aoEJUfrvn6QOEqBOy6EvBNRuX4FG8g+U4ACPWYjoGowXSw/3H5kP6ACHqCPJLFF4jKR6O32GPXLyD66CH9XddSh8gRJ2QxSTKb/HwRGfMRSGcshL9UCmMv/GB2NH0AkJU2SHPogj/PW7FL0ieLXgcmeH7rQW9gBBVBPlnyvCh0RBfwj3r0T1kv3e8Eb2AEFVCFpspxQIZeAEHIYvPUDtMv/0d9AJC1OAotm8SaIBFkEsu7grP1ZCn6QaEKEHmyZTjztgNLxgXllzlifQDQtQIWJwpOR6JZngaH2MZcgEAediM7zEJPXCBmvFTDE0io8Iui1AnDII8h35AiBLEK8hz7Dp4ERtNxakQC/GAYjkIFTAN3rIBjdUPWayhHxCixg65phynzsYY5NkQqM3ojQxFhKgyvoL37EAb1SU5P3YMPYEQBZBT663L4QCFPVbheiXkeAH8Ya/ykswSnISosUNu4l7YPnAsUQUYHnAFiPKYBf/Yi9ZqBy3OpycQosIO+Tp3rlwXS5IUqfmoFeBR3nT4y3ZcovJ18Vb0BEIUQL/FjSNfjPWuDryuDEiAhsF/ViNb3R1yd3oCISrskLsm78aNsMX1gVfzAOTnLg8T3ayYq26hzmfpCYSoIMg9k3Xi+tggQaR2oYXP4lPfo2sgdnheVUEeT08gRIWQxaPJuXAVLJckUrtwha81KxYhOAqUyC8xiCF/Rk8gRAG0/sk4cDpmS7084d99tucRLGtRWUVJXkxPIESFkMUTyTjwc5Jl6nufqj5cZNKMyU9GqyjIG+kJhKgQsnjGuftea+tOnjPG+NIL5BsET0EgB5kJ7+odRV8gJPiQxQvOr1Ss8ESobvZcdu6BGixUsP9exun0BUKCD1kMd+q6T3kkUxtxjsd381ZBFdSrlZxWmb5ASPCCPMppESHvksbe8FRy+kAdVqO8apLckL5ASPAhi7HOHHeMp9HVZp4JTkVshkr0VC3xrTV9gZDgBfkNJ257vsS+c0bM8UxwekMt/lDt1l5n+gIhIdshj/RcqLypipaOP6Aa96lVzeIh+gIhwceQxzi5nbfLc5n62qPqFerxi1o75CfpC4QEL8iv23faHr4IlRd75HlQEaXK1o+gLxASvCCPtu+0/lyryJEuNo2hJh+rJMhv0xcICV6QX7N/oFfgk1A1kSw2YxQV5LwAS/SXGp/SFwgJXpBt5yE/6ZtQyb1GneGo35+/DFBHkOfRFwgJHP1Vuy671DeZ2olKEqXmZkk50ovxKcbhNXyKn6WVKFLoYG85fYGQwNFesdusyU+6SpSaKa5/msXojprFnlkV3ZAj5TdtpIogb6IvEBJ8yOIlFS9WzJGYgbzD1U+yCreYlgJqj19d/6ZPqSLIB+gLhAQvyEPsOezHvgpyIRpIEprWrn6Oj1AtQcGiSa4rQasStMg+lt5ASNAhi6fs7TO3+Xzc1T/w/tIF6G3zsLPQ1Z8eVXpRx/9NbyAkYPTH7DhrU9/zD76UJDOLk3x/PrrZfsdjrn7TOxUR5HJn0RsICTpk0duOsw5Kaoe5DhuSzkfYLyXTolKSvU0KHR4ruqnxMU6VHXJ5egMhQQtyTzvOOs2hFH+Ctsg65OZogTFJyXJHCSLTJkmRHOG4OdQXSQvyClWiyNXpDYQEHUPubsdZlzsQmDW4ttTn6ybRpVrG9ZBBSUlkThKlMc9LOspecPhPV+A9Q+rSGwgJOoZ8l527bva/+P9o0ogpjucdCtWvEkTmvSQEcg8uSOpdXZPeI7dSo0R9Y3oDIUEL8i2JXbWRAxGtafGcAQ53jpVdi8wvScjjoKTftihJQe6rRkXka+kNhAQdsmib2FU72xSWfWic4EnPOBKqa1xfCtnvWBx/ddHt7qYkBfkNNXbI7egNhAQtyNckdtXBNoWlt43Dr88cCNVDLiXmwiTEsZurN85XpOBoUjvkjvQGQoIOWTSWVb5yma2jsHOwybedYyvH0rgeGa7eeG9SgryaXfUIIbFYLBa/MLGrfmBLVm636fjdbQvVApcSc7djaezj8o2Z2J7UJRQlGp52pTcQEnTIokZiV51lqwiPbjtnd4FNodruUmKc3qDbKyEBLbli+EoUqu9BbyAk6JBFZmJX/cGGpAz25PDL3W29oQ5l8T0JstYiKUG+XAVB7k1vICRgMsomdtWVNiSlricVJuq5kpjXHcpiBynlPpPpT9JWhSyLgfQGQgKm7GmJXTXXxoGeN4df17qSmMmORDFXUiT3/SQE+Q4VBPkZegMhAZN1XGJXTXwp+BXHh187fBAqZxU4PpQkbN2TEORuKgjyi/QGQgJH7E3kqps9KAQ03pZQPepKYj51JIoPSxK2ZJpdPaRCDHkEfYGQ4AX5z0SuusGDLIEbbAnV864k5jNHonixrDKW2O1YkJ9Q4WLIK/QFQoIX5OWJXHVtAjnZkIT7Z2CnB2Uwi4+ZjiLI8qTtW8eCPESFHfIo+gIhgaPNd5tlMcuzCO/rvgnyfInSNs6xIA9WQZBH0xcICX6HPDORq65IICdvJiUAfWwI1Zu+HepNkChtzzgW5CdVEOQx9AVCghfkyW4vhjyblABcY0Oo3nElMU46Qj8mUdoedCzIA1WIIb9BXyAkeEEe7fZwrGeSdR8Sl73/wLdrzDJbjbZ3LMi9VNghv0lfICR4QX7ebYpaslm0vycUqimuJGZYQHflWoaz8/Rb9AVCAkfrn8hVhySQk7uSlIDEjUHddWTu70ASm0iUtmscC3I7FQT5bfoCIYGj35/IVR/y6D5d4pDCSFcSc6cDSbxQorRd5ViQr1Lhpt479AVCghfkWxO56i0J5KRrkhLwlMf5uU5CBzUkStsVjgW5pgo75Mn0BUKCjyG3SeSqTRLIySNJSkDfhEL1uCuJqeOgXLxMSbzeoRzvs11L2tPxHn2BkOAF+XK3+RDJ9mnuYVksfjruQzXX15ivwkB8buMy83kSpa2zQ0H+XY0WTh/QFwgJHO38xM66zFJQXk5SAu4xfFoB5uA+VJYqNulog5H4zacY8kMOBfkzNbpOf0hfICRw0rISO+sUS0GZmqQE3FrqSZsxxGGpe2ejAQbgGxQY/A4NJb7lKYeCPEyNHfI0+gIhgWOnZ8hAS0FZlKQEdCz2lCW4HxV8kZ46GIifSvwOzSU+f7RDQb5XDUGeTl8gJHCyTkrsrO08qZTW7cgTfrFZUbkyLsdt6I9hGIXx+BAfYSrGYwyGYwA6o6mjo7lGGIp1nlzN+NKhIF+qhCBrM+gLhCiAOJjIWasbfs3/mzouLm6sxF2IW/67LNyAwfgMf9oQtz2Yj9HohkYJnvnXoV8n5EjI5yg+1jmS4+22flIfxkx6AiEqCPKmxO66yFJUbkuyK/R+DLEMU9RHf8yxUfPCiF2Yjl64wMbP0RSTMUqasFVGoaOfc6YacgzxKT2BEBUEeVlid7W+Pv1iklkWDUz/X1U8ip8hg2UYYSNCnClN2FqFsfQmBMTH9ARCVBDkb93WZ1gkVRqaYjz2QC6/YQjq+yJsQxz+ZE0UEWSmvRGihiB/YieTN9dCVAqS6KpnlnmxGF5RgDno7nkmxzxHP9OfatzS48UQQpQR5LfsOOz7lsLygJSylXPhPVswRGrlipIR5IOOfpq3VZFjiCn0BEJUEOThdhz2dkth+dp1mOIr+MdevCH1Ksjfo6vDn+RmZQSZ1d4IUUOQH7d3/XiThbAUuojQVsaryIffFGAaGkmXtVmOfoZcZKizQ2Y9ZEKUEOQH7bnsCEtxGZqkEHTAGgRFAT6yyPRwPrIdpui9oY4cs2MIIWqQuCLyoXGRZYbtTlR1LAJVE1TJ8IMDGI1sSaL2tMN3t1BIkPVx9ARCVBDkVnaddr6lvDzhUAKuxh9Qgz0YgooS9sfbHL11iUr7Y4gx9ARCFCDeyHn1CeOIqJPshV4O8xG85g+b9TTMr2F/6vCNj6olyK/REwhRQZBr2XXajATx3rdsH+NNh4p86qIu8gjHV7urKCXI+qv0BEIUoFy6fbd9JMEh2Q22yl/+mECs8vEtnsGduBpN0RYP4ytH9SE2YCg6oiWuwo3ojSmOAgn7MCSpa9R9HIv/y2rtjyFG0BMIUYCM0+27bQVsSHDtIlHlt5bYYvmElRhgcMh2m+0Ax7RSd/HScRM+TVCvrnhLpfaOe4QUOpTjA1KbRkkZL9ETCFEAcYLzopnmLLbshHcPDlh8diPuNy1G+blNqatjWv/YSY7wdNSzPSO9HcsxME41OYY2lJ5AiBqSfNDJHvn3BGLzo+nhXh/Lfeosi6hqA+yQUD3tQQcXUPbheVuJfN0c7L3/Yr+tsqA+j+fpB4SoIci5ybdeMuJXXGLwuUGWn1mDSoZvq4J2eMtR9bd5eND03uBQR8K5G8NxToLZaIxhjq+2DFdPjiGepR8QooYgr3bmvJ8lEJwfSrUqjWNcgs+MNris3RPfJn2pej1exfkG8umUnRhm8JzStThGY7PtC9NVFRRk7Wn6ASFqCPLPzpy3PvZZCM6oUhUa0jExoUx9WeIz9fC96zS2Xehe6nAwuSvWOeiC9IRJgR0xBXsTPu0RFffHEIPoB4SoIchznbrvw6Z33u4yEKoPbZairFHk8G8b5PD2kUPGOLpaVnVOfHVkiI3KF1XQC79YPOU7VXrolRyP0w8IUQJthnMHnmIYO25scAg4w7bk5WE+JuA1yUXqczERYzANWyU8qxAL8IiNG4lNMd5wr3zAgwpzkkIWA+gHhKixQ57s3IGzsLKE2ExB5VL/qhJmI3rkIwfdkZWwV/cA/FrikwMVlWMB0Zd+QIgaO+SxybhwY2wvUvK9h2G5nfmILnsxFbcmaAml4zq8fyT3eqY6DZtKj970A0KUQB+WnBM3w24AwApcZvi1fT2iz3ZMwA0J4sLZGIJcrPOwdZSEkMXD9ANC1AhZDEq+D94eTDbMIH4E+5E6bMCLuMhypiqqeBmk6OhJPyBEjZDFw8k78nmGheenIhVZjH5K74ItgysP0A8IUWOH3FWma7fEOqQuezEJzUIoyNp99ANC1Igh3yXLreMY7LCvXFT3yj0Mck6UHl3pB4SosUO+XY5Tn4scanGRS9evK5t1bBCyuJt+QIgaMeSOMlz6BvxJFS7FfHRSOdnt75BFF/oBIWqELG50687peDGJMpSpwlJ0Vl+U76AfEKJGyOI6d858fqQvgMjhe1yntiDfTj8gRI0dcms3rtzJVcmeVOIjg+ZU3CETQorHkNsm68bl8WoSDYxSl224V1VB7kw/IESNkEWH5Jy4Lr6jxjpmsklvlIAP9e6kHxCixg65UzIufCd2Ul2TzFKuxbQ3QojJDvkOp+6bidHUVResRkNenSaEGAryPc6c9xIspaa6LkekWLGhvvQDQtQIWfR34rr3O+oBTcxYoVQhIjY5JUSVHfJwu25bGZOppNL4XKHrIvow+gEhauyQJ9lz2jr4mSoqlcfU2SG/QT8gRI0d8pd2XLYpNlJBJbMX56siydPoB4SoIcg/J3bYy7CD+ukB76siyPPoB4SoIcibEgcr1lM7bVKId9ERbfEoltj41wVooIYg/0Y/IEQFjhL5iWq5/UidtUk+7izS3soOr6ohyDvoCIQogHZmImcdTJ21zePFuk3bYaMiuRaZJ9MXCAmctGxrR62HA9RZm8wsJq6P2fzU1WrkWVSiLxASOHpTa0d9jTpr+/Zd0aseNbDF5uf6qJGJ3Ji+QEjgWHfUq4JdVFpb5KFNUXnDdNuffFuNHXIn+gIhwQtyX+uabqWZjevwNDZTg4tlSxSvdPyCg89+qYYgD6AvEBI42kgrNx1rkNZV+/BX8kXU4cMcRPdis9bDUdn+xWrkWUygLxASfAz5Qys3LZ1L+8eR/1eTfaYBALkl+uV1d9jwVRFB/p6+QEjwO+Qfrdy0dL+8VUX+bxeqMeajTrEZexD5jp+ghCDvjpWhNxAStCDvMnfSuIG4HEBmkX+R2v2mC/EaMorNWN8kegx+qMj16fRy9AZCAiXjdOvOIEYU/YLeIoXleDPalbjROCqp57ysSsW3JvQHQoKNINe2dlKjYvQfFfsXH6SoHOfg3GLzUA2zknzS3aoI8kP0B0KCFeTW1k662rBeQ+Mi/6IWNqRgxYpnEC82Txfh16SfpkwJzrfpD4QEiuhh7aQ5hhLyCyoU+TdXGBz9RftGXusSs9QO25N+2q/qNHJaRn8gJFhBftnaSc0uOEwqtkNslEK75M9L9cLrizwXzxuqjiAXVvgvPYKQIAX5c2snvdFUSD4oll9QF7+nxPXo50qEKrLwvstnNlap93QzegQhQQry+kRtTc17TM8olgBXK/Id91aheYnZuRIrXT7zG5XkGPpgegQhgZHxr8ROOslCTuaiSrE8gyhnJb+LrBIz0w17XT/1VqUEWXxLnyAkuP3xeYmdtE2Ca79FI6qV8EVEL0ffXqoK3lQJz12sSHH6I4lveVkn0SsICUqQ29v4GotllqKyotjV4QzLHXU4mXW4nNLf42rXoYpD3KTW/hgCaZfQKwgJSpAft+OktyWQlTVoWEzAh0ZIjPegd4ldbHkMdZVV8TcfKyfHAqIvvYKQoAR5iq2jHixMeIn4ymKf6CVJsoLm01KXNprY6iVth90lihIpMj6nVxASlCCvtOemrRKWzNmDDtKuSqjBRnQr1X17EA5Ke/4DKsoxxD5GkQkJRo5PEYV2HfV1Gzm6PYt9ogFWhFaMCzC+VE5FYyyW+IZpasoxBLRr6RmEBIB2kX03rWTj4kchBpcot/NlSA/xLi+Vjf2SxL0x8CuqKivIYgw9g5AgBLm7E0e9xlZceEqxyyLpeN5h94ygWYy2pX7z27FO6ju2FzsEVW5sjR1D3yDEf0Ee68xVH7IlNwtLJIm1w5aQiPFq3FsqL7iJSXml5DmA60u8o4ZqktyQvkGI/4L8o1NXtVeAfQOaFvvUefg2BBXcHkb5Er/tBXhH+v4+H11KSf7nqgnyc/QNQnzmrBO1PMdNfjDTluzsR98SraD64oCyYrwVg1CxxG9aE8OxX/qb8nFfifdUx2ocRGW1BPl3egchPiMaJuOslfGNTfGZXEJm5GYpyGILnkClEr9jNl7BPk9qxd1Tqmfhl0re2NOr0T8I8VeQeyXnrJXwtU0B+g2XlcrjVWmfvBZ9S4lxdTyHXZ68bZ9BIaGRh//fSNUEeSD9gxB/I8hTk3XXivjKpgjtxSMljskuSbrznFyWoVuJftECVTHEIzEGctGy1DwOOPJ/f1Itirw2djQ9hBD/KCM2Je+wmfjYthTloG6JT3fCqkDFeC5uKZVNURlPY5uH8t+g1Bz2LpbBna2aJF9GFyHEN/RMl19qMSjhdeq/2IWeJQSwAgZhRyClgsYZdOiohIHY6uFb3zc4tOteIn/jbtUEeQJ9hBD/Isjt3TvtPQ7yEL4stUesisG+Nkf9FX2KldP/6zbh057mSe/DowYzdz/yS/y7CcrVtCh7Gr2EEL8EebQMt22O9Q4uRAwvVR+iMh7HZs+leBcm4QaDUvDnYrhnMeND/IhLDWbN6LvFWvVqWnShlxDilyCvluO25zjqnPEnupcSxop40LPWTwcwHV2KXeb+a9THOA/yjItyEC+UumoikIG3Tf79RaoJ8nx6CSGhiCAXH10cxYMX4gaDZ1yCEVL3yvvxFXrgHMPod1tMLxUykM18w27SWZht+on+yu2RmY1MiC9od8p13foO97gLSlRP/mv32BETXMvyb3gNHUrlF/8liL19KAq6weB7wKGrMVbNsGarV2ZoBD2FED8CFpNlO28cPR2mjS3GbYayFcfVeAJfYKdDGVyF9/EQLjT9CRtjDHb7kMcxxOQidPcEt/8OqHaBGmK/fgZ9hRCvOVrkupXfqobx5NEOi/EsxwDUNE2sa4A7MRRTsdgkKW0/1uAbjEM/tEN1i5/2fDyOX3xJqhtdqh3qXzNjJ2/7VvX2yH3oLIR4vT8+z62j1sB6g7rBAgItsdTx4dfH6Ij0hGWNzkVjNEULtMU1aIoGtopWVkcvfOtLReYdGG56ueNmrLX1jPHqCfKf4gT6CyGeog9066gXAyjEeMMv2enohz1JxF1fRgvEJUa1e2OW1C4fVnWUB6Gayc9RG5MdzIGu3sHeLfQXQjzFeR3kkqPFYQn5A60N/39D2wWIStZem4SurroxZ6MLxuJXny6bHMRHuMn0z0gcvRzmOV+u3h55aawMPYYQ7wIWwr2bdixS4XeU4T5Zx2Mu9qcrMQWP4TrbvTRq4wYMxAf43fZ1brcUYgH6msa/BQRuSKLc6FMqtnS6nD5DiHeCfI97J72vmIxsxB2G/+oqG41RE7EdP+ADvIbB6IEuuANt0RZt0Rld0BPPYAym4UcfcieKsxQDcYHl/DSzWci/JPNUFOSZ9BlCvBPkme6ddEApKZmKcw3zfj9DlMjFaFyVYG4a49Ok9+l5ltki7LFHSNTk+BRx0L2LjjDcy/Y0OJTSMSQiYrwW/Uyum/w9rsMnLnM6uqooyLPpN4R4I8gdZLjo+6YXhhsZBjgOhFyMV6F7qXL2okRB0e5Scp2nqSjIiDei5xDihSBPl+Ggcy1qSDxmsE++1oeabl6xDYNQwXI2GmCotHrKewxLIQU+5jHXghDppP/Peadpo2Hd8SPHIJ58oWUdB1XJwwjDO4l/X5DphfmSMzs6KrlH1q6k9xAiGf1uOe6ZqCfzRjQzKAU/L2RyPNewYtuhUQUPIMeTmnFvKSnI+gLukQmRHbD4WoZzVrfVKeMug+aoM0Ijxptxr+nv3wbvYq+Hb44rKcmiOf2HEJn7Y00UynDNpjavTgwvFU1Ox1uhkOOPTK6k6OiERZ6/vYWaQYsVWcfRhwiRhvawHNe807a0vF/qiEr9NLg/0M7k974dy335CV5Wc4cM0ZU+RIgsymgr5Djm0w7EZaFBDbQ+nvfrSP4Q72VUNLl7518E/DdVBTm3wn/pRoTICVhcKssx33ZYl6J+qSd0SqIenPcsRhOTgkXv+FYj4xCNFJVkbSj9iBApiImy3PJbh/KyCVeWesbl2KCUGO9EP8OazHE8iu2+/zRPqbpHzk+vQk8ixDUV/iv2y3JL51K6y6CxaR38rIwcz8T5hr/pFT4c4Rnxo6qCDP0z+hIh7gMW98tyyaykvr4fxN2lnlTVogezf/xu0vukIob4VODeiAbKSjKviBDiPmDxiyyHbJ6kxBRggEF3kSG+NFgyv+g9xOSqcjv8EeifiSfUFeQVbOtEiLv98aXyHLKHC5mZYFCi52bkBiJ5hfjQ4LjxUEvS8T4f4pXmB2UFWUDrT48ixM3+eJo8d3zFldDMQpVST6yFT30XvO/Q0uTqx4MB/YEo+efiQnUl+UBaZfoUIcnujzNFgTx3/NKl1CxDXcN99w4fxbiDye92OeYrc9A4UOE9spjNyhaEJLs/HiHTGde7lpo/cbVhhYzRPlwYmY9OpuWCRiFPoUS8hSoLMrSO9CtCkqDsaWK3PEesLiW6uh8PmXTh+9yz6O0BTME1pr/XPdio2DWVQpNUPEXG1vT/0bcIcYysChaHRltpgjPFsFu1QBNMk5558QcGWXSIvgQ5Sl7k7q/2HnksfYsQh2QcL9bLdMPHpWYAX2vyljoYhJVS3rEeo9HSoIfJX+NcjFMqUFE8vCLUluQr6F+EOIsfd5brhB9IlZx8jDBtWaSjBV7E4iR3y3uRg2fQ3EKKBbIwRMmaGn9nbtdRW5LXpZ1KDyPENtnHipVynfB3D2qb3Wz5xhrojKGYgTW2rmgvwiQ8jpYon+D3qIrBSqS3hTjTAgLidfoYIbbRb5HrgFU8ulc3C5fYurTdCNejKwZiOIZjOEZjPMbjZTyBHrgdrW0fgtXAkAAKBiXDYtUFGdq19DJC7HG0WC7X/dp4Jj15mIiLfRCQJngb+xEeGqouyRvO/g8djRA78eP2st1vkMcx0w9NKhLLKYrUXaFrH3YZrPweWbxJTyPEzv54qWzn86NJ6XLLFLVkRjraYrLSx3fm/Kq+IEO7hs5GSKL48Y3yXW+zTzJ0ANPwAM5z/fNegJ6Y5uOlbC+4TH1B3qydSX8jxIKs48Rvsh2vnu931X7By7jVcZmdDFyFXngLKxAFhoVgjyw+ZW0LQizQust3u3sDE6Ud+AavYwDuRWtcXOqGXzXUwqXogIcwDO/hBxxAlPjDMpdamdGNPkeICfF/iy3yne51hWRqP7YjF9tDlTGRLM3DIMj7RXX6HSHG8eOBXjjdUpAgGBUGQYb45awT6XmElA5XnCmzvttfo2bgXTRSlT8N+2ErOF6i7xFSCrn1j/8ad1IZA6NdOAS5UL+a3kdIMdKytDwv3G0cdTEw3g2HIEPkajo9kJCi++MvvHG236mLgbHHpHa0gmNe1nH0QUL+kuM23jjaeVTFQLk3LIIMMYReSEgsFovFyv5DrPLGzbpREwPli/AIMvSW9ERCYrGY1t8rJ5tITQyUPJwbGkHWdomK9EWS8sTTxB6vnGwNNTFg+oVojywWl/0H/ZGkevx4ilcOVp96GDg/hEmQoY2kP5LUDldc6Z179aAeKkDjUEmyfhN9kqQsmSeL1d451xSqoQIMDZUgi91plemXJFX3x0M93OvgT6qhAqxBPFySvDTzZHomSUH02iLfO8dqSi1UhLbhEmSIt+ibJPU4RnzvpVsNoRIqwpSwCTL0W+meJNXCFQ9761SLqYSKsA/VwibJ+7Sa9FCSQsQriH1eulRtlt1UiIdDt0fWVohT6KUkVThKzPbWoXpSBRViUegEWUBMjx1NRyUpgejptTvNoAoqxeVhlOS+9FSSCtHjSt6GKwQqYg81UClGhlGQC7Vr6a0k6hwj5nntSh2pgIqxBRlhlOSdWiU6LIl2uKKv9470BhVQOW4LoyBDLMn4F32WRDdcUUMc9N6N1lL/lGNGOAUZYnKsDP2WRHN3fIL4yXsXupLqpyB5qB1SSda603NJNAV5lB8ONJjqpySPh3WPnK83pu+SyKE/4I8DLaL2KcmKsAoyxBYh6L8kWnLc2MtSQn+PC3hHT1muCa8kL2Q3ERIlOc4U2/xxncepe8oyPryCDDGGXkwiQsa/xM9+Oc4P1D1l2YVKIZZk1oAj0eBoMc0vp7mQAQul6RbmPfJ+cR6dmYQ/XDHYP6dhwEJt5oRZkCE2pJejP5Nwy/GNfroMAxZqU4gG4ZbkhWf8kz5NQktattjrn7swYKE+z4dbkKG/w5t7JKRoZ4q1fjrLE9Q75dmA9JBLsuhNzyYhRJwg5vrrKgxYhIEbwy7IhaINvZuET5BH+eso9RiwCAUfh12QIfbGz6V/k3DJ8YN+uwkDFuEgD3XCL8nryp5NHyfhkePL/LkozT7TYeTZ8AsytPm8TE1Cgn8Xpf8eDRiw4MGev5I8lp5OQkDWSf5dlP57DKHOhYhbIyDIAuJBejtRnTLapACyQ7GKKhciZkVDkAv0q+nwhId5pUZLalyoCP2NvSNtUNOy6PNEWbSLtbwgHONNalzIGB4NQYZYLk6h3xMlSS8nNgXhFOWRS4ULGbmoEBVJ/iB2FH2fKEfG8WJeMC7RmfoWQu6JiiBDf5TeT9QLV4wMyiFmUN1CyLeREWRRoF1J/ydK4W+ZzaKjBg5S3UJJ4+hIcm65dGoAUWd3XFPsC8oZelPZQsro6AgyxPdnnUgdIEqQebJYGpwrLKKyhZSdqBwlSX6TSkBUoIz+TnBu0JBXpkNMjygJMvS7KQYkcES3IJ1gKFUtxPwQKUEWB/X61AMS7GFebXEgOBeIYy1VLdQ0jZYkb2RZThIgaaeKlUE6wM1UtJAzIVqCDPFN1nHUBRJQ9Fi8F6z5f0xFCzl7cU7EJFkbSmEgwUSPewZr+rWQR0ULPX2itkeGfiO1gfgfPa4fTCGhv8fjVLMIsDxygix2a5WoD8RXMk4X64I2/BVUs0hwQ/QkeTEbPBF/o8fvB230ralkEWFG9AQZ4mWKBPEN7b7gTf5dKllEKMBFEZRkrS11gvhCWnaQuceHRlXspZJFhteiKMi74hWoFcRzsk4Sy4I390epYhFiN6pGUJL1BRnHUy+I19kV41Qw9h+pYpGiXxTjyBDPUS+It3J8iwqGfjkVLGKsRnoUBblQNKdmEM+IV9B2qWDoY6lgkeOWaO6Rc4WgbhBPECeIRSoYeWXson5Fjq+jKcgQc7OPpXYQL8IVw9QwcR7oRZMroirJT1A7iPz98eWiUA0DX0rtiiTuK79dgv5orWATVL0x9YNIJeN0sUEN825F5Yoo+1DDlWWciwMADuJO9ST5z3JnUUOIPMqID1Qx7g+oXJFlsCvLqH34Kfl4WD1JnhU7mjJCJKHdqYph18QB6lZk2Yjyrqxj4ZEnDVdPkntRR4gcOa4k9qhi1oOpWpHmXlfW0anIk15W7Sp1nl6bWkJck32smKeKUaezh17EWezSQiYXedYrqu2Rl5x1IvWEuN0fP6WOSd9KxYo817osOrWqyLNGqFbd4kXqCXGFXk/kq2PQs6lXkWeqSxtpgFx1d8mFWhNqCkmatFPFanXMuSEKqVeRJw91XNrJ9cUOfhU73ttQ4b/UFZIk4k2VjPkVqlVK8JJrS7mlWPvbQWpJ8nvUFZJc9LiFSoZcGdupVSnBNmS5tpbORSS5EL3UyrfoRG0hjsk4XWxUyYwfolKlDI9JsJe7ikhyPu5SSZJ36Br1hTg9zntHqfNpLKdOpQwbXF4QKS3JB9FeJUmeGStDhSFOosft1UoYupEqlVI8IMVqigYu9qK5SmGLLtQYYpuyZ4tctQR5JjUqpfgNcemSvAl11bHo3ekZ1BlijzJimhyzq415uF/CcxqggBqVYtwuSfruLZIsuQzV1AnC5bDcELEXrugsy+g+hNvqBIfGaOpTyrFImvQ9UeSpc1FBnV1yV2oNSZzspoudcgyuHQDgMtfPqcKWTSnJddKkb0yRp74LXRVB3pdWmXpDrDlKzJZjbuXxG4BVEp7Uj9qUknwhTfri+KTIc59UZ4/8dewoSg6xClfcK8vYngEAPC8h4e13alOK0kSa9FXEd0eeWoCO6kSS76bmEFN0Tdslx9DqYx8A4FLXT+pIXUpZ3pMofdnYcOS5O3GxMtkWaXHqDjHbH0+Xm6b2rYQn5VCXUpZ8NJAofs2KFB36XZ18i4+pO8T4OK+jLCO77bDZd3b9pMas8JbSjJEqfr2KPPlzSZnOEsIW7ag9pPTu+P9kXQapjHUAgHVId/2st6lJKc0+ZEsVv6L29IIqe+Qt6f+j/pCSgvyuLAMbftjgn3D9pFrYT01KcYZKFb9M/FDkcE+Z+hbjqT+k+HFea1nGdTEOAgD2orrrZw2lHqU82yUU4yw66hbpKJLruhi+tNGMGkSOcPZ/5JXa/PKwsb8mIfSxjXpEMFCy+HUsci6xABlqCPLqrJOoQ+Sv47w3ZB/nHZSw9+hNLSKQVYyz6Bhb5OmqdN3TB1OHyCE5vkJehG71YTOf4PpZ6cX6B5NU5iHJ4lcJK448uxC3qVGQM09UpxaR2Bn/FH/IMqpnj+SPNpRQOJEQHM7Xkb1HbnL4pAMAduACXqQmyhznDZZlUOdjz2ETf1/C076jDpEj9JAuf8VrwKmRk8xueylPvKo4KMucph35Eui+BkFLahApwlrpe+Q4vvbw4DDJsTXjdGpSKnOUmCPLmNoeMe7pEp72CTWIeLxHPh87jjz9AK5UQ5Jfoyil8nFeF1mGlI6lR/bHV0goTZRPBSIe75EFehZ5/gpUUkGQC0VD6lKqyvGZYpssQ+p/xLA/kpyWRMghHvSgl/ncIs8fo0Yc+cfYMdSmlERMkFfacOdhoy5AY9dPq4G9VB9SilUSaqOUvle6v0gC3A1qhC3uoTalohxfJs+E3jxi1DIq2D5L7SE+xZEFBhd5/hrJ17STHLk82ks5yv5D/CrLgBodabWej0tcP60CNlF5iCEbUFG6/KXjZ+XCFuJlKlSq7Y8fl2c+s46Y8zuSD1oIKU5/D+SvWZEj5AK0UUGQC+K1qFEpRFplcUCW8dxwxJjzcZGEY5blVB1iSq4nQYWiXalXo7IKkvwlVSqV9sfT5X3hW3rElCdIeB476BFrBnsgf1WKhcleVaPYUGvqVIqgt/KiKc5+nC/hed9QcYglOyXU2S49ehR5QwGaq5D+tuaMf1KrUuM4b6Uso6mMP4+Y8UgJz2tKvSEJGeaB/MWxuMgbFnuQYJfE6Eu1SgG0/vJM5u+OHrul9D57n2pDErLPkz4f1xV7x6MqCPKesmdTryJOPE3skWUwdYpc4HhGyvPyqDbEBt4kp00v8oZdqK2CJI+iYkX9OO89eeYy+Yj5bpFy9v0KlYbY4iDqeyB/DYvUSAamKJH+ptWgZkV5f9xIZonvgiPG21fC887BbioNsclkTwSw+JZAiYvU06hakSX7WLFEnqn8XU12LSpIeN7TVBliGxk1U0qPakU6UgMrlGiAql9K5Ypqutv98sykbRHDvV9KN77NVBnigE89kb8+xd7RV4U98iI2doqmHJ8htsszk4VHjPY3KSlCj1BhiEOu9UD+KmBDkTdsRw0V9sjtqF5RPM57XZ6J3FLEaO+Qct+PHaaJU+Z4In+9i71DiVt7q8QJ1K+oZR/XFAXykuiXHDHYH6FLeOKdVBeSBG093yMflNA/XcIe+X4qWNQCFp/JM497ixjszVKeuJjaQpJgvg975Okq7JG3ZPyLGhalcEUzmfVjfztirD9I2R+3pbKQJLnB8z2yN/twx3vkR6li0eEY8bM3ZVjkmOpX1BWSJPN82CMvlrLtcDm2lz2NQhaV+PGdMncP644Y6lxJF0wIUXuPfIcCe2RtAJUsEmSeLDbKM4t+0l1hKjWFKB5HXoZ48IK8K/1/VLMoxI8HyTOKykWubyyU8sT6RdrnEKLKHjmzSGFZAOiqwh75KapZ6MkoK6+6W/HrzZ2kPPEN6glRco88uNg7VqlQIXkvy3GGf3/8pjyDqIrtRwx0iZSDjmzso54QJffINYoUlwWAHiqkvz1PRQs18VqiUJ45PFPEPO+WXOCeENX2yGOLvWOdlBJaLse+jLJUtTDvj2fJM4asIpWwVkr5AlcZ26glRAqtPamPXFDsHY+osEceQlULb7rbFTJN4YkiptlLyhP7U0eIJD73RP5mFnvHHyrEkfdknE5lCydlxLfyDKESthwxzG2oJOGJGUUymglxy5UeyF/HEu+4V4Vci/6UtnDuj1vINIMBRcxyqJQn3kcNIRLxoodIHKuLvWOJEnf24v+muoWPo8QP3txcypPS81fHMmoIkUge6nogf4NKvKWjCnHkHpS30KHfKNMEeknfiXSkghDJvOZJ8tuBYu+Yp4Igbyz7DypcqMg+Vvwq84vbyiIm2VTKM7+lfhDJ7PWkv8dHJd7SUoU48p3UuHClu90uc/nvKGKOcgoKXU31IB7wrAfi16HEOz5TYY+8Ous4qlx45PgEbY3M5f+uiDl29mTXQYgMclFZuvill6j8VqhEDxHRnjoXHkHuJnPp2xQxxs1SGqPXQx61g3hCbw/E7+US7xipQtDix1gZKl0oOOOfMsttFk+OHy7lia9TN4hHrPbg8kajEu/YhooqSPJF1Lpw5B8/LHPZL0VhkS9rDSQ8sTr2UDeIZ9zjgfj9XOIdD6oQtHifWhcCMv4lcmUu+1tFzPArD8oaEiKX7z0QvydLvONnFQS5ID2Deqd+/LinzEU/p9huVsaBXgVsomYQT2kmXfzqFfmeeIhrWYyT2MmvEOu9uqck50CvJ/WCeMy7HojfDyXeMUUFQd7JS9SqC3JXuQk/Rcv/vCzlwvQK6gXxmAPIli5+A0u94xwVDva6U/MUJus48YfM5e5SzAQvk/DEW6gWxAcGS5e++qXe8bAKe+RVsWOoe8qi3yZ3uecXMb8lUp44j1pBfGCjlPBa8bG8xDu+U0GQoV1L3VOVo7UVMpf6ymLmN0jCE5tRKYhPdJEufcNLveMiBQRZ/4zCp2r8uL3cpR5XxPQKcaGEJ06jThCf+Fa69LUs9Y6hKuyRC+PlqX0qcpT4SeZCV8YuyeZdH/nUCeIbl0uvabG1xBvWIa6CJA+i+KkYP24td5mLp6fJ6KE3hhpBfOQt6dL3fql3XK9CFHlzxvHUP9UoI77zLu/yIKrzwjQJGXslWG3x8WCpd0xS4mBPb0UBVIz4VXKXuEkxs5NRAZYXponfDJQsfHVLvWG7B9kcSeyRZ1ABVTvQm+XdgZ6MUirleWGa+M5q6THelaXe0U6Jgz1WtVAKrYbcBa5U7ECvALUkXzEhxB86SJa+N0q94Q0lghbicaqgSoI8Vu7ydi1mcgskPDGH2kACYJpk4bu71Bs2qZFpsTH7WOqgKnJ8pjggd3m/KmZyT0qolVVAbSABkIdzPY4iK1L3Ddo1VEJVEt4Gyl3a80rkC1/q+okvUhlIQDwuWfg2lHrDCDWCFu9SCZXgrBPFFrlLO6iYua2SkFC/kbpAAuJ36FK9Y5rB0aESgnzg7P9QDVXIr7hD9tIuK2Zuo1w/7zaqAgmQVp6W4QSAxmpkI99GNVThQsgvcpe1aQljc38X6XNqAgkQueXqWxq8ob8ae+TZlMPgD/SayF7WUcVMbY/rxPcLWMGCBMpeZEn0jyqlmjkBM9UQ5EJNpyIGfaD3meSvPVhfzNS+dP3EIVQEEjAPSPWR1aWev1uJ+3oC2sNUxEBJryIK5S5pixKm9pTL58WLNYEiJAjmSPWR6QZvaKnGHnkJNTHYgMVIbwMW7nMsO1INSOAUop5EHzH6zjdEDUGGqE5VDIzMk8VO2QGLdZIjyJ9SDYgCyOyxd4fB8+crIsjaAOpicAlvnWUv5zUlzGy2y+fVQB61gCjASonZyI0Nnp+HKmpI8jLqYnCC/J3s5RxZwsyedvm8h6gERBGukVh6q9Dg+R0U2SOnZVEZg8mvqC1/MVdLPqqYSx0gijDW0+vTCkWRe1Mbg9kfj5K9lCW/iu1FeZc1MVhSiKhCLtKlecq3Bs//QhVB/oHaGADxf4vdspfyiRIm5rax6QCqAFGIG6V5ytuGgq8rIsl6JvXR/4S3LvIXsmSA4XWJXfkICZq3pXnKM4bPb6DKHrkX9dH/gMVC2ctYtVRGhLv7TQ0Mjz4ICYodqOBJR/a/uFcVQZ5DffRbjuvIX8a7ShnYVR7sIggJjk6SfKWT4dNHqSLIBen/o0b6K8ivyV/Gd0qYV57L/cQy+j9RjCkeVUQ8xAJVBBlaW2qkvwd6e6QfBGBLCfNa6up5l9H7iXLsRkUp3lLHJCSiiiCLN6mSfmYg3yp/CUvfPprs6nnD6P1EQTpL8ZYMk/OR81QR5K2xo6mT/gUsZslfwj6ljOsxV/vt1fR9EuGgxV7Dp9+gTtDiAuqkT6SXEwXyF7B0p7C2Lp7WnJ5PlGSHy8tOf43Nhk/vrY4gs8iQb/vjBz1IJcfWUsaVzS7TJILcJMVjVhk+e4w6UeSFVEq/BHmxHxHkXcywIJFknBSPWWL47K/VEeTCCv+lVvpAWmUvlq93KdP6ycXT6tLribL8ibgEj5lv8myhTtCiBdXSj/3xIC8W76NSpvWRVHknRB1aSPCYHJNnV1RHkIdSLb2njFjpxeKVLic4zMXTvqTPE4UZKcFjvjZ5dgN19sg/US69z0Cu78XS1TIwrIeTflplHKDPE4VZ6eEOuY1CUWT9DCqm1wGLEV4snVEj0uRv/d9OjyeK09CzHfK9CkWR9dZUTE/JOk5s8WLhjLroNpVaK5YQlejnmSA/rpAgi+HUTG8DFld7s3AzDQwr2UugcWyivxPFme3aZ+aYPPk1lQR5CTXTU7Sx3ixc6VtH+Um3u2lGbyfKsx+VXfrMQpMnT1NJkJmL7ClHexOwuMDArHKTftoL9HYSAtxWRl5u8tz5KgkytCspm97tjy/2ZtE6ST2H/om+TkLAGy69Zr3Jc5cqJciiL3XTuwyL571ZtMcNzGpR0nVi2baJhIG1Lr1mp8lz16glyB9TN70T5N+9WbQJEg89utPTSUi41FUxrnyTp+aqJchbY2WonN7IcXWvFm2egVl9mOSz3qWfk5DgJvWtiulTD6glyIiXp3Z6I8h9vFqyrQZmNUnaFWxC1ORTFz7TyOK55dU61mN3PY8EeaE3C3aOoVGNl26mhKjFzqRTOwXaWjy3ulqC/AK10wPiaaLQmwW7xtCokiu0zSpvJEw0T9prulk89UKlBFnPoXp6sT++x6sFMz6GeyWpZ02nj5MQ8VTSXvOkxVMbqBVF3s5jPS8EeaZXC/a0oVENT+rS9Db6OAkROUl7zZjQ7JAF0stRPyWTdZI44NVyGZvWCCltoAhRmf3ITNJrPrd46vmKCbLWhAoq+47eFd4t18eGRvVqEk96hB5OQsZ1SXrNGotnnqeYIIseVFDJ6IO9W64F0g713qN/k5DxfFI+UwkFFs88V7Ud8htUUNkR5O+9Wy7jv/XJ3PRfT/8mKRFFbmr5zJqq7ZAXUUGlcvZ/RIF3y7XP0KjedvycC+ndJHTsSSoXuavlM2uoJsj7Y8dQRWUGLFp6t1jVTIxqmmQjJURNrkrCa4ZZPjFLNUGGnkkVlRmwGO7dUjWQ9lVuDH2bhJA+EhucAkAedOUEWbuCKipTkJd7t1SXmZjVYsdPWkzfJiHkgyTy7XdZPG+zcnIsoN1JFZVGejkvl6qZiVk5LVCfiYP0bRJCNjj2mcstn7dcQUHWB1NH5e2PO3i5VG1MzGqbw+dcS88mIcXpRY6elk+br6Agi8nUUXmXQt7wcqnamxpWRUfPGUC/JiHlLoc+M9HyaZ+qKMhMfJO4Q17t5VLdbmpYzkqkfEC/JiFllEOfWWn5tEkqCvJO6qis/fGZ3i6VebKas0ulq+jXJKTMc2Tp9RI8baSKgoyM06mlcvbHzbxdqAdNDaurg6dkWV4lJURldiMuseb3ACUFWa9NLZVzKWSgtwtl3pT0aQdPaUWvJiHmEge2PjPBs25RUpBFM2qpnJDFDG8X6i5Tw5rs4Cl96dMkxNxr29IrYE+CZ12q5g75NmqpDMqIbd4u1K2mhrVY2rkzIWpjvz/OjQmeVJB0hWWPBflRiqmMCHJFrxeqvalp7XFwBfQX+jQJMd/YtvTxCZ60Xs2ABfQXqaYyIsg3er1Q11kYl92E+Qze0iOhZqfNzUcGcqVJu8+C/A7VVEYE+QWvF8rqht3NNp9xKT2ahJyGtiy9Y8LnTFBUkLWvqKYyQhZzvV6oJhbG9ZzNZ3ShP5OQswQ5yEEOZmEyRuIxdEUrg7rGiXviPKGoIIvlVFPXZB0n9nm9UFZl5T+3+Yzn6M8kkmzBHLyB+3ExBAQqJ8ywANqqKsg7qKeuScv2fqEqoNDUuLbafMaH9FwScXLxGaYk/FeFqKaqIBfGjqaiug1YdPBjqayOKerZesJy+ishAH5VVY4hkHkyFdXtkd7TfizUEgsD68YcC0JsM0VhQdbOpKK63SF/7MdCfWFhYO/a+PzF9ENCACTXDsqvES9PRXUryKv9WKgJFga20UZ+Zkf6ISEAgGtU3iHXoKK6IuNfotCPhXrB0sQS38zvRz8kBECew6YOPu+QL6SmurulV9ufhephaWT92G2aEFvkYwquUneHzM7TLo/0bvBnoZpZGllOws/PoicScoT56IJ0FS9Pt6SmutshP+rPQlVEvuVf/Wz2CiHEEavQD5VVE+R21FR3R3pj/Fqq3yyNq4flZ9ORR/8jpBTbMBTVVRLkG6mp7gT5a7+W6iNLw/rS8rMX0PMIMWEPhuMcCnJEBHmjX0s1OMHZsdXf+Zb0OhKZPe0vWIzF+B45WIQ1NipX2GEnhihxoVq/iZrqRo5P8CfpTUCgUwKT6p1U12pCwrCH/QrPoTOuMhTNCqiDVngIo5GDDS7esgPPoQoFOczEy/u3VOcnMKefLT77FH2ahJJ9mIyOjhou1UJnvIbFlofg5mxFX5SnIIc26e1iPxdrbQJjamr6yXH0bBI6tmKQizBCFm7C61iTxHv/wD0OGqNJHu2pqm6S3m7yc7HeTWBIb5p+8nN6NwkVBzBUUkraZXgaC1Hg8P0/oh0FOYQ75If8XKwHExjRLlMT/pkeTkLET7hEsu/UwUDLiolGfI6LKMgh2yEP83Ox6iY0of4mn9xEHyehYQIqeORBl2OEo2O/g3gZWf7GkFtRVd3skCf5+/dzWQIDWocMo4IlSR5wEOI/g70u34P2+MyBR2xENx8jyqxl4S7tbZa/gvxSQvPpavCpbHo5CQnP+ORJF+IlbLX9U823UU9R0g65HlXVjSD/5K8gJ77gscTgr/nl9HMSCsb56k0V0BU/2D5kfNaXdDitJlXVjSD/6XO1VGxMaDodS32qHT2dhID5hgE3r8f1+NLmz7cMzb338ApU1eQpo+X5bT6jE5rNL4jznh4JHbttNuv1YjTBB7aiyvl41dElFeej3FmU1aTJ+Jf/ptPChtmUjCP3obcT5ekd8KXl+phgqybiMjT2cof8b+pq0pQ9O4CrlTYqG68pkTb0LL2dKM4yJcrF17MlyvvR27O8i9jR1NXks5AzgzCap22Yd/GWTqPo70RxOilTkdieKM9EDS/evoOq6qa0UK0gDOY8G+aSW8xc3qG/E8X3x7oygiwg0BDTUJjgZ16LK+W/eSlV1U2ORcNgzOVTGyb+dpF/P4MeT5Smh4Ld7a7BvAQ/9R50kf3WWVRVN/f0mgRjKtfbMPFCtDzy7+fR44nC7FGus91f4xb8nsDLhpbKaXI13qaquhHka4IylJ9sfQ38K6vzF/o8UZh3FJXjQ5dHnkrQk+QDmdnTz1FV3RzqtQrKTLrZMvRBh//1Svo8UZhbFRbkQx0ppyU44Kso6109qapuYsjXB2UiGbYKb+8/nDG5kT5PlGUfKikuyAICHSyrxM2V1fqJxTdd7ZDbBWcgPWwZ+y+oAIEd9HqiLF+HQI4FBKpigkXmxfdy4uCXUVXd7JDbB2ceGVhty9xHQuAgvZ4oy5CQCLKAQHuLffKXEmLJ+jlUVTeC3CFI47jflrkX4Eb6PFGYm0IkyAI1MMv0N5nsNpu6MOskqmpIQxYCcZuNmbbQ54nC1A6VIAvoeMr0atZL7p69jprqbofcJljTuIHeTEJObsjk+NC4DtsMf5tCd1fAeS3EZR7ytUEbxmf0aBJq5oVSkAUuNinylYs6yRenf4Wa6i5k0TT4Qih76dMkxLwdUkEWqInvDH+jucnXrXuQmuouZHFZ8GYxiD5NQsyToRVkgUr4xvB3Srays3YNNdUV8QuDN4p0m0d7hKhI5xALskBlfGvwO21PsjRnWhY11V3IopoKRtHUVp8DQtRjAxqEWpAFqhrWlRmdzLMKyv6DmuouZCHUMIpn6NkkZOThU3RUokuI+0oXWw1+u/rOAxYrqKguKXuaGiaRju/p4SQ07MfrLnIRVEyCK/0ddaTz50ygorrlGFVMogF20s9JCNiH13BehMT40Bhc6vfc5rwCHHMsJAQtdqhiEp0TtpwhJGimoW7kxFhAoDyWlfpdH3B687YR9dS9IC9XxyjYypSozO+4IZJifGi0QEGJ33emwzoWZU+jnrq/q/eVOiaRgfn0eqIkhRgTiqrHMjtd7nZW/e13qqkMQZ6k1t2h1fR9ohxbcWPExfjQHrkkrZzkWEyimsoQ5KFqGUVj7KL/E6X4AeengBwLCCwo8ZsPdvLpXlRTGVdDHlGv1QyviRB1mIIKKSLHAn1L/O6O6nSwV4gUQb5RPbPoWup4gZBgGI14ysixQN0Sv7395lRaXsa/qKYRqWZRegygEhAFeCKFxPjQ+LXY77/a/ifnUkulUO4sNQ1jKNWABMyglJNjgY+LzYCD4vtPUEvlUEbsUdM0hlERSIA8Y8NGr8W0iAnySyWySxhB9v9qyM/OlqwCzsOlaIm2uA5N0RCZnhnHi1QFEhDjE1rneZiMQhRK6NSs0nik2Cxsth1BzjyZSion7a2G2GZv0uujL97BUoMciE1YgHF4CI3d9qwtNV6gMpAA+DJBFTcdfbDn8L+tHSlB7llsHjbY/dwcKqkcOa4ptti5rjEIi20Z8mZMwa1S98z9mHFBfGYVqibYG+cU+ddXRkqQexSbiUU2P6UPpJbKyLCoJbYmmuo6eM1x17tdeAOXSzORe3GQGkF8Yx+usLTH1thU7N/fHClB7l3sd3vfriBfSjWVkfCWoNJbJp7HgaQNew7aSjKSm3h7j/hGT0tbfKBUyK5vpAR5ZLHfbai9T+0960TqqVs5rpoodnwdfndt3N+hpaQL1axxQfzgM0s7fMqgROyYSAnytGK/W3d7n3qfeuqSjLLaGsvKpnhOUuy2ENOkVAKoyUpwxHO2WR7RPWf4mVmREuTiVZHttXHSOlFRXVH2NLHEaoJrYJZUM9+NvhJ6j1XABCoG8RSrHeETJp9ZEyE5rlnsG8A6e58qEP9HTXWTd3yCnmN9n/1XD0x9oZTuvN2OJBsRIpv5Fmmbd5r2sylEjcgI8p3FfrN3mfLmiyCPsprey7HRI3Pfgc4STOZyrKRyEA/IQ2NTq2uG/RafbBsZQW6NQUVGM3bS80GOu1lNblPs8NDkC/GChKsjVTCF6kGkY344VznB8XbqlSAqlvKWSVVNmrRLtDzzqb0CuZ6b/UxUkdIQdRsVhEhkD2qZWtukBJ+dlsJyrK2gqiZ/L0+3upfX2Ac5BoCfcYEEQzgfc6giRBrPW/zxT0RuStVMLjGGU1eTJPtY8Y2VwG3wzfg3J7gLZfOrEnphN5WESGA3qplek95u4/NXpHLIIkdvFTuG+uo8evy8VVz2F18dYIfdA4OEFbdmUE2Ia0aZWtg7tj4/IKWjyAJilX4bRdnZzbyrRKHZdGYUK5biDztxjSRjuM/WHoYQM/JQz8S2rrJ5PerzVBdkCIhleqtYGSqtvd2xELnmU/l2IG6wE9dKMoVamExVIUkz1dSy7G5UDkg5qo7AEd9X8QpUWzvR4znmk/hogJG7FtJMoSPWUVlIUjQ3sanbHTzjbsrxobFP9IgdTc213h8/a9WEJsjilttwiTRTqIThyKe6EIfMMz00Xu7gKR9Siv8e38TTqLrmyW5NzKPH55Wo7eo/q3GuRFNoUaI4CiGJuNfElto7esoeVKYQ/z22xBtReQ3RNfMi9PEADvNK86NUU87AIBc1nEmqYS6ksx0+6YFQS2gGzkEd1EcTND0yLkZ9nJtkjrWWJ7pSfR1Gj4co4hRfSKgFV3Q04KURYpPJptekCh0+aX4ohfhVbE1QLiEff+JnTMcL6IwGzkofvMxocsno8ZPm03W9QhHX8ZLNLI6H2WWE2OAmEwtKptRro9DJ8VDHv+NWTEYXZNndJ0/KOJ4q/LccXy4KzCufblTKMXpKN7a6+IZ6QyzZYvLd7BzL6m5mjA6ZHD+W9LztxVsWtfGKjfd4YeQw5c4Sm8yvHX+mmGscwNXyL3WiH+PJxIJRtnov249HVw+RHA90HJQpTiG+sld49HVeF4nFYrGj9M/MJ+lJBZ1jnSeFvi/z+VI4CRNmF/iTPYMYHBo5HiRpBmfiwsRv6005jol+wqLcdp6S7pEj+XDvr/PjIcxPJobx0LhJMmiy/SS3oGIYygGV6C3tjr0YjPLWbywUzVNdjhuIfLPpqY61yrrIUI9M8Fqsov6QEkw2/TKfPE8qL8cVPGjwsBh1rd+6XYhUvgpyplhv/tdR5fpoBbjKIzPMwngqEClGVxNbWezimTsV77BXA996Mpe5aGf95tkpmwKXfayY7cXJqj9846Ex3ootVCFy5I9/tkllcG8OClUYl3r4TTEfj1u/vVuqhitGmE/K1YFWrrBHBw8NMluJu4lEBRZLzbD4m4PK5iPf5XnP9tFW9/r2pGTYQtxuviDVsDoEjrLCk6O9v0Y6hiR9ZEOihNl5xTTXT16oYEundAz3ZVbHWl4TSb3o8cXigHn0+JOQuMqDHhtnB5+6BxKVaW0iXDL6rj+imBzXxXzf5vUxi58jrW5qyXENsdN8MvqHxlU2el45q46PBkpUJA+VTOoFymCXnexc30Y37PR1ZptbHe2lDhlltTXhjh7/zWAfvsIxdJHK/GBiFy9Ie34FJcS4qgdJbolYZ3FjMWX2yOkZYrlVssuaULnLLtT0wVg7YhuVKUUxqzsh75vTGAXk+LaAKtZMsaptkRJHeXW0zVa7wa9D5zBjfIqtfU9tSknuMbSH8kkVFTKjW6BiXFvC8WSyFJr3yyzUKkVfjtuLfVZLMyaUMb6GPt1bmkh1SkGMb5Y1l/qOg4kuS3g24nhIyuFk8nxvWjlZGxlpMT77P9ok68W5L6QuM8038+2laG0P4hV/mlhCP8nv2Y2mAchxa/yowBx3NW2DWva06O6Nm5lfkj40rgttAcpCiT2pEyfC7aRKpRCfmNjBVOlv2oIrfRXjC/GRInP8m3k29h3RTHKrKT5PtDyNsT3EbrPQWcMYV6MhfqVOpQzPmljBOg/etROtfLLhbLwqNQbullvMbkTkRG9nXFEba94N5O9s23Uhd5w7fNxbnMNr1SnD7SZlN71hH271oWjQS55fjHbKt6YHe+XSI3X9QxtrXlyzqMAsC73j/I6MCF4vJUHT0CQN0rvw2zAPCwLUxouKdpC8Otol68v+Q79JfG3368tPkXCd3j4fiPTkAV/k2Wsijt720ZmHOh7Y6xV4R+ErX6bNi5eEP0hRXTwvcu0u0wX4LSLOs8V2h1tZoy12U7MijVmdtykev3cn+kncJ2fiLuXvF+xAplliXvnQSnG5s8S94jsnS3Ul1kfIfYb6njZ0NbZStSLMRJN196P74lJcL8FCm2JMSI7ru0SpOrI4Rb9Jm6rlOVus+7EvYl8w6/guyQ3Y8inCDDDpvehXguh36Jxkgc44mmEYlodormea/S4zwyXFJ+hNxUTzUpoqlRLxngkBJNefh6VUrohyk0k3DT9ZhSG4wpE93onx+DN0c52Hqsa/0UFxSkgaMOlNxZtidzIicn2kQhV/k4/LApDkah51HyNB08Ckn4b//IHR6I7LTXKJ4qiLtuiNyaFoLGHGPWbZyC2VF+O0ymKQ2JhsHuLYCJeT/Dyg/rwfUb0iR56J/D0b4M90AEvxNT7BRIzCOEzBdORgmVKXPJLnA7OaFkMVluIz/inucHZwVzz61SvyPTDaBtT4ZgIVLGKsMlnrdzk1nrAT5Y1nfLGqFz3OFH3FluTrOt0RmRQ3KxYH1KdMD2WtPGLOl55XQia2NlOFFf6rnhhXEm85zaIoujPuHqoTV3d0DaiUISU5Wpi14dzMqfGIF818q7lSYqxrYkTyYlwNfbE2pZZ1TWBNcXSMpVdFBuMmnJVRyKnxiO/MPOs5ZcS4wn/Fy+Jg8mnh45UrJOIHAwPrvkBJjg7GNcgu58R4Rp7ZbduFquyNW4lNyXZLHpjC+bHbLZonei/J4+lZkeByw/W9nRPjIe2NvSpfgVzktLiYnlz32PuRk/J9kkcG2KOMu+RocI7h6g7kxHjIy2apb02CvoF3s9jrVAgqohMmYy9XFcBBk6R+vyT5HS5ByNlrsravcWo8ZJGZID8VoBhnHK+NdHoxoRMms/ZYMd4LtJNvOj7lEoSa301WdhqnxkPyUc143r8NTI7Ty4m5Thz/RrzDPm8GFAbSNvLvUQnfcRFCzNcm67qQU+MpHY13yHlZJwUTqjhP22zX5S/BEKzhCpoyN1BBFqiREhdxosq7Jqu6gVPjKWanP2mXBHH94yKx096+uBP7uiX919a/UR+buAghZZiJ57FPjLf8YOZNfXyX43gjsc9OB7xnQ1hcLxiWedifzG4m+B4uQyjpbZJOSrwlD5WMgxYz/M45rif2JHLvLAzCDq6ZA3oELMgCN3FPFUqM+00348R4ThtjQd4VO8bP2HHFRH3wMvCEoh1jVWYjKgcuyX25DCHkWsO1vI0T4zlPmZVHq+XnBelfrZ26JZZxpZLimcAFWWASlyF0GOexP8yJ8ZzPAu+ud5T4xMqdy+N1FjRJmt2oFbggZ2IxFyJkGFdVeI4T4zm50I2vW73jV7iil3VVCuazumOsAnvkupFvDBAt9pmsIy/F+8HFxrO/KVbGj1S3mlalNdvQkV2TZ7bAvo62yOdShIa1vKcXIA+YlSTI9F6Pj7FqyNSaSVNS+EQBQRZ4igsRGsyyYdnO1g/eMvOhzt6HK3pSjv2gpQKCrONzLkRIMGuWy7uXfrDMzIfe9bpuxf/EDjP3vQb7uDLS+M7koMDfUZsBqJAwyWQFt3FqfKDArJ75ttjR3saPXzGvg8AqFXLprETYguXNw8EIk7sAzHbyh9uCyEXWKol8sw7Rs7kmkvnDrMm4z+N9LkUIeMrkGw7xh1FmdZEf9lKQ3zBz2he4Ih7QRwlBrob1XArlechw7RpzYnziFzP/meuZHJdLN9sfN8QBrogH5KKqEpLcjl98ledOw5VrxYnxiULUMPaeAvF/Xu2PnzZz2FlcD494UQlBFnibS6E47QzXrRMnxjfMzny0Tp7IcdZx4k/jF3bmWnjGPlyghCBns2af4lxluG73c2J8Y6KZ97zvTf5xM7Oabsyu8JJJiuyRH+NSKE09rlrAbEHc2Hf2p53qhSCPMXbUrlwJTylAEyUEOZ3V+5TG+LRhKCfGR5qbXbC6xYsL01uMX7aI6+AxsxTZI3fgUihLvsk1IpYW8pMXzHxnlvxmTbWMX9WCq+ADbRWR5JlcCkXZzhxyBVhi5jkF8TTZAYtuxq8axVXwgV/MolM+j0tQwMVQErNab6xF4i+Xm/nO47JT3iYZv4hxRX/opsgemcUcw7U3m8+p8ZURZp6z9awT5e6Qlxu95lxeGPCJDSadbf0eV3MplGS+yXot4dT4ykbzrvEyC3GedaIoMHrJPVwB33hCkT1yDpdCQcyKb67l1PiM6XnPMok9qPVzWMEiaHaYXc30/Ro1UY8PWHxTET409x15e2S9qfErPuD8+8goRfbIbH+qHuNN1iqPU+Mz+SbdvwXEpvi/ZUWQ7zB+xY+cfx85gDpKCPJ9XArlGGm4UpU5MQEwxtRztKdkCXIP4xewm4S/vKGEIFfGbi6FYjzLasjKsBc1zQQ5T68nJ+mtP78QqUCeScUC1n5LdfobrtPFnJhAeM7cdzZIKcapP2P08EzOvO9MVEKQb+RCKIZxG/pmnJhA2I1sc++ZLqHLnnjZ6NE1OfO+U4CmCghyBk/vFcO4Fm9bTkxAjLbyn5c9at10Iec9AOYosUeewoVQihvZoFYp8nCZlf/c43aH/KbRY+tw3gPhVgUEmYXP1aI5V0kxFpnf2YMoEM3dxZBfNXpsLc56IKxD5cAF+QIug1I0MlylvpyYAHnMyoP2ivPcCPKLRg+tzjkPiFcV2CNv4DIohHGG+jOcmAA5YN1aYoOuSW5vyrTzoMhX4GiPtZFVIstwjUZwYgLld1Sz8qGfxSnJCvIAw8YkzEMOjCXICFiQ2RxIHQpM+oW8yakJmK+sIskQX2Qdl5wg32f8wC2c8cAYGLAgP8glUAb2C1GX0dZ+9FJyMeR2xo9bwfkOjL2oH6ggM8dVHZabrNEsTo0C9LH2pJuTEeRLjR82j7MdIME2P72MC6AMOWDxL5UDSpaJqvvSsp0LcjXjh33M2Q6UhwIU5PqcfmV4l5kwin+bbWblS6sq/NepIJ9h/KhXONcBL/TFgQkyK4mpw8swPnQ/wKlRhI3WpXM/dVrf4iixz+hBvTnTAfMjygckyPU4+crQG7y4pTrLUNXKn/o6vTy9xOgxHTnPgTM0IEFuzKlXBuM+bs05MUoxy/IytXals8S3qUaPacRZDpwCXMfeeimO8dfhuzgxivG6lUdtLXeWkx3yEOOKyIWc5cBZj3MCEOQenHhF2GVyLWQQp0Y5ulpHksvYP9a72/ghGznHCjAlAEF+ndOuCN+brNBkTo1y7LOub3GH/ZDFlcaPWMA5VoL7fRfkhZx0RZhkskI/c2oUZKXV4d7ueHm7O+RMFipXmf24wlc5roaDnHRFML4Jls6kN0WZYRJiEhAQc2wmwGUdJ/KNHvAC51cRfkcVHwW5GydcGa4xXKFLOTHK8riVb/W0e6y3ko6pNu/5KMg5nG5FyENF5liEbs3amPvWfr2avaDFZ+xrqzoP+ZaDzOwaVfjZZI1e5NQozAarzKhvYkfZ2SEPN/pwFbqmQhzAVb4I8iecamUYb7JGn3FqlGaShX/pt9gR5G4sYKI+q6wvaEoZ13GaFaKnySqt4dQozi3mPrbFRrmh+FWMJoaB6VZnuBJGZazkJCvEJaxjEVK2Itt8j/xiYkGuYPzRMZxZxRjsoRzrmMoJVsqpjf/83sGpCcXmyczPtDytUiJFPkYcZMW3MFCAjp4J8jBOr1J8YrJOIzk1oeAuc1+bnDiKvJStfMLBbjTyRI5ZHUE1+pus1PecmlCw2eL2QLxWUhXf6nBWFeRX6ddEMjGR06ocTQ3XqiLvUYaGYeY+916iTOTBxh/cxVlVMj4l83DvEvZnU5BdJhV2W3FqQsNBNDTzusIE3fbE7cYfXMxZVZKnJIlxJQxhXQQlmWGyYk9yakK1dTI9Qh9nHbK4yPhjH3JOlaQAN0tIcuuHTZxKReltsmozOTWh4iYz/zsg/s8qZKHx5D1cbEcDF2LcFOOxm5OoMBeZ1HnbzqkJFYvNvbCPZeKblsfeEeFiRRKHew3QA5N5A1N51pqs39WcmtDR1swb/7Csa2Fc8a0N51NhPrE83KuMy9EMbXELumMIJmMBtnLKQsJbJmv6FKcmdOSY+2gDK0H+wugjdTmfSvOEhSBn4VdOUEjpzNKoEaKp2Z29kVaC/LrRR8qz4pvSFKCDhSRfhj2cohCSj+omOcj7OTkh5EMzD91oEbQQjxt/KJfzqTTbLA/37uEEhRCz1qa8ORtO8kxLDVnc2BP3Gn9kCedTcZagMjtIR4qhJmv5EqcmpJi1l9AfNU98a238kVmcTeV530KQMzCPExQyWoPXtKLFHDP//NhckOsbf2QyZzMEDLSQ5HOxkRMUInYjw3AdqyOfkxNS8nGusXdujZUxEeS0LGN3HsfZDMWCWx3utWBBmhAxg+cBEaSHWaaFbhZDFqy+GmasD/cGcIJCg9ml6SmcmhAzziyK3NhEkDNON/7AC5zLkGB9uMfQU1gw/sMaxxZOTYhZZLZD7mIiyGX/wcLlYedji5t7lbGMExQCfjVZv2s5NaFmv8nJgP6YeeJbodEH+nMuQ8TjFnvkhtjJCVKekSarN5RTE8lvPvow87563CGHnny0s5DkW3jvUnnMStGwiUDYucZZXWRxgrEhDOFMhoptqGchycM5QUqzG+UN1602/5SGntbOBDnzZGMXfpkzGTJ+RkVTQU7HfE6Qwph1mmYZ3PDTwnhtXzcR5PT/GZvCaM5k6HjLYo9ch9VJFMYsW/UTTk3oqW28ti+ZNXGqYWwK7EccRh60kOSO/PqrKIWoA+Oai+zuEnb2mGRAaQ+bCHL8KmP3/YZzGUL2m9ZgFRAYxQlSkp9Z5S2ymLZyutlsh9zF+APrOJehZB1qWBQcWsgJUpAXTdbrVU5N6HnOrADnuWZZFs8Zuy4LmoSVHKSbSnJ95iQrSEuT1fqNUxN6LjUOWOSV/YfZDnm+cVNMEr2/ygICnTk9irHd5A8ofTD8/GLmh/NM5DjrJOOu0x05lyEmH9dZSPIbnCClMKtq3ZdTE3o6mXlhP7OAxeW8sBlFNpvVYYVABfzECVKGj3COyTp9yckJOfNNfVCvbRawGMkut9HkC4uCQxezCaoSbMGtFkWh2Ng03Bw0z3haZlKePvtYbbNxl9u9nM/QY1Vw6BFOjwJ/Mmtb1h8h4aav+eo+6DBg0YGzGQHyzC5tQkDH55ygANmO+yzEWEDgTU5SqLEoibsj7VQzQX6Nxz5RZg2qmTp8NgufB8ZMk5t5vAcQFRZYNY143CzD4jix1bgQDV01KkyzcPnbOD0BsAXdE4qxwJWcqBCzEFnma7u17Glm/aabGn+kHWc0QvSwcPt3OT0+M8XiHmXR8TSnKrTMR1Wrtb3DtFOIPs74IxM4pxFij0UT1KrYwAnyjVW4yZYYCwh8x+kKKVMtiuAK6Dmxo80L0+8wvjTNMo1R+4udblEBjvjBPgxBBdtyXJ2FC0JJIYZYJJsKaLvKpZvvj682/tDNnNfIMdDCSKZyejxnpmU3l9KjK6cshGxBxwTrqt0QM0e8xLhiqnAAl5kaSU1+I/KU3xK6aenxAactdHxlmVUuIKANjVkhfjO+VstqYFHkJ5OebQICt/NOmEfswACTJvBWI51/IkPGHvS2DFUICIgpsWMs5DhenjHF1OIFC2NpwHYE0inAZGQ7FmMBgeacvFDxBS5MuKbajIzjLffH+l3GHxzL+Y0oebjawmDi6MP6FhKZgcZJibGAwLOcvtCwDb3srOmcrJNi1mhTjT+6inMcWZYk+Pp8IWZzkiSwEG2SFmMBwf7godnijEZ1Oyv6dfzfCeQ46zhtl9FH63GWI82AhMZzH29puvyj19GVGAtUQR6nMQTk2P0O9K5pb5Ai++OLjT/8KOc50uy1Ee2qhlGUhKRYhrsRdynHAndwIkOw0u3trufzsaNiidEHGn/8U851xPnElhldhC84VQ5dtLvF9RsnYzwnU2nWoZfNldbyROeYPcRM43QbprxFn1ts79RWc7Jshik6S9gZ/zU46+qSi0H271v+kVbXphzHyohtRo9oxRlPAdZaFQYsNjIxAFs5YZbMRcfEGagOxsWcUkXZhIG2PUdATDat6WY/B3kwZz0lGOFAICpjEHZwygwowExcK1GKD43enFgF2YC+liWDSoy9FhXdDI/02ho/6BPOfEqQh4sciUQNjMQ+TlsR9mCsRQ09N2MaJ1cx1qGfEzGG9pWoGHOGeM74USzFmCpMcywUdTCKF0cAAL+jL6p4IsYCOpMOlWIt+iHTyQpuF/fayqoosUP+yuhhtTj/KUSLpDJk++HPlA5S5KCT1IhxydGYhqkMq9HLaR2SyeXOiiXB0WI3q1ikOvOSlIwK6J6Stzk3YDjqeyjFjCCrxDJ0dZrE+LPeOJYc5dKNHzmE65BSJH+jLAN34hsUpsg87cd7aCsxrY0RZLX5xXlGea7okXVcLFn0xrwUQoClLi8yNMLrEc9bL8Bc9LLo280IctSY7zwkdVB7wUGCm2EE+U7jRy/leqQY97uWkMroie8jOTeL8Rjq+CbFjCCrIMZtna5YoZiYnhFziz7Y+PG8pZdqrLMoWu9kXITnIxNXLsQPeNphWiAjyGFf85lo5ny9PtVqxmQg3jQuKUNSjwckft1ugbGh7nRxELPxiO+74qLjPRqk7+RjSjKVq79OuyQmC/G50Suu4NqkIL9JPqxKRxu8Errd8jpMQBdUDVCKWYs8CArwES5xvk7f6E1jMhE/Gb3mFq5PSnK7R9HQp7BQ+Vb2e/AF+qFR4EJ8aFRPmbwVVcIUTZyv0hxxWUw2Yq3Rq3pyjVKSeR5KTGW0xXAsVk5odiEHg9BSUgRd1uhAY/SNHFwV/M74iCBvN3pdH65SitLEc6nJxt14HQsD7m19AD/gDTyIRp7etUt+sJOeX2J8tTpiHIvFYlqe0SsHcqVSlDd9k5wMNMUjmIRfcMC33y4X8/AmeuEqp9dgfR8zaYo+iHES2RTfaFfEvEQUGr32Sa5WirIHWb6LTzoa4jY8hSlYLD0zYx+WYybG4BFcj2zFRbjo2ExT9JSv0dJ57lCOhzvjI4Kcz4vTpCj3BSxFlXApOuAhDMUEfIr5WIEttg4EC7Adq7EQn+FtvIj+uAvNUStEEly84zfxjhXooqYYx2KxmDhg9PpnuGop/EVORYk6B9VRHw3QFFejLdqiLZoeHpehPqo7K4uo/OhMM/SIDXjAcXKnNkM7P+YXYqvRj9CLK5eyFAR6HYKD31C9C8cNcVRcXkAUalP12jE/0VYwD5kUpzclMeDxIY1Q+jZjAmo6W4UCbWpadsxvxLdGP0wzrmAK8wUlMeCxjEYolcVO+x0WiLe0SrEgEJONW/SQ1GU/KlEUAxzpPiYCRp9c9HMWNS7Upmo1YkGhPWX8Y23iSqYwHSiLAY6GNEBJ5GOUw6ok2owAwhTFym/exm4FpCRDKYsBjltpgFJY4vTix8fxc2NBo9c2/uH6cz1TmBzKYoCD17JkhN2GOKpOoueIhjEVyDpO7Ge/AlKc3T51jeMwGu/SAF0yz1khTZn1jCUc631j/GMu5LqmMMxFDm7Mo/m5YA96OikYtciDEpouBbmv8Y96H9c2hbmewsjS9CFkERraP8Bbo98WOzqmGuI84x+3IgucpDAPURgDG3tofkmRh+H2q/jlih5l/xFTkqPESuMfuivXOGUZTGEMaFSh8SXFGtv127Q87YWyp8XURetv9qN/xXVOUV6mNAY0LqbxJcEkVLY7w1/Eq8bUJi1uXIRToB62cq1TkjcpjQGN62h8DjmAfnZnd6XWIhYGxESzX6EpI1oUZA4fxz00PkesR3N7M7tP9FE1alx6j5xt3DlEQKATDnLVU45XKI0BjcdofA6YY7cPzCw9MxYmxNvmv0wrBi5SjhcojQGNoTQ+mxRgiL0LTNvEvbGjYuFCCLHP/Feqh6Vc/5SiH6UxoDGKxmczcny3vRmdmP6/WBgRPa1+rQwMCrhxO/GT2ymNAY3xND4bbEMrO7O50adOeB7lI89OlJCTQ0tIEZpRGgMaU2h8CVmJBnbmcpp2ZizM6JrYlOiXbImZKKRFRJ7alMaAxgc0vgQstHOQt1O/LRZ+tIu1vMQm0wQTsIt2EWHyWO0tsPEezc+SaXY6jM/W9Fg00NuJAjtmUxFdMRt5tI9IsoLCyJCFkkxFeqIZLBTPZx8biw6is3lOcslRGZ0wHhtpJxHjAwojqyEryOTEcpwb5mM8813yQScmFMeV6IOp2ECLiQhPUxgDG2/Q/Ex4L7EcL0yLx6KI3lhsTcaY6qIzhmIm1tN6Qk1HCmNg4yWanyETEp9rvJxxfCyqpMXF927MqjraoCdGYiZWMtIcOtgvJLjxFM3PgPGJuoDk63fFok32saKvWRU4p+McNEUXDMJ4zMRi7KZ9Kc1KymKAoycNsBQfJtod745g5Nikm8h3XhjduWiGzhiAUfgIC7Cee2ilYKW3IEd7GmAJvk2U6LZOqxlLGY4Wd2hrvDbCOGqjGW5DHwzHFMzFakp0gNwZLgnbJ9aJJdp8bYaYoo8TI8QoMVFMFBPFFG2GvkAs0dZYVWlRb7Dfe3GW4xzrGfshvVwstcg4XtwhVvlrlumoizbojucwCd9QoH2kADXVlKrdYomYLd7WXtAf0TrqTeMXpmWVO8tehdvMk+MV0uqK5vpd2tPibTFXbFBXkLN4E7YIG3GB5WxpX2X8K5aKZB+rdRK/BGemhwT6PgzFh/gZe2mpHn5BVESa9oif9Q/1F/X79ZbxWhX+KzkYd4KeqV+q36IN0MaKOYlLBvg51tIID7MbV1rP1RdZJ8VSGe18baTYEbzJ6rgA7dAb47CAl7gl80hgq6rt0uZrY0VPvbVe2++SifF/x2uJ6/RHxBgxR9scrHXPoBECAPLQ1tpeZpx1YoycdaJ+o/hI7FVnR1EPt2AwPsJq2rAEJ/A5YLFVz9FGat3FZboWK6PMYfYp8VriOu1h8Zr4Uqy1f3OVJerlUYjuCWq5haYhk0+yfLU2UqxTK/5WEx0xBF8gl/acJLP8WKeD4gcxRuuedol+RihyjU5Iy9Kbiq7aUDFNLPP+iLADzRDAM9a746kRvgTigjLxqloX8aZYrdrRSAM8iMm8zO2YW71bk23iCzFE3KzVyDou5Ifcp+vVtCb6baKvGCU+Fj+JXLkzVZldLDHBOmSZw91xohhcmnaD9rQ2Q2xRTZh7YArLH9lkpfyym6vF+6KfaC5ExL8vZooG2jVaJ/0BMUgbKSZqM8RsfYFYJlaKXJErcrVdRbJFcrU14jfxg77A7BvmvJT/nlaqakXRGpRLyp5GxbVNern4VaKXNlabL3aqlN05CPNRQM314UBPyxM/izf1B+KNzv4P/cEyGNLeeAYfT2krXIQso6KaBw7/1/po/3H3WpwbiTvEk2KiNl+FvXMtPIiPsYfKa8hWVHIzuyv1D8Ugra2ozuieXcqdZXxgeB7yU9YKl6K6WZ3j3aJQ7NRq0G5kxd7+pZ8jmotu2gvaVPGT2B2ULGeiEz5inK4UvZ3O5AbxjXhLPK7fop2foun57hNJfzSe229SNmh2rnVOzqW0Gc9IOzVeNX6V6Cwe18aKL8XvR76U+DKqoTtmpvBOpCS/I8Nsrv4Qv+oL9AXaDDFBH6b117poV6ZV5rGKlKBFP+M5vzMlbXAd6lr3AulAi/E1Z0M7U5yntdDu04ZqU8VPYo/3snw+BjMXAwBwm9kcLVYnPziCm5Iss5upq1LOAjegvrW39qG9BB2D/p9eW28tHhTDxcdiiVcZoOm4HTkpXkHgC/MUo1a0wyCCFg+nmAWuQQNrP32NGwPldtC6pl+qddFeEJ+I3+01Y3WSIDc8ZS+U7DAvSf9T7CganqdBi3uMZ748/kghC1yNetb++UmkGpdGkbNOjNfSOopntRlio7yU/IHYlIKCfK/5nDSnpXksyKeYhea6pYz9/ZqoR833mSfTUkIV2tCuEL21qTLKKlZE3xSLKr9nPhszaVs+BC1GmlUJ/zEl7O/nRPVTlon/o5WEVZrLaddoT4tvtTw3olwe3VPmUOUn8+zjfP0cWpT3lEs3a5XWPgXs7xtUs/bGVSlXgD6KZJ0kLtMH6jnJp9JloEcK1I/70+LLov4i7cgf9HFma/BlxO1vKipY++H69AzaR4Q445/61eLlZIsfRV2Ud6GZxc27FC/+7SPx8uKg8SrUjfS90tEJaqdom9OyaB3R3INUEz3E7GS6aGegO1ZG0h32oI1FEj7vRPlqny+arcSgiIpxIZ5I5Hvb07JpGdE+PjlT3Cu+cV5wPAP3Y1nEHGI3WloVOBxGa/H17ON/ZqW40vFTBOV4t/lFpCPXpOO1aBepYfzlxL16jvO2UTdHqMLAJqtgBcQPvBjt+x75UbPVaBq5uiu/45JE/vYnD5RTbbdcU3vFtMBRoblzfBiB+hdLrHv57oiXp334f9oh1putyMBIyfGsRHkVEOu0SrSIVDxM+bd+t0Ev7ULroMb5GIrNIXaI6Ub1ZouWAm9Gywhkj3yj+bezzyMTOX4xcROEP5hZkdKIhuL9ohJsJ4e5PLqEsv7FPvSDbn2y3Z0WEZglfmLeLTIKl5VycXPi4OBSXaMlcHdyjph4uDpGvv0qGZdjdKjqX/yAixP9Ti/RFgIUZGFeJfxa7Au5HM/BeYl9ag67zJDDpFXWxmp5TmvKpaNtKMrd70C/0p3KSu6OJ8WOph0EKsndzFenc4hbkOVjSELrExDvnXUibYAUjSqX115J5tp1TfTDd8qGMAowHjUS/xZTYsfQAgLmaDHXfIWeDG1WRQs7eUzDuB0gBpRLF6OTq4VRB/2Ua6VagI8SJxlBQExhLzwVSM8Q281XaVzoxLgAr6BiYusrFD259sQqmjci2QJFddAHX2K/Ekd4ExKV/f5rjOHuWJnzjJZW2fBjQyXHf1jdBv07VLZLu4brThLulPVXxf7ky3i2xWisDcwVfsMgO2GKQ+MJdmNQSpJftJLkN0MixgcxzFYfc21FWmWuObH3BfJ/oq/Y6qaU5yV4CO/jTx8dYT1es7wWXWLsZ+tI1cg4Xl9gJcljQiDHOfYCZRCfpJ3KFScOyDxZu09b47bw/UXoibex1MN7fgX4CS+jeYI845J3osR5XGElQ2aWzRZ6IU9hMf4T3e1ZYaH2FA/ySBJkH6u3szr/dtImqiX6YzIWY68k88/DTxiHLvYDFH/vtT7MOJ1rqyZp2douq7Vrj11KivEeDEcVe/a3RW/KdSaunES8JvbK6uCnox46YCDGYCaWYIcjs9+PFZiJ19ADV6F8cu/fp9/NyLHKaE2sj5WvwK/KRY3HINum/WlfsRMIkUDZ0/T7xa9yO14fGlVwCVqiE+7HY3gRwzEa4zEeUzEe4/E6huMF9ENXtEdTnOcsLGE0vtQzuZbKBy5uT/Rt6y1lxDgPU+xm9EAU6I8xq4fI4yjtIjHG/Jqr4iNXv41745BIcq9Eq9lZgcv7BzDevhhDrI434soS+Xvlf+ittBnOy90HOg6KEen/49qFKHBxX6I1rY7xAV5G2oNRFn0ZDcbEsqdxVYlnlEvXHhaLQiHGBdqkeAWuWOh2yfck/qN/NX4IQIx/RR9UdWKBa7UruZ7EB+IVFJflAjEhvQrXKaSS3DlxBUIdt/nY7OkgpqGt05OM18UpXEviqyyLB8WsZK9cezZ2iOe5Mw65JDezToL7S5RvwULPS8zPx8Oo7tQGf9Eu5iqSYJznFNFGjBGbVBBjbb7WJfNkrkn40c8Rf9hb8yswFjs9KaG5AE/iQudWuFv0zDqOK0iC5ai0bO0+bapV7S5Px0rxBGsEREqSzxBz7F8/uhtTpV0dycVUdE3i4pGAgJgcT+PaEXU4Oi1bu0+8J9b5dnQ3X3+UPXujSMbx4jknWT0V0B6v4vukr1n/gcnohUuTz3r/VruIq0YUpezZopn+mJgutniU0LZIe0G7hklFEQ+IXWbendq88mBrDMCbmJOwyNU+/IYcjMFDaOksf6L0WKa3ZLY7CcdO53TRUNyhvaDNEH+4OwLUNou54mX9tngtlpdPIet5L3mLqYjz0RQdcC96HRl3oRPa4vJkgxJGJavuyD6WK0XCyDHxtPiFWlvRSzyvvSE+Et+IZWKLwZn6XpErVovvxMfaG+I50VNvpdWM/5vTl6L75OvEWkUTLH8Tt3NzQKLpdieknZp2atqp/OpHSpJ5sva0OKiYGP+kt2ONCkJISpJWWXysiBQXiul609hRXBNCSCp/i6qjTQ24nsp2MSItiytBCCGxWEzUER8FIsoFYpbW8awTuQKEEFKE9AwxyNfboT+LvmlxzjshhBjvlE/QbxSzRL7Hu+JvRe94Vc42IYQk3iv/T79NfOJBBkaumCjas5o2IYQ4JO1UvaX2gliUuHBnwrFKe0PckV6FORSEEOIujHFK/Cr9UTFBLBYHHIjwHm2+eE27T29c7izOISGEyOYYPVNcpt+kPyCe1ceJ97UZ2gztK32BmKvNEJPFeDFCPKHfpV+t1dTP4GQRQghJYf4fTci7RwYvH54AAAAASUVORK5CYII=")]
+
+pub fn add(left: usize, right: usize) -> usize {
+ left + right
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn it_works() {
+ let result = add(2, 2);
+ assert_eq!(result, 4);
+ }
+}
diff --git a/src/test/rustdoc-gui/src/scrape_examples/Cargo.lock b/src/test/rustdoc-gui/src/scrape_examples/Cargo.lock
new file mode 100644
index 000000000..7cd6d0844
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "scrape_examples"
+version = "0.1.0"
diff --git a/src/test/rustdoc-gui/src/scrape_examples/Cargo.toml b/src/test/rustdoc-gui/src/scrape_examples/Cargo.toml
new file mode 100644
index 000000000..aea9b657d
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "scrape_examples"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-1.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-1.rs
new file mode 100644
index 000000000..1d1bc5002
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-1.rs
@@ -0,0 +1,3 @@
+fn main() {
+ scrape_examples::test_many();
+}
diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-2.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-2.rs
new file mode 100644
index 000000000..1d1bc5002
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-2.rs
@@ -0,0 +1,3 @@
+fn main() {
+ scrape_examples::test_many();
+}
diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-3.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-3.rs
new file mode 100644
index 000000000..1d1bc5002
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-3.rs
@@ -0,0 +1,3 @@
+fn main() {
+ scrape_examples::test_many();
+}
diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-4.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-4.rs
new file mode 100644
index 000000000..1d1bc5002
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-4.rs
@@ -0,0 +1,3 @@
+fn main() {
+ scrape_examples::test_many();
+}
diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-5.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-5.rs
new file mode 100644
index 000000000..1d1bc5002
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-5.rs
@@ -0,0 +1,3 @@
+fn main() {
+ scrape_examples::test_many();
+}
diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-6.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-6.rs
new file mode 100644
index 000000000..1d1bc5002
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-6.rs
@@ -0,0 +1,3 @@
+fn main() {
+ scrape_examples::test_many();
+}
diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-7.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-7.rs
new file mode 100644
index 000000000..1d1bc5002
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check-many-7.rs
@@ -0,0 +1,3 @@
+fn main() {
+ scrape_examples::test_many();
+}
diff --git a/src/test/rustdoc-gui/src/scrape_examples/examples/check.rs b/src/test/rustdoc-gui/src/scrape_examples/examples/check.rs
new file mode 100644
index 000000000..b3f682fe4
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/examples/check.rs
@@ -0,0 +1,26 @@
+fn main() {
+ for i in 0..9 {
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ }
+ scrape_examples::test();
+ for i in 0..9 {
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ println!("hello world!");
+ }
+ scrape_examples::test();
+}
diff --git a/src/test/rustdoc-gui/src/scrape_examples/src/lib.rs b/src/test/rustdoc-gui/src/scrape_examples/src/lib.rs
new file mode 100644
index 000000000..88b03cf26
--- /dev/null
+++ b/src/test/rustdoc-gui/src/scrape_examples/src/lib.rs
@@ -0,0 +1,9 @@
+/// # Examples
+///
+/// ```
+/// test();
+/// test();
+/// ```
+pub fn test() {}
+
+pub fn test_many() {}
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
index fdf97e492..d6eeab803 100644
--- a/src/test/rustdoc-gui/src/test_docs/lib.rs
+++ b/src/test/rustdoc-gui/src/test_docs/lib.rs
@@ -76,6 +76,7 @@ impl AsRef<str> for Foo {
///
/// # title!
#[doc(alias = "ThisIsAnAlias")]
+#[non_exhaustive]
pub enum WhoLetTheDogOut {
/// Woof!
Woof,
@@ -342,6 +343,9 @@ pub mod doc_block_table {
/// | header1 | header2 |
/// |--------------------------|--------------------------|
/// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum |
+ /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum |
+ /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum |
+ /// | Lorem Ipsum, Lorem Ipsum | Lorem Ipsum, Lorem Ipsum |
pub struct DocBlockTable {}
impl DocBlockTableTrait for DocBlockTable {
@@ -408,6 +412,11 @@ pub struct WithGenerics<T: TraitWithNoDocblocks, S = String, E = WhoLetTheDogOut
p: P,
}
+pub struct StructWithPublicUndocumentedFields {
+ pub first: u32,
+ pub second: u32,
+}
+
pub const CONST: u8 = 0;
pub trait TraitWithoutGenerics {
@@ -416,3 +425,20 @@ pub trait TraitWithoutGenerics {
fn foo();
}
+
+pub mod trait_members {
+ pub trait TraitMembers {
+ /// Some type
+ type Type;
+ /// Some function
+ fn function();
+ /// Some other function
+ fn function2();
+ }
+ pub struct HasTrait;
+ impl TraitMembers for HasTrait {
+ type Type = u8;
+ fn function() {}
+ fn function2() {}
+ }
+}
diff --git a/src/test/rustdoc-gui/struct-fields.goml b/src/test/rustdoc-gui/struct-fields.goml
new file mode 100644
index 000000000..3ec60b58c
--- /dev/null
+++ b/src/test/rustdoc-gui/struct-fields.goml
@@ -0,0 +1,5 @@
+goto: "file://" + |DOC_PATH| + "/test_docs/struct.StructWithPublicUndocumentedFields.html"
+
+// Both fields must be on their own line. In other words, they have display: block.
+store-property: (first_top, "//*[@id='structfield.first']", "offsetTop")
+assert-property-false: ("//*[@id='structfield.second']", { "offsetTop": |first_top| })
diff --git a/src/test/rustdoc-gui/target.goml b/src/test/rustdoc-gui/target.goml
new file mode 100644
index 000000000..3e5c30dc7
--- /dev/null
+++ b/src/test/rustdoc-gui/target.goml
@@ -0,0 +1,35 @@
+// Check that the targetted element has the expected styles.
+goto: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html#method.a_method"
+show-text: true
+
+// Confirming that the method is the target.
+assert: "#method\.a_method:target"
+
+define-function: (
+ "check-style",
+ (theme, background, border),
+ [
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ ("reload"),
+ ("assert-css", ("#method\.a_method:target", {
+ "background-color": |background|,
+ "border-right": "3px solid " + |border|,
+ })),
+ ],
+)
+
+call-function: ("check-style", {
+ "theme": "ayu",
+ "background": "rgba(255, 236, 164, 0.06)",
+ "border": "rgba(255, 180, 76, 0.85)",
+})
+call-function: ("check-style", {
+ "theme": "dark",
+ "background": "rgb(73, 74, 61)",
+ "border": "rgb(187, 116, 16)",
+})
+call-function: ("check-style", {
+ "theme": "light",
+ "background": "rgb(253, 255, 211)",
+ "border": "rgb(173, 124, 55)",
+})
diff --git a/src/test/rustdoc-gui/theme-change.goml b/src/test/rustdoc-gui/theme-change.goml
index b1de3c366..cc47f1f45 100644
--- a/src/test/rustdoc-gui/theme-change.goml
+++ b/src/test/rustdoc-gui/theme-change.goml
@@ -2,31 +2,66 @@
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
reload:
+
+store-value: (background_light, "rgb(255, 255, 255)")
+store-value: (background_dark, "rgb(53, 53, 53)")
+store-value: (background_ayu, "rgb(15, 20, 25)")
+
click: "#settings-menu"
wait-for: "#theme-ayu"
click: "#theme-ayu"
// should be the ayu theme so let's check the color.
-wait-for-css: ("body", { "background-color": "rgb(15, 20, 25)" })
+wait-for-css: ("body", { "background-color": |background_ayu| })
assert-local-storage: { "rustdoc-theme": "ayu" }
click: "#theme-light"
// should be the light theme so let's check the color.
-wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
+wait-for-css: ("body", { "background-color": |background_light| })
assert-local-storage: { "rustdoc-theme": "light" }
click: "#theme-dark"
// Should be the dark theme so let's check the color.
-wait-for-css: ("body", { "background-color": "rgb(53, 53, 53)" })
+wait-for-css: ("body", { "background-color": |background_dark| })
assert-local-storage: { "rustdoc-theme": "dark" }
+local-storage: {
+ "rustdoc-preferred-light-theme": "light",
+ "rustdoc-preferred-dark-theme": "light",
+}
goto: "file://" + |DOC_PATH| + "/settings.html"
+
wait-for: "#settings"
click: "#theme-light"
-wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
+wait-for-css: ("body", { "background-color": |background_light| })
assert-local-storage: { "rustdoc-theme": "light" }
click: "#theme-dark"
-wait-for-css: ("body", { "background-color": "rgb(53, 53, 53)" })
+wait-for-css: ("body", { "background-color": |background_dark| })
assert-local-storage: { "rustdoc-theme": "dark" }
click: "#theme-ayu"
-wait-for-css: ("body", { "background-color": "rgb(15, 20, 25)" })
+wait-for-css: ("body", { "background-color": |background_ayu| })
assert-local-storage: { "rustdoc-theme": "ayu" }
+
+assert-local-storage-false: { "rustdoc-use-system-theme": "true" }
+click: "#theme-system-preference"
+wait-for: ".setting-line:not(.hidden) #preferred-light-theme"
+assert-local-storage: { "rustdoc-use-system-theme": "true" }
+// We click on both preferred light and dark themes to be sure that there is a change.
+click: "#preferred-light-theme-dark"
+click: "#preferred-dark-theme-dark"
+wait-for-css: ("body", { "background-color": |background_dark| })
+
+reload:
+// Ensure that the "preferred themes" are still displayed.
+wait-for: ".setting-line:not(.hidden) #preferred-light-theme"
+click: "#theme-light"
+wait-for-css: ("body", { "background-color": |background_light| })
+assert-local-storage: { "rustdoc-theme": "light" }
+// Ensure it's now hidden again
+wait-for: ".setting-line.hidden #preferred-light-theme"
+// And ensure the theme was rightly set.
+wait-for-css: ("body", { "background-color": |background_light| })
+assert-local-storage: { "rustdoc-theme": "light" }
+
+reload:
+wait-for: "#settings"
+assert: ".setting-line.hidden #preferred-light-theme"
diff --git a/src/test/rustdoc-gui/theme-in-history.goml b/src/test/rustdoc-gui/theme-in-history.goml
index c29571728..10508e86a 100644
--- a/src/test/rustdoc-gui/theme-in-history.goml
+++ b/src/test/rustdoc-gui/theme-in-history.goml
@@ -3,7 +3,6 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
// Set the theme to dark.
local-storage: {
"rustdoc-theme": "dark",
- "rustdoc-preferred-dark-theme": "dark",
"rustdoc-use-system-theme": "false",
}
// We reload the page so the local storage settings are being used.
diff --git a/src/test/rustdoc-gui/toggle-docs.goml b/src/test/rustdoc-gui/toggle-docs.goml
index 8c9fd0a88..45bb8daf1 100644
--- a/src/test/rustdoc-gui/toggle-docs.goml
+++ b/src/test/rustdoc-gui/toggle-docs.goml
@@ -7,6 +7,10 @@ wait-for: 50
// This is now collapsed so there shouldn't be the "open" attribute on details.
assert-attribute-false: ("#main-content > details.top-doc", {"open": ""})
assert-text: ("#toggle-all-docs", "[+]")
+assert-css: (
+ "#main-content > details.top-doc > summary",
+ {"font-family": '"Fira Sans", Arial, NanumBarunGothic, sans-serif'},
+)
click: "#toggle-all-docs"
// Not collapsed anymore so the "open" attribute should be back.
wait-for-attribute: ("#main-content > details.top-doc", {"open": ""})
@@ -40,3 +44,32 @@ assert-attribute-false: (
click: "#toggle-all-docs"
wait-for-text: ("#toggle-all-docs", "[−]")
assert-attribute: ("details.rustdoc-toggle", {"open": ""}, ALL)
+
+// Checking the toggles style.
+show-text: true
+define-function: (
+ "check-color",
+ (theme, filter),
+ [
+ // Setting the theme.
+ ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+ // We reload the page so the local storage settings are being used.
+ ("reload"),
+
+ ("assert-css", ("details.rustdoc-toggle > summary::before", {
+ "opacity": "0.5",
+ "filter": |filter|,
+ }, ALL)),
+ ("move-cursor-to", "details.rustdoc-toggle summary"),
+ ("assert-css", ("details.rustdoc-toggle > summary:hover::before", {
+ "opacity": "1",
+ "filter": |filter|,
+ })),
+ // moving the cursor somewhere else to not mess with next function calls.
+ ("move-cursor-to", ".search-input"),
+ ]
+)
+
+call-function: ("check-color", {"theme": "ayu", "filter": "invert(1)"})
+call-function: ("check-color", {"theme": "dark", "filter": "invert(1)"})
+call-function: ("check-color", {"theme": "light", "filter": "none"})
diff --git a/src/test/rustdoc-gui/trait-sidebar-item-order.goml b/src/test/rustdoc-gui/trait-sidebar-item-order.goml
index a799444a1..e5d023544 100644
--- a/src/test/rustdoc-gui/trait-sidebar-item-order.goml
+++ b/src/test/rustdoc-gui/trait-sidebar-item-order.goml
@@ -1,4 +1,9 @@
// Checks that the elements in the sidebar are alphabetically sorted.
+
+// We need to disable this check because `implementors/test_docs/trait.AnotherOne.js`
+// doesn't exist.
+fail-on-request-error: false
+
goto: "file://" + |DOC_PATH| + "/test_docs/trait.AnotherOne.html"
assert-text: (".sidebar-elems section .block li:nth-of-type(1) > a", "another")
assert-text: (".sidebar-elems section .block li:nth-of-type(2) > a", "func1")
diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml
index fce3002e7..c014eb52e 100644
--- a/src/test/rustdoc-gui/type-declation-overflow.goml
+++ b/src/test/rustdoc-gui/type-declation-overflow.goml
@@ -1,4 +1,10 @@
// This test ensures that the items declaration content overflow is handled inside the <pre> directly.
+
+// We need to disable this check because
+// `implementors/test_docs/trait.ALongNameBecauseItHelpsTestingTheCurrentProblem.js`
+// doesn't exist.
+fail-on-request-error: false
+
goto: "file://" + |DOC_PATH| + "/lib2/long_trait/trait.ALongNameBecauseItHelpsTestingTheCurrentProblem.html"
// We set a fixed size so there is no chance of "random" resize.
size: (1100, 800)
@@ -35,3 +41,20 @@ goto: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLon
store-property: (scrollWidth, ".mobile-topbar h2", "scrollWidth")
assert-property: (".mobile-topbar h2", {"clientWidth": |scrollWidth|})
assert-css: (".mobile-topbar h2", {"overflow-x": "hidden"})
+
+// Check wrapping for top main-heading h1 and out-of-band.
+// On desktop, they wrap when too big.
+size: (1100, 800)
+goto: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html"
+compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y"))
+goto: "file://" + |DOC_PATH| + "/lib2/index.html"
+compare-elements-position: (".main-heading h1", ".main-heading .out-of-band", ("y"))
+// make sure there is a gap between them
+compare-elements-position-near-false: (".main-heading h1", ".main-heading .out-of-band", {"x": 550})
+
+// On mobile, they always wrap.
+size: (600, 600)
+goto: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html"
+compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y"))
+goto: "file://" + |DOC_PATH| + "/lib2/index.html"
+compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y"))
diff --git a/src/test/rustdoc-gui/where-whitespace.goml b/src/test/rustdoc-gui/where-whitespace.goml
index 776c8ec72..41596a9bc 100644
--- a/src/test/rustdoc-gui/where-whitespace.goml
+++ b/src/test/rustdoc-gui/where-whitespace.goml
@@ -5,13 +5,13 @@ show-text: true
// line than "pub trait Whitespace<Idx>").
compare-elements-position-false: (".item-decl code", ".where.fmt-newline", ("y"))
// And that the code following it isn't on the same line either.
-compare-elements-position-false: (".item-decl .fnname", ".where.fmt-newline", ("y"))
+compare-elements-position-false: (".item-decl .fn", ".where.fmt-newline", ("y"))
goto: "file://" + |DOC_PATH| + "/lib2/struct.WhereWhitespace.html"
// We make the screen a bit wider to ensure that the trait impl is on one line.
size: (915, 915)
-compare-elements-position-false: ("#method\.new .fnname", "#method\.new .where.fmt-newline", ("y"))
+compare-elements-position-false: ("#method\.new .fn", "#method\.new .where.fmt-newline", ("y"))
// We ensure that both the trait name and the struct name are on the same line in
// "impl<K, T> Whitespace<&K> for WhereWhitespace<T>".
compare-elements-position: (
diff --git a/src/test/rustdoc-js/reexport.js b/src/test/rustdoc-js/reexport.js
new file mode 100644
index 000000000..871e75d9b
--- /dev/null
+++ b/src/test/rustdoc-js/reexport.js
@@ -0,0 +1,17 @@
+// exact-check
+
+const QUERY = ['Subscriber', 'AnotherOne'];
+
+const EXPECTED = [
+ {
+ 'others': [
+ { 'path': 'reexport::fmt', 'name': 'Subscriber' },
+ { 'path': 'reexport', 'name': 'FmtSubscriber' },
+ ],
+ },
+ {
+ 'others': [
+ { 'path': 'reexport', 'name': 'AnotherOne' },
+ ],
+ },
+];
diff --git a/src/test/rustdoc-js/reexport.rs b/src/test/rustdoc-js/reexport.rs
new file mode 100644
index 000000000..d69b2901e
--- /dev/null
+++ b/src/test/rustdoc-js/reexport.rs
@@ -0,0 +1,11 @@
+// This test enforces that the (renamed) reexports are present in the search results.
+
+pub mod fmt {
+ pub struct Subscriber;
+}
+mod foo {
+ pub struct AnotherOne;
+}
+
+pub use foo::AnotherOne;
+pub use fmt::Subscriber as FmtSubscriber;
diff --git a/src/test/rustdoc-json/enums/auxiliary/color.rs b/src/test/rustdoc-json/enums/auxiliary/color.rs
new file mode 100644
index 000000000..7188f7938
--- /dev/null
+++ b/src/test/rustdoc-json/enums/auxiliary/color.rs
@@ -0,0 +1,5 @@
+pub enum Color {
+ Red,
+ Green,
+ Blue,
+}
diff --git a/src/test/rustdoc-json/enums/doc_link_to_foreign_variant.rs b/src/test/rustdoc-json/enums/doc_link_to_foreign_variant.rs
new file mode 100644
index 000000000..470b195a2
--- /dev/null
+++ b/src/test/rustdoc-json/enums/doc_link_to_foreign_variant.rs
@@ -0,0 +1,11 @@
+// aux-build: color.rs
+
+//! The purpose of this test it to have a link to [a foreign variant](Red).
+
+extern crate color;
+use color::Color::Red;
+
+// @set red = "$.index[*][?(@.inner.is_crate == true)].links.Red"
+
+// @!has "$.index[*][?(@.name == 'Red')]"
+// @!has "$.index[*][?(@.name == 'Color')]"
diff --git a/src/test/rustdoc-json/enums/use_glob.rs b/src/test/rustdoc-json/enums/use_glob.rs
new file mode 100644
index 000000000..62b8b832a
--- /dev/null
+++ b/src/test/rustdoc-json/enums/use_glob.rs
@@ -0,0 +1,18 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/104942>
+
+#![feature(no_core)]
+#![no_core]
+
+// @set Color = "$.index[*][?(@.name == 'Color')].id"
+pub enum Color {
+ Red,
+ Green,
+ Blue,
+}
+
+// @set use_Color = "$.index[*][?(@.kind == 'import')].id"
+// @is "$.index[*][?(@.kind == 'import')].inner.id" $Color
+// @is "$.index[*][?(@.kind == 'import')].inner.glob" true
+pub use Color::*;
+
+// @ismany "$.index[*][?(@.name == 'use_glob')].inner.items[*]" $Color $use_Color
diff --git a/src/test/rustdoc-json/enums/use_variant.rs b/src/test/rustdoc-json/enums/use_variant.rs
new file mode 100644
index 000000000..5f0d2b9b1
--- /dev/null
+++ b/src/test/rustdoc-json/enums/use_variant.rs
@@ -0,0 +1,15 @@
+#![feature(no_core)]
+#![no_core]
+
+// @set AlwaysNone = "$.index[*][?(@.name == 'AlwaysNone')].id"
+pub enum AlwaysNone {
+ // @set None = "$.index[*][?(@.name == 'None')].id"
+ None,
+}
+// @is "$.index[*][?(@.name == 'AlwaysNone')].inner.variants[*]" $None
+
+// @set use_None = "$.index[*][?(@.kind == 'import')].id"
+// @is "$.index[*][?(@.kind == 'import')].inner.id" $None
+pub use AlwaysNone::None;
+
+// @ismany "$.index[*][?(@.name == 'use_variant')].inner.items[*]" $AlwaysNone $use_None
diff --git a/src/test/rustdoc-json/enums/use_variant_foreign.rs b/src/test/rustdoc-json/enums/use_variant_foreign.rs
new file mode 100644
index 000000000..11bb6ce1f
--- /dev/null
+++ b/src/test/rustdoc-json/enums/use_variant_foreign.rs
@@ -0,0 +1,9 @@
+// aux-build: color.rs
+
+extern crate color;
+
+// @is "$.index[*][?(@.inner.name == 'Red')].kind" '"import"'
+pub use color::Color::Red;
+
+// @!has "$.index[*][?(@.name == 'Red')]"
+// @!has "$.index[*][?(@.name == 'Color')]"
diff --git a/src/test/rustdoc-json/fns/pattern_arg.rs b/src/test/rustdoc-json/fns/pattern_arg.rs
new file mode 100644
index 000000000..32b7da0fa
--- /dev/null
+++ b/src/test/rustdoc-json/fns/pattern_arg.rs
@@ -0,0 +1,7 @@
+// @is "$.index[*][?(@.name=='fst')].inner.decl.inputs[0][0]" '"(x, _)"'
+pub fn fst<X, Y>((x, _): (X, Y)) -> X {
+ x
+}
+
+// @is "$.index[*][?(@.name=='drop_int')].inner.decl.inputs[0][0]" '"_"'
+pub fn drop_int(_: i32) {}
diff --git a/src/test/rustdoc-json/fns/return_type_alias.rs b/src/test/rustdoc-json/fns/return_type_alias.rs
new file mode 100644
index 000000000..2578bb49a
--- /dev/null
+++ b/src/test/rustdoc-json/fns/return_type_alias.rs
@@ -0,0 +1,10 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/104851>
+
+/// @set foo = "$.index[*][?(@.name=='Foo')].id"
+pub type Foo = i32;
+
+// @is "$.index[*][?(@.name=='demo')].inner.decl.output.kind" '"resolved_path"'
+// @is "$.index[*][?(@.name=='demo')].inner.decl.output.inner.id" $foo
+pub fn demo() -> Foo {
+ 42
+}
diff --git a/src/test/rustdoc-json/impls/import_from_private.rs b/src/test/rustdoc-json/impls/import_from_private.rs
index 856f7c701..fa88b6113 100644
--- a/src/test/rustdoc-json/impls/import_from_private.rs
+++ b/src/test/rustdoc-json/impls/import_from_private.rs
@@ -8,7 +8,7 @@ mod bar {
pub struct Baz;
// @set impl = "$.index[*][?(@.kind=='impl')].id"
impl Baz {
- // @set doit = "$.index[*][?(@.kind=='method')].id"
+ // @set doit = "$.index[*][?(@.kind=='function')].id"
pub fn doit() {}
}
}
diff --git a/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs b/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs
new file mode 100644
index 000000000..bfe85f59e
--- /dev/null
+++ b/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs
@@ -0,0 +1,8 @@
+pub trait Trait {
+ /// [`Enum::Variant`]
+ fn method() {}
+}
+
+pub enum Enum {
+ Variant,
+}
diff --git a/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs b/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs
new file mode 100644
index 000000000..e29682313
--- /dev/null
+++ b/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs
@@ -0,0 +1,13 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/105025>
+// aux-build: enum_variant_in_trait_method.rs
+
+extern crate enum_variant_in_trait_method;
+
+pub struct Local;
+
+/// local impl
+impl enum_variant_in_trait_method::Trait for Local {}
+
+// @!has "$.index[*][?(@.name == 'Trait')]"
+// @!has "$.index[*][?(@.name == 'method')]"
+// @count "$.index[*][?(@.docs == 'local impl')].inner.items[*]" 0
diff --git a/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs b/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs
new file mode 100644
index 000000000..1e87966b2
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs
@@ -0,0 +1,2 @@
+/// The Docs
+pub trait HasDocs {}
diff --git a/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs b/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs
new file mode 100644
index 000000000..25a7c08d6
--- /dev/null
+++ b/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs
@@ -0,0 +1,10 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/105022>
+// aux-build: trait_with_docs.rs
+
+extern crate trait_with_docs;
+
+pub struct Local;
+
+impl trait_with_docs::HasDocs for Local {}
+
+// @!has "$.index[*][?(@.name == 'HasDocs')]"
diff --git a/src/test/rustdoc-json/traits/trait_alias.rs b/src/test/rustdoc-json/traits/trait_alias.rs
new file mode 100644
index 000000000..35db9296c
--- /dev/null
+++ b/src/test/rustdoc-json/traits/trait_alias.rs
@@ -0,0 +1,30 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/104923>
+// ignore-tidy-linelength
+
+#![feature(trait_alias)]
+
+// @set Orig = "$.index[*][?(@.name == 'Orig')].id"
+// @is "$.index[*][?(@.name == 'Orig')].kind" '"trait"'
+pub trait Orig<T> {}
+
+// @set Alias = "$.index[*][?(@.name == 'Alias')].id"
+// @is "$.index[*][?(@.name == 'Alias')].kind" '"trait_alias"'
+// @is "$.index[*][?(@.name == 'Alias')].inner.generics" '{"params": [], "where_predicates": []}'
+// @count "$.index[*][?(@.name == 'Alias')].inner.params[*]" 1
+// @is "$.index[*][?(@.name == 'Alias')].inner.params[0].trait_bound.trait.id" $Orig
+// @is "$.index[*][?(@.name == 'Alias')].inner.params[0].trait_bound.trait.args.angle_bracketed.args[0].type.inner" '"i32"'
+pub trait Alias = Orig<i32>;
+
+pub struct Struct;
+
+impl Orig<i32> for Struct {}
+
+// @is "$.index[*][?(@.name=='takes_alias')].inner.decl.inputs[0][1].kind" '"impl_trait"'
+// @is "$.index[*][?(@.name=='takes_alias')].inner.decl.inputs[0][1].inner[0].trait_bound.trait.id" $Alias
+// @is "$.index[*][?(@.name=='takes_alias')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $Alias
+pub fn takes_alias(_: impl Alias) {}
+// FIXME: Should the trait be mentioned in both the decl and generics?
+
+fn main() {
+ takes_alias(Struct);
+}
diff --git a/src/test/rustdoc-json/traits/uses_extern_trait.rs b/src/test/rustdoc-json/traits/uses_extern_trait.rs
index 430dd1543..55a51f739 100644
--- a/src/test/rustdoc-json/traits/uses_extern_trait.rs
+++ b/src/test/rustdoc-json/traits/uses_extern_trait.rs
@@ -1,7 +1,5 @@
#![no_std]
pub fn drop_default<T: core::default::Default>(_x: T) {}
-// FIXME(adotinthevoid): Theses shouldn't be here
-// @has "$.index[*][?(@.name=='Debug')]"
-// @set Debug_fmt = "$.index[*][?(@.name=='Debug')].inner.items[*]"
-// @has "$.index[*][?(@.name=='fmt')].id" $Debug_fmt
+// @!has "$.index[*][?(@.name=='Debug')]"
+// @!has "$.index[*][?(@.name=='Default')]"
diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
index e58bba640..94ea0e93b 100644
--- a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
+++ b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.rs
@@ -1,3 +1,4 @@
+// check-pass
// This test ensures that rustdoc does not panic on inherented associated types
// that are referred to without fully-qualified syntax.
@@ -9,8 +10,4 @@ pub struct Struct;
impl Struct {
pub type AssocTy = usize;
pub const AssocConst: Self::AssocTy = 42;
- //~^ ERROR ambiguous associated type
- //~| HELP use fully-qualified syntax
- //~| ERROR ambiguous associated type
- //~| HELP use fully-qualified syntax
}
diff --git a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr b/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr
deleted file mode 100644
index b963b722f..000000000
--- a/src/test/rustdoc-ui/ambiguous-inherent-assoc-ty.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0223]: ambiguous associated type
- --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27
- |
-LL | pub const AssocConst: Self::AssocTy = 42;
- | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy`
-
-error[E0223]: ambiguous associated type
- --> $DIR/ambiguous-inherent-assoc-ty.rs:11:27
- |
-LL | pub const AssocConst: Self::AssocTy = 42;
- | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0223`.
diff --git a/src/test/rustdoc/const-evalutation-ice.rs b/src/test/rustdoc-ui/const-evalutation-ice.rs
index 68c7f9c56..0dd3bcaa2 100644
--- a/src/test/rustdoc/const-evalutation-ice.rs
+++ b/src/test/rustdoc-ui/const-evalutation-ice.rs
@@ -7,4 +7,5 @@ pub struct S {
s: Cell<usize>
}
-pub const N: usize = 0 - (mem::size_of::<S>() != 4) as usize;
+pub const N: usize = 0 - (mem::size_of::<S>() != 400) as usize;
+//~^ ERROR evaluation of constant value failed
diff --git a/src/test/rustdoc-ui/const-evalutation-ice.stderr b/src/test/rustdoc-ui/const-evalutation-ice.stderr
new file mode 100644
index 000000000..5d9c16c07
--- /dev/null
+++ b/src/test/rustdoc-ui/const-evalutation-ice.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-evalutation-ice.rs:10:22
+ |
+LL | pub const N: usize = 0 - (mem::size_of::<S>() != 400) as usize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
index e7b4c43e7..19e541736 100644
--- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
+++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
@@ -4,7 +4,7 @@ error: unknown disambiguator `foo`
LL | //! Linking to [foo@banana] and [`bar@banana!()`].
| ^^^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
note: the lint level is defined here
--> $DIR/unknown-disambiguator.rs:2:9
|
@@ -18,7 +18,7 @@ error: unknown disambiguator `bar`
LL | //! Linking to [foo@banana] and [`bar@banana!()`].
| ^^^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: unknown disambiguator `foo`
--> $DIR/unknown-disambiguator.rs:10:34
@@ -26,7 +26,7 @@ error: unknown disambiguator `foo`
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
| ^^^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: unknown disambiguator `foo`
--> $DIR/unknown-disambiguator.rs:10:48
@@ -34,7 +34,7 @@ error: unknown disambiguator `foo`
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
| ^^^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: unknown disambiguator ``
--> $DIR/unknown-disambiguator.rs:7:31
@@ -42,7 +42,7 @@ error: unknown disambiguator ``
LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
| ^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: unknown disambiguator ``
--> $DIR/unknown-disambiguator.rs:7:57
@@ -50,7 +50,7 @@ error: unknown disambiguator ``
LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
| ^
|
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
+ = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
error: aborting due to 6 previous errors
diff --git a/src/test/rustdoc-ui/issue-103997.rs b/src/test/rustdoc-ui/issue-103997.rs
new file mode 100644
index 000000000..36f42fb15
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-103997.rs
@@ -0,0 +1,6 @@
+// check-pass
+
+pub fn foo() {}
+
+/// [`foo`](Self::foo) //~ WARNING unresolved link to `Self::foo`
+pub use foo as bar;
diff --git a/src/test/rustdoc-ui/issue-103997.stderr b/src/test/rustdoc-ui/issue-103997.stderr
new file mode 100644
index 000000000..c06db9149
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-103997.stderr
@@ -0,0 +1,10 @@
+warning: unresolved link to `Self::foo`
+ --> $DIR/issue-103997.rs:5:13
+ |
+LL | /// [`foo`](Self::foo)
+ | ^^^^^^^^^ no item named `Self` in scope
+ |
+ = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/rustdoc-ui/issue-91713.stdout b/src/test/rustdoc-ui/issue-91713.stdout
index a19e452b4..167835243 100644
--- a/src/test/rustdoc-ui/issue-91713.stdout
+++ b/src/test/rustdoc-ui/issue-91713.stdout
@@ -5,11 +5,9 @@ check_doc_test_visibility - run various visibility-related lints on doctests
strip-priv-imports - strips all private import statements (`use`, `extern crate`) from a crate
propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items
collect-intra-doc-links - resolves intra-doc links
-check-code-block-syntax - validates syntax inside Rust code blocks
collect-trait-impls - retrieves trait impls for items in the crate
calculate-doc-coverage - counts the number of items with and without documentation
-check-invalid-html-tags - detects invalid HTML tags in doc comments
- check-bare-urls - detects URLs that are not hyperlinks
+ run-lints - runs some of rustdoc's lints
Default passes for rustdoc:
collect-trait-impls
@@ -18,10 +16,8 @@ check_doc_test_visibility
strip-private (when not --document-private-items)
strip-priv-imports (when --document-private-items)
collect-intra-doc-links
-check-code-block-syntax
-check-invalid-html-tags
propagate-doc-cfg
- check-bare-urls
+ run-lints
Passes run with `--show-coverage`:
strip-hidden (when not --document-hidden-items)
diff --git a/src/test/rustdoc-ui/track-diagnostics.rs b/src/test/rustdoc-ui/track-diagnostics.rs
new file mode 100644
index 000000000..fcc50a7ab
--- /dev/null
+++ b/src/test/rustdoc-ui/track-diagnostics.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Z track-diagnostics
+// error-pattern: created at
+
+// Normalize the emitted location so this doesn't need
+// updating everytime someone adds or removes a line.
+// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
+
+struct A;
+struct B;
+const S: A = B;
diff --git a/src/test/rustdoc-ui/track-diagnostics.stderr b/src/test/rustdoc-ui/track-diagnostics.stderr
new file mode 100644
index 000000000..ec3031862
--- /dev/null
+++ b/src/test/rustdoc-ui/track-diagnostics.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> $DIR/track-diagnostics.rs:LL:CC
+ |
+LL | const S: A = B;
+ | ^ expected struct `A`, found struct `B`
+-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout
index 46f11d2e5..94cf7b942 100644
--- a/src/test/rustdoc-ui/z-help.stdout
+++ b/src/test/rustdoc-ui/z-help.stdout
@@ -77,6 +77,7 @@
-Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`)
-Z ls=val -- list the symbols defined by a library crate (default: no)
-Z macro-backtrace=val -- show macro backtraces (default: no)
+ -Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no)
-Z merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name
-Z meta-stats=val -- gather metadata statistics (default: no)
-Z mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no)
@@ -90,7 +91,6 @@
-Z no-analysis=val -- parse and expand the source, but run no analysis
-Z no-codegen=val -- run all passes except codegen; no output
-Z no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups
- -Z no-interleave-lints=val -- execute lints separately; allows benchmarking individual lints
-Z no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests
-Z no-link=val -- compile without linking
-Z no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)
@@ -171,6 +171,7 @@
-Z time-passes=val -- measure time of each rustc pass (default: no)
-Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details)
-Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no)
+ -Z track-diagnostics=val -- tracks where in rustc a diagnostic was emitted
-Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation)
-Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics
-Z translate-lang=val -- language identifier for diagnostic output
diff --git a/src/test/rustdoc/anchors.no_method_anchor.html b/src/test/rustdoc/anchors.no_method_anchor.html
index 521fdcb78..b9ec8bf4c 100644
--- a/src/test/rustdoc/anchors.no_method_anchor.html
+++ b/src/test/rustdoc/anchors.no_method_anchor.html
@@ -1 +1 @@
-<section id="method.new" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#48">source</a><h4 class="code-header">pub fn <a href="#method.new" class="fnname">new</a>() -&gt; Self</h4></section> \ No newline at end of file
+<section id="method.new" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#48">source</a><h4 class="code-header">pub fn <a href="#method.new" class="fn">new</a>() -&gt; Self</h4></section> \ No newline at end of file
diff --git a/src/test/rustdoc/anchors.no_trait_method_anchor.html b/src/test/rustdoc/anchors.no_trait_method_anchor.html
index d7bd525ff..4308ddad4 100644
--- a/src/test/rustdoc/anchors.no_trait_method_anchor.html
+++ b/src/test/rustdoc/anchors.no_trait_method_anchor.html
@@ -1 +1 @@
-<section id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fnname">bar</a>()</h4></section> \ No newline at end of file
+<section id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fn">bar</a>()</h4></section> \ No newline at end of file
diff --git a/src/test/rustdoc/anchors.no_tymethod_anchor.html b/src/test/rustdoc/anchors.no_tymethod_anchor.html
index e668e5e4d..91eed8a37 100644
--- a/src/test/rustdoc/anchors.no_tymethod_anchor.html
+++ b/src/test/rustdoc/anchors.no_tymethod_anchor.html
@@ -1 +1 @@
-<section id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fnname">foo</a>()</h4></section> \ No newline at end of file
+<section id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fn">foo</a>()</h4></section> \ No newline at end of file
diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs
index a3e10ee55..3da19a13e 100644
--- a/src/test/rustdoc/assoc-consts.rs
+++ b/src/test/rustdoc/assoc-consts.rs
@@ -46,6 +46,7 @@ pub fn f(_: &(ToString + 'static)) {}
impl Bar {
// @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \
// "const F: fn(_: &(dyn ToString + 'static))"
+ // FIXME(fmease): Hide default lifetime, render "const F: fn(_: &dyn ToString)"
pub const F: fn(_: &(ToString + 'static)) = f;
}
diff --git a/src/test/rustdoc/async-trait-sig.rs b/src/test/rustdoc/async-trait-sig.rs
new file mode 100644
index 000000000..2578bc8f7
--- /dev/null
+++ b/src/test/rustdoc/async-trait-sig.rs
@@ -0,0 +1,14 @@
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+pub trait Foo {
+ // @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn bar() -> i32"
+ async fn bar() -> i32;
+
+ // @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn baz() -> i32"
+ async fn baz() -> i32 {
+ 1
+ }
+}
diff --git a/src/test/rustdoc/auxiliary/masked.rs b/src/test/rustdoc/auxiliary/masked.rs
index f289359e5..3d722d5e0 100644
--- a/src/test/rustdoc/auxiliary/masked.rs
+++ b/src/test/rustdoc/auxiliary/masked.rs
@@ -8,3 +8,7 @@ pub trait MaskedTrait {
impl MaskedTrait for String {
fn masked_method() {}
}
+
+pub trait MaskedBlanketTrait {}
+
+impl<T> MaskedBlanketTrait for T {}
diff --git a/src/test/rustdoc/bounds-in-multiple-parts.rs b/src/test/rustdoc/bounds-in-multiple-parts.rs
new file mode 100644
index 000000000..279e3c148
--- /dev/null
+++ b/src/test/rustdoc/bounds-in-multiple-parts.rs
@@ -0,0 +1,20 @@
+#![crate_name = "foo"]
+
+pub trait Eq {}
+pub trait Eq2 {}
+
+// Checking that "where predicates" and "generics params" are merged.
+// @has 'foo/trait.T.html'
+// @has - "//*[@id='tymethod.f']/h4" "fn f<'a, 'b, 'c, T>()where Self: Eq, T: Eq + 'a, 'c: 'b + 'a,"
+pub trait T {
+ fn f<'a, 'b, 'c: 'a, T: Eq + 'a>()
+ where Self: Eq, Self: Eq, T: Eq, 'c: 'b;
+}
+
+// Checking that a duplicated "where predicate" is removed.
+// @has 'foo/trait.T2.html'
+// @has - "//*[@id='tymethod.f']/h4" "fn f<T>()where Self: Eq + Eq2, T: Eq2 + Eq,"
+pub trait T2 {
+ fn f<T: Eq>()
+ where Self: Eq, Self: Eq2, T: Eq2;
+}
diff --git a/src/test/rustdoc/check-source-code-urls-to-def.rs b/src/test/rustdoc/check-source-code-urls-to-def.rs
index d00a3e355..5959f9c7c 100644
--- a/src/test/rustdoc/check-source-code-urls-to-def.rs
+++ b/src/test/rustdoc/check-source-code-urls-to-def.rs
@@ -10,14 +10,14 @@ extern crate source_code;
// @has 'src/foo/check-source-code-urls-to-def.rs.html'
-// @has - '//a[@href="auxiliary/source-code-bar.rs.html#1-17"]' 'bar'
+// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#1-17"]' 'bar'
#[path = "auxiliary/source-code-bar.rs"]
pub mod bar;
-// @count - '//a[@href="auxiliary/source-code-bar.rs.html#5"]' 4
+// @count - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#5"]' 4
use bar::Bar;
-// @has - '//a[@href="auxiliary/source-code-bar.rs.html#13"]' 'self'
-// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait'
+// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#13"]' 'self'
+// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait'
use bar::sub::{self, Trait};
pub struct Foo;
@@ -28,29 +28,29 @@ impl Foo {
fn babar() {}
-// @has - '//a/@href' '/struct.String.html'
-// @has - '//a/@href' '/primitive.u32.html'
-// @has - '//a/@href' '/primitive.str.html'
-// @count - '//a[@href="#23"]' 5
-// @has - '//a[@href="../../source_code/struct.SourceCode.html"]' 'source_code::SourceCode'
+// @has - '//pre[@class="rust"]//a/@href' '/struct.String.html'
+// @has - '//pre[@class="rust"]//a/@href' '/primitive.u32.html'
+// @has - '//pre[@class="rust"]//a/@href' '/primitive.str.html'
+// @count - '//pre[@class="rust"]//a[@href="#23"]' 5
+// @has - '//pre[@class="rust"]//a[@href="../../source_code/struct.SourceCode.html"]' 'source_code::SourceCode'
pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::SourceCode) {
let x = 12;
let y: Foo = Foo;
let z: Bar = bar::Bar { field: Foo };
babar();
- // @has - '//a[@href="#26"]' 'hello'
+ // @has - '//pre[@class="rust"]//a[@href="#26"]' 'hello'
y.hello();
}
-// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'bar::sub::Trait'
-// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait'
+// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'bar::sub::Trait'
+// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait'
pub fn foo2<T: bar::sub::Trait, V: Trait>(t: &T, v: &V, b: bool) {}
pub trait AnotherTrait {}
pub trait WhyNot {}
-// @has - '//a[@href="#49"]' 'AnotherTrait'
-// @has - '//a[@href="#50"]' 'WhyNot'
+// @has - '//pre[@class="rust"]//a[@href="#49"]' 'AnotherTrait'
+// @has - '//pre[@class="rust"]//a[@href="#50"]' 'WhyNot'
pub fn foo3<T, V>(t: &T, v: &V)
where
T: AnotherTrait,
@@ -59,11 +59,11 @@ where
pub trait AnotherTrait2 {}
-// @has - '//a[@href="#60"]' 'AnotherTrait2'
+// @has - '//pre[@class="rust"]//a[@href="#60"]' 'AnotherTrait2'
pub fn foo4() {
let x: Vec<AnotherTrait2> = Vec::new();
}
-// @has - '//a[@href="../../foo/primitive.bool.html"]' 'bool'
+// @has - '//pre[@class="rust"]//a[@href="../../foo/primitive.bool.html"]' 'bool'
#[doc(primitive = "bool")]
mod whatever {}
diff --git a/src/test/rustdoc/decl-trailing-whitespace.declaration.html b/src/test/rustdoc/decl-trailing-whitespace.declaration.html
index e60caaeff..02b51b344 100644
--- a/src/test/rustdoc/decl-trailing-whitespace.declaration.html
+++ b/src/test/rustdoc/decl-trailing-whitespace.declaration.html
@@ -1,7 +1,7 @@
<code>pub trait Write {
- fn <a href="#tymethod.poll_write" class="fnname">poll_write</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;buf: &amp;mut [<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
-<span class="item-spacer" /> fn <a href="#tymethod.poll_flush" class="fnname">poll_flush</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
-<span class="item-spacer" /> fn <a href="#tymethod.poll_close" class="fnname">poll_close</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
+ fn <a href="#tymethod.poll_write" class="fn">poll_write</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;buf: &amp;mut [<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
+<span class="item-spacer" /> fn <a href="#tymethod.poll_flush" class="fn">poll_flush</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
+<span class="item-spacer" /> fn <a href="#tymethod.poll_close" class="fn">poll_close</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
- fn <a href="#method.poll_write_vectored" class="fnname">poll_write_vectored</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;bufs: &amp;[<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt; { ... }
-}</code>
+ fn <a href="#method.poll_write_vectored" class="fn">poll_write_vectored</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;bufs: &amp;[<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt; { ... }
+}</code> \ No newline at end of file
diff --git a/src/test/rustdoc/deref-to-primitive.rs b/src/test/rustdoc/deref-to-primitive.rs
new file mode 100644
index 000000000..527de780d
--- /dev/null
+++ b/src/test/rustdoc/deref-to-primitive.rs
@@ -0,0 +1,15 @@
+#![crate_name = "foo"]
+
+// @has 'foo/struct.Foo.html'
+// @has - '//*[@id="deref-methods-i32"]' 'Methods from Deref<Target = i32>'
+// @has - '//*[@id="deref-methods-i32-1"]//*[@id="associatedconstant.BITS"]/h4' \
+// 'pub const BITS: u32 = 32u32'
+pub struct Foo(i32);
+
+impl std::ops::Deref for Foo {
+ type Target = i32;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
diff --git a/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html b/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html
new file mode 100644
index 000000000..f2ec8320a
--- /dev/null
+++ b/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html
@@ -0,0 +1 @@
+<script type="text/json" id="notable-traits-data">{"&amp;'static [SomeStruct]":"&lt;h3&gt;Notable traits for &lt;code&gt;&amp;amp;[&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\"&gt;SomeStruct&lt;/a&gt;]&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &amp;amp;[&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\"&gt;SomeStruct&lt;/a&gt;]&lt;/span&gt;"}</script> \ No newline at end of file
diff --git a/src/test/rustdoc/doc-notable_trait-slice.rs b/src/test/rustdoc/doc-notable_trait-slice.rs
index b0d414027..2411da8cd 100644
--- a/src/test/rustdoc/doc-notable_trait-slice.rs
+++ b/src/test/rustdoc/doc-notable_trait-slice.rs
@@ -8,13 +8,13 @@ pub struct OtherStruct;
impl SomeTrait for &[SomeStruct] {}
// @has doc_notable_trait_slice/fn.bare_fn_matches.html
-// @has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]'
+// @snapshot bare_fn_matches - '//script[@id="notable-traits-data"]'
pub fn bare_fn_matches() -> &'static [SomeStruct] {
&[]
}
// @has doc_notable_trait_slice/fn.bare_fn_no_matches.html
-// @!has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]'
+// @count - '//script[@id="notable-traits-data"]' 0
pub fn bare_fn_no_matches() -> &'static [OtherStruct] {
&[]
}
diff --git a/src/test/rustdoc/doc-notable_trait.bare-fn.html b/src/test/rustdoc/doc-notable_trait.bare-fn.html
new file mode 100644
index 000000000..b426a4d7a
--- /dev/null
+++ b/src/test/rustdoc/doc-notable_trait.bare-fn.html
@@ -0,0 +1 @@
+<script type="text/json" id="notable-traits-data">{"SomeStruct":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/span&gt;"}</script> \ No newline at end of file
diff --git a/src/test/rustdoc/doc-notable_trait.rs b/src/test/rustdoc/doc-notable_trait.rs
index 58a24b855..279faf554 100644
--- a/src/test/rustdoc/doc-notable_trait.rs
+++ b/src/test/rustdoc/doc-notable_trait.rs
@@ -9,7 +9,8 @@ impl<T: SomeTrait> SomeTrait for Wrapper<T> {}
#[doc(notable_trait)]
pub trait SomeTrait {
// @has doc_notable_trait/trait.SomeTrait.html
- // @has - '//code[@class="content"]' 'impl<T: SomeTrait> SomeTrait for Wrapper<T>'
+ // @has - '//a[@class="notable-traits"]/@data-ty' 'Wrapper<Self>'
+ // @snapshot wrap-me - '//script[@id="notable-traits-data"]'
fn wrap_me(self) -> Wrapper<Self> where Self: Sized {
Wrapper {
inner: self,
@@ -22,15 +23,16 @@ impl SomeTrait for SomeStruct {}
impl SomeStruct {
// @has doc_notable_trait/struct.SomeStruct.html
- // @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct'
- // @has - '//code[@class="content"]' 'impl<T: SomeTrait> SomeTrait for Wrapper<T>'
+ // @has - '//a[@class="notable-traits"]/@data-ty' 'SomeStruct'
+ // @snapshot some-struct-new - '//script[@id="notable-traits-data"]'
pub fn new() -> SomeStruct {
SomeStruct
}
}
// @has doc_notable_trait/fn.bare_fn.html
-// @has - '//code[@class="content"]' 'impl SomeTrait for SomeStruct'
+// @has - '//a[@class="notable-traits"]/@data-ty' 'SomeStruct'
+// @snapshot bare-fn - '//script[@id="notable-traits-data"]'
pub fn bare_fn() -> SomeStruct {
SomeStruct
}
diff --git a/src/test/rustdoc/doc-notable_trait.some-struct-new.html b/src/test/rustdoc/doc-notable_trait.some-struct-new.html
new file mode 100644
index 000000000..4f8063807
--- /dev/null
+++ b/src/test/rustdoc/doc-notable_trait.some-struct-new.html
@@ -0,0 +1 @@
+<script type="text/json" id="notable-traits-data">{"SomeStruct":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\"&gt;SomeStruct&lt;/a&gt;&lt;/span&gt;","Wrapper&lt;Self&gt;":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl&amp;lt;T:&amp;nbsp;&lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt;&amp;gt; &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/span&gt;"}</script> \ No newline at end of file
diff --git a/src/test/rustdoc/doc-notable_trait.wrap-me.html b/src/test/rustdoc/doc-notable_trait.wrap-me.html
new file mode 100644
index 000000000..bed2a38b2
--- /dev/null
+++ b/src/test/rustdoc/doc-notable_trait.wrap-me.html
@@ -0,0 +1 @@
+<script type="text/json" id="notable-traits-data">{"Wrapper&lt;Self&gt;":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl&amp;lt;T:&amp;nbsp;&lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt;&amp;gt; &lt;a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\"&gt;SomeTrait&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\"&gt;Wrapper&lt;/a&gt;&amp;lt;T&amp;gt;&lt;/span&gt;"}</script> \ No newline at end of file
diff --git a/src/test/rustdoc/extern-default-method.no_href_on_anchor.html b/src/test/rustdoc/extern-default-method.no_href_on_anchor.html
index dab0a6495..ef14836cc 100644
--- a/src/test/rustdoc/extern-default-method.no_href_on_anchor.html
+++ b/src/test/rustdoc/extern-default-method.no_href_on_anchor.html
@@ -1 +1 @@
-<a class="fnname">provided</a>(&amp;self) \ No newline at end of file
+<a class="fn">provided</a>(&amp;self) \ No newline at end of file
diff --git a/src/test/rustdoc/extern-default-method.rs b/src/test/rustdoc/extern-default-method.rs
index 8139f5b26..fc28b230a 100644
--- a/src/test/rustdoc/extern-default-method.rs
+++ b/src/test/rustdoc/extern-default-method.rs
@@ -11,13 +11,13 @@ extern crate rustdoc_extern_default_method as ext;
// However, the method in the trait impl should *not* have a link (an `href` attribute) to
// its corresponding item in the trait declaration since it would otherwise be broken.
//
-// In older versions of rustdoc, the impl item (`a[@class="fnname"]`) used to link to
+// In older versions of rustdoc, the impl item (`a[@class="fn"]`) used to link to
// `#method.provided` – i.e. "to itself". Put in quotes since that was actually incorrect in
// general: If the type `Struct` also had an inherent method called `provided`, the impl item
// would link to that one even though those two methods are distinct items!
// @count extern_default_method/struct.Struct.html '//*[@id="method.provided"]' 1
-// @count extern_default_method/struct.Struct.html '//*[@id="method.provided"]//a[@class="fnname"]' 1
-// @snapshot no_href_on_anchor - '//*[@id="method.provided"]//a[@class="fnname"]'
+// @count extern_default_method/struct.Struct.html '//*[@id="method.provided"]//a[@class="fn"]' 1
+// @snapshot no_href_on_anchor - '//*[@id="method.provided"]//a[@class="fn"]'
// @has extern_default_method/struct.Struct.html '//*[@id="method.provided"]//a[@class="anchor"]/@href' #method.provided
pub use ext::Struct;
diff --git a/src/test/rustdoc/foreigntype.rs b/src/test/rustdoc/foreigntype.rs
index 891cdd5fe..29f9c2926 100644
--- a/src/test/rustdoc/foreigntype.rs
+++ b/src/test/rustdoc/foreigntype.rs
@@ -6,7 +6,7 @@ extern "C" {
}
impl ExtType {
- // @has - '//a[@class="fnname"]' 'do_something'
+ // @has - '//a[@class="fn"]' 'do_something'
pub fn do_something(&self) {}
}
diff --git a/src/test/rustdoc/impl-parts.rs b/src/test/rustdoc/impl-parts.rs
index 7b931727e..90cbb77cb 100644
--- a/src/test/rustdoc/impl-parts.rs
+++ b/src/test/rustdoc/impl-parts.rs
@@ -6,7 +6,7 @@ pub auto trait AnAutoTrait {}
pub struct Foo<T> { field: T }
// @has impl_parts/struct.Foo.html '//*[@class="impl has-srclink"]//h3[@class="code-header"]' \
-// "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync,"
+// "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
// @has impl_parts/trait.AnAutoTrait.html '//*[@id="implementors-list"]//h3[@class="code-header"]' \
-// "impl<T: Clone> !AnAutoTrait for Foo<T>where T: Sync,"
+// "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
impl<T: Clone> !AnAutoTrait for Foo<T> where T: Sync {}
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs
index 5f4712aab..db2491b87 100644
--- a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs
+++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs
@@ -33,8 +33,12 @@ extern crate assoc_item_trait_bounds as aux;
// @snapshot out9 - '//*[@id="associatedtype.Out9"]/*[@class="code-header"]'
//
// @has - '//*[@id="tymethod.make"]' \
-// "fn make<F>(F, impl FnMut(&str) -> bool)\
+// "fn make<F>(_: F, _: impl FnMut(&str) -> bool)\
// where \
// F: FnOnce(u32) -> String, \
// Self::Out2<()>: Protocol<u8, Q0 = Self::Item, Q1 = ()>"
pub use aux::Main;
+
+// @has main/trait.Aid.html
+// @has - '//*[@id="associatedtype.Result"]' "type Result<'inter: 'src>"
+pub use aux::Aid;
diff --git a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
index d326e61da..6644c8e41 100644
--- a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
+++ b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
@@ -42,5 +42,5 @@ pub trait Helper {
}
pub trait Aid<'src> {
- type Result<'inter>;
+ type Result<'inter: 'src>;
}
diff --git a/src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs b/src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs
new file mode 100644
index 000000000..9ac2e3d96
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/auxiliary/dyn_trait.rs
@@ -0,0 +1,17 @@
+pub type Ty0 = dyn for<'any> FnOnce(&'any str) -> bool;
+
+pub type Ty1<'obj> = dyn std::fmt::Display + 'obj;
+
+pub type Ty2 = dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>;
+
+pub type Ty3<'s> = &'s dyn ToString;
+
+pub fn func0(_: &(dyn Fn() + '_)) {}
+
+pub fn func1<'func>(_: &(dyn Fn() + 'func)) {}
+
+pub trait Container<'r> {
+ type Item<'a, 'ctx>;
+}
+
+pub trait Shape<'a> {}
diff --git a/src/test/rustdoc/inline_cross/dyn_trait.rs b/src/test/rustdoc/inline_cross/dyn_trait.rs
new file mode 100644
index 000000000..fa760540e
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/dyn_trait.rs
@@ -0,0 +1,31 @@
+#![crate_name = "user"]
+
+// aux-crate:dyn_trait=dyn_trait.rs
+// edition:2021
+
+// @has user/type.Ty0.html
+// @has - '//*[@class="item-decl"]//code' "dyn for<'any> FnOnce(&'any str) -> bool + 'static"
+// FIXME(fmease): Hide default lifetime bound `'static`
+pub use dyn_trait::Ty0;
+
+// @has user/type.Ty1.html
+// @has - '//*[@class="item-decl"]//code' "dyn Display + 'obj"
+pub use dyn_trait::Ty1;
+
+// @has user/type.Ty2.html
+// @has - '//*[@class="item-decl"]//code' "dyn for<'a, 'r> Container<'r, Item<'a, 'static> = ()>"
+pub use dyn_trait::Ty2;
+
+// @has user/type.Ty3.html
+// @has - '//*[@class="item-decl"]//code' "&'s (dyn ToString + 's)"
+// FIXME(fmease): Hide default lifetime bound, render "&'s dyn ToString"
+pub use dyn_trait::Ty3;
+
+// @has user/fn.func0.html
+// @has - '//pre[@class="rust fn"]' "func0(_: &dyn Fn())"
+// FIXME(fmease): Show placeholder-lifetime bound, render "func0(_: &(dyn Fn() + '_))"
+pub use dyn_trait::func0;
+
+// @has user/fn.func1.html
+// @has - '//pre[@class="rust fn"]' "func1<'func>(_: &(dyn Fn() + 'func))"
+pub use dyn_trait::func1;
diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs
index 6c1cf8252..9c4f64659 100644
--- a/src/test/rustdoc/inline_cross/impl_trait.rs
+++ b/src/test/rustdoc/inline_cross/impl_trait.rs
@@ -29,7 +29,7 @@ pub use impl_trait_aux::func4;
// @has impl_trait/fn.func5.html
// @has - '//pre[@class="rust fn"]' "func5("
// @has - '//pre[@class="rust fn"]' "_f: impl for<'any> Fn(&'any str, &'any str) -> bool + for<'r> Other<T<'r> = ()>,"
-// @has - '//pre[@class="rust fn"]' "_a: impl for<'alpha, 'beta> Auxiliary<'alpha, Item<'beta> = fn(&'beta ())>"
+// @has - '//pre[@class="rust fn"]' "_a: impl for<'alpha, 'beta> Auxiliary<'alpha, Item<'beta> = fn(_: &'beta ())>"
// @!has - '//pre[@class="rust fn"]' 'where'
pub use impl_trait_aux::func5;
diff --git a/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html b/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html
index 6955a9614..f3c1c0452 100644
--- a/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html
+++ b/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html
@@ -1 +1 @@
-<h4 class="code-header">fn <a href="#method.touch" class="fnname">touch</a>(&amp;self)</h4> \ No newline at end of file
+<h4 class="code-header">fn <a href="#method.touch" class="fn">touch</a>(&amp;self)</h4> \ No newline at end of file
diff --git a/src/test/rustdoc/issue-102154.rs b/src/test/rustdoc/issue-102154.rs
new file mode 100644
index 000000000..b36f27080
--- /dev/null
+++ b/src/test/rustdoc/issue-102154.rs
@@ -0,0 +1,13 @@
+trait A<Y, N> {
+ type B;
+}
+type MaybeBox<T> = <T as A<T, Box<T>>>::B;
+struct P {
+ t: MaybeBox<P>
+}
+impl<Y, N> A<Y, N> for P {
+ type B = N;
+}
+fn main() {
+ let t: MaybeBox<P>;
+}
diff --git a/src/test/rustdoc/issue-20727.rs b/src/test/rustdoc/issue-20727.rs
index f7acffcb4..c1a98cd57 100644
--- a/src/test/rustdoc/issue-20727.rs
+++ b/src/test/rustdoc/issue-20727.rs
@@ -19,6 +19,6 @@ pub mod reexport {
// @has - '//*[@class="rust trait"]' 'trait Deref {'
// @has - '//*[@class="rust trait"]' 'type Target: ?Sized;'
// @has - '//*[@class="rust trait"]' \
- // "fn deref(&'a self) -> &'a Self::Target;"
+ // "fn deref<'a>(&'a self) -> &'a Self::Target;"
pub use issue_20727::Deref;
}
diff --git a/src/test/rustdoc/issue-41783.codeblock.html b/src/test/rustdoc/issue-41783.codeblock.html
index 89987491d..3bca4536c 100644
--- a/src/test/rustdoc/issue-41783.codeblock.html
+++ b/src/test/rustdoc/issue-41783.codeblock.html
@@ -1,5 +1,5 @@
<code># single
## double
### triple
-<span class="attribute">#[outer]
+<span class="attr">#[outer]
#![inner]</span></code>
diff --git a/src/test/rustdoc/issue-41783.rs b/src/test/rustdoc/issue-41783.rs
index 87267a750..769f984a2 100644
--- a/src/test/rustdoc/issue-41783.rs
+++ b/src/test/rustdoc/issue-41783.rs
@@ -1,10 +1,10 @@
// @has issue_41783/struct.Foo.html
// @!hasraw - 'space'
// @!hasraw - 'comment'
-// @hasraw - '<span class="attribute">#[outer]'
-// @!hasraw - '<span class="attribute">#[outer]</span>'
+// @hasraw - '<span class="attr">#[outer]'
+// @!hasraw - '<span class="attr">#[outer]</span>'
// @hasraw - '#![inner]</span>'
-// @!hasraw - '<span class="attribute">#![inner]</span>'
+// @!hasraw - '<span class="attr">#![inner]</span>'
// @snapshot 'codeblock' - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]//pre/code'
/// ```no_run
diff --git a/src/test/rustdoc/issue-88600.rs b/src/test/rustdoc/issue-88600.rs
index fc63ed343..db0d102b7 100644
--- a/src/test/rustdoc/issue-88600.rs
+++ b/src/test/rustdoc/issue-88600.rs
@@ -8,22 +8,22 @@ pub struct S;
// @has issue_88600/enum.FooEnum.html
pub enum FooEnum {
- // @has - '//*[@id="variant.HiddenTupleItem"]//code' 'HiddenTupleItem(_)'
+ // @has - '//*[@id="variant.HiddenTupleItem"]//h3' 'HiddenTupleItem(_)'
// @count - '//*[@id="variant.HiddenTupleItem.field.0"]' 0
HiddenTupleItem(#[doc(hidden)] H),
- // @has - '//*[@id="variant.MultipleHidden"]//code' 'MultipleHidden(_, _)'
+ // @has - '//*[@id="variant.MultipleHidden"]//h3' 'MultipleHidden(_, _)'
// @count - '//*[@id="variant.MultipleHidden.field.0"]' 0
// @count - '//*[@id="variant.MultipleHidden.field.1"]' 0
MultipleHidden(#[doc(hidden)] H, #[doc(hidden)] H),
- // @has - '//*[@id="variant.MixedHiddenFirst"]//code' 'MixedHiddenFirst(_, S)'
+ // @has - '//*[@id="variant.MixedHiddenFirst"]//h3' 'MixedHiddenFirst(_, S)'
// @count - '//*[@id="variant.MixedHiddenFirst.field.0"]' 0
// @has - '//*[@id="variant.MixedHiddenFirst.field.1"]' '1: S'
MixedHiddenFirst(#[doc(hidden)] H, /** dox */ S),
- // @has - '//*[@id="variant.MixedHiddenLast"]//code' 'MixedHiddenLast(S, _)'
+ // @has - '//*[@id="variant.MixedHiddenLast"]//h3' 'MixedHiddenLast(S, _)'
// @has - '//*[@id="variant.MixedHiddenLast.field.0"]' '0: S'
// @count - '//*[@id="variant.MixedHiddenLast.field.1"]' 0
MixedHiddenLast(/** dox */ S, #[doc(hidden)] H),
- // @has - '//*[@id="variant.HiddenStruct"]//code' 'HiddenStruct'
+ // @has - '//*[@id="variant.HiddenStruct"]//h3' 'HiddenStruct'
// @count - '//*[@id="variant.HiddenStruct.field.h"]' 0
// @has - '//*[@id="variant.HiddenStruct.field.s"]' 's: S'
HiddenStruct {
diff --git a/src/test/rustdoc/local-reexport-doc.rs b/src/test/rustdoc/local-reexport-doc.rs
new file mode 100644
index 000000000..1c8468008
--- /dev/null
+++ b/src/test/rustdoc/local-reexport-doc.rs
@@ -0,0 +1,16 @@
+// This test ensures that the reexports of local items also get the doc from
+// the reexport.
+
+#![crate_name = "foo"]
+
+// @has 'foo/fn.g.html'
+// @has - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]' \
+// 'outer module inner module'
+
+mod inner_mod {
+ /// inner module
+ pub fn g() {}
+}
+
+/// outer module
+pub use inner_mod::g;
diff --git a/src/test/rustdoc/masked.rs b/src/test/rustdoc/masked.rs
index 80d5b99c0..875c026fd 100644
--- a/src/test/rustdoc/masked.rs
+++ b/src/test/rustdoc/masked.rs
@@ -10,6 +10,7 @@ extern crate masked;
// @!hasraw 'search-index.js' 'masked_method'
// @!hasraw 'foo/struct.String.html' 'MaskedTrait'
+// @!hasraw 'foo/struct.String.html' 'MaskedBlanketTrait'
// @!hasraw 'foo/struct.String.html' 'masked_method'
pub use std::string::String;
diff --git a/src/test/rustdoc/multiple-import-levels.rs b/src/test/rustdoc/multiple-import-levels.rs
new file mode 100644
index 000000000..1daae49cd
--- /dev/null
+++ b/src/test/rustdoc/multiple-import-levels.rs
@@ -0,0 +1,34 @@
+// The goal of this test is to ensure that the attributes of all imports are taken into
+// account.
+
+#![crate_name = "foo"]
+
+mod a {
+ /// 1
+ pub struct Type;
+}
+
+mod b {
+ /// 2
+ pub use crate::a::Type;
+}
+
+mod c {
+ /// 3
+ pub use crate::b::Type;
+ /// 4
+ pub use crate::b::Type as Woof;
+}
+
+// @has 'foo/struct.Type.html'
+// @has - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]' 'foo 2 1'
+/// foo
+pub use b::Type;
+// @has 'foo/struct.Whatever.html'
+// @has - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]' 'whatever 3 2 1'
+/// whatever
+pub use c::Type as Whatever;
+// @has 'foo/struct.Woof.html'
+// @has - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]' 'a dog 4 2 1'
+/// a dog
+pub use c::Woof;
diff --git a/src/test/rustdoc/no-unit-struct-field.rs b/src/test/rustdoc/no-unit-struct-field.rs
new file mode 100644
index 000000000..d301954b6
--- /dev/null
+++ b/src/test/rustdoc/no-unit-struct-field.rs
@@ -0,0 +1,18 @@
+// This test ensures that the tuple struct fields are not generated in the
+// search index.
+
+// @!hasraw search-index.js '"0"'
+// @!hasraw search-index.js '"1"'
+// @hasraw search-index.js '"foo_a"'
+// @hasraw search-index.js '"bar_a"'
+
+pub struct Bar(pub u32, pub u8);
+pub struct Foo {
+ pub foo_a: u8,
+}
+pub enum Enum {
+ Foo(u8),
+ Bar {
+ bar_a: u8,
+ },
+}
diff --git a/src/test/rustdoc/rfc-2632-const-trait-impl.rs b/src/test/rustdoc/rfc-2632-const-trait-impl.rs
index 602ee1b1b..7ed9d6729 100644
--- a/src/test/rustdoc/rfc-2632-const-trait-impl.rs
+++ b/src/test/rustdoc/rfc-2632-const-trait-impl.rs
@@ -61,7 +61,7 @@ impl<T> S<T> {
// @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone'
// @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const'
// @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
- pub const fn foo<B: ~const Clone + ~const Destruct>()
+ pub const fn foo<B, C: ~const Clone + ~const Destruct>()
where
B: ~const Clone + ~const Destruct,
{
diff --git a/src/test/rustdoc/spotlight-from-dependency.odd.html b/src/test/rustdoc/spotlight-from-dependency.odd.html
new file mode 100644
index 000000000..1d02c13eb
--- /dev/null
+++ b/src/test/rustdoc/spotlight-from-dependency.odd.html
@@ -0,0 +1 @@
+<script type="text/json" id="notable-traits-data">{"Odd":"&lt;h3&gt;Notable traits for &lt;code&gt;&lt;a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\"&gt;Odd&lt;/a&gt;&lt;/code&gt;&lt;/h3&gt;&lt;pre class=\"content\"&gt;&lt;code&gt;&lt;span class=\"where fmt-newline\"&gt;impl &lt;a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\"&gt;Iterator&lt;/a&gt; for &lt;a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\"&gt;Odd&lt;/a&gt;&lt;/span&gt;&lt;span class=\"where fmt-newline\"&gt; type &lt;a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\"&gt;Item&lt;/a&gt; = &lt;a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\"&gt;usize&lt;/a&gt;;&lt;/span&gt;"}</script> \ No newline at end of file
diff --git a/src/test/rustdoc/spotlight-from-dependency.rs b/src/test/rustdoc/spotlight-from-dependency.rs
index 524578921..090ad187d 100644
--- a/src/test/rustdoc/spotlight-from-dependency.rs
+++ b/src/test/rustdoc/spotlight-from-dependency.rs
@@ -3,7 +3,8 @@
use std::iter::Iterator;
// @has foo/struct.Odd.html
-// @has - '//*[@id="method.new"]//span[@class="notable-traits"]//code/span' 'impl Iterator for Odd'
+// @has - '//*[@id="method.new"]//a[@class="notable-traits"]/@data-ty' 'Odd'
+// @snapshot odd - '//script[@id="notable-traits-data"]'
pub struct Odd {
current: usize,
}
diff --git a/src/test/rustdoc/static-root-path.rs b/src/test/rustdoc/static-root-path.rs
index 08c055c5b..86928b0fb 100644
--- a/src/test/rustdoc/static-root-path.rs
+++ b/src/test/rustdoc/static-root-path.rs
@@ -1,18 +1,18 @@
// compile-flags:-Z unstable-options --static-root-path /cache/
// @has static_root_path/struct.SomeStruct.html
-// @matchesraw - '"/cache/main\.js"'
-// @!matchesraw - '"\.\./main\.js"'
+// @matchesraw - '"/cache/main-'
+// @!matchesraw - '"\.\./main'
// @matchesraw - 'data-root-path="\.\./"'
// @!matchesraw - '"/cache/search-index\.js"'
pub struct SomeStruct;
// @has src/static_root_path/static-root-path.rs.html
-// @matchesraw - '"/cache/source-script\.js"'
-// @!matchesraw - '"\.\./\.\./source-script\.js"'
+// @matchesraw - '"/cache/source-script-'
+// @!matchesraw - '"\.\./\.\./source-script'
// @matchesraw - '"\.\./\.\./source-files.js"'
// @!matchesraw - '"/cache/source-files\.js"'
// @has settings.html
-// @matchesraw - '/cache/settings\.js'
-// @!matchesraw - '\./settings\.js'
+// @matchesraw - '/cache/settings-'
+// @!matchesraw - '\../settings'
diff --git a/src/test/rustdoc/trait-impl-items-links-and-anchors.rs b/src/test/rustdoc/trait-impl-items-links-and-anchors.rs
index fba594c38..a125fa036 100644
--- a/src/test/rustdoc/trait-impl-items-links-and-anchors.rs
+++ b/src/test/rustdoc/trait-impl-items-links-and-anchors.rs
@@ -13,10 +13,10 @@ impl MyTrait for String {
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="associatedconstant.VALUE-1"]//a[@class="constant"]/@href' #associatedconstant.VALUE
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="associatedconstant.VALUE-1"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-1
const VALUE: u32 = 5;
- // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function
+ // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function"]//a[@class="fn"]/@href' #tymethod.trait_function
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
fn trait_function(&self) {}
- // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-1"]//a[@class="fnname"]/@href' #method.defaulted_override
+ // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-1"]//a[@class="fn"]/@href' #method.defaulted_override
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-1"]//a[@class="anchor"]/@href' #method.defaulted_override-1
fn defaulted_override(&self) {}
}
@@ -28,10 +28,10 @@ impl MyTrait for Vec<u8> {
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="associatedconstant.VALUE-2"]//a[@class="constant"]/@href' #associatedconstant.VALUE
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="associatedconstant.VALUE-2"]//a[@class="anchor"]/@href' #associatedconstant.VALUE-2
const VALUE: u32 = 5;
- // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function"]//a[@class="fnname"]/@href' #tymethod.trait_function
+ // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function"]//a[@class="fn"]/@href' #tymethod.trait_function
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.trait_function-1"]//a[@class="anchor"]/@href' #method.trait_function-1
fn trait_function(&self) {}
- // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-2"]//a[@class="fnname"]/@href' #method.defaulted_override
+ // @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-2"]//a[@class="fn"]/@href' #method.defaulted_override
// @has trait_impl_items_links_and_anchors/trait.MyTrait.html '//*[@id="method.defaulted_override-2"]//a[@class="anchor"]/@href' #method.defaulted_override-2
fn defaulted_override(&self) {}
}
@@ -45,13 +45,13 @@ impl MyTrait for MyStruct {
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="associatedconstant.VALUE"]//a[@class="constant"]/@href' trait.MyTrait.html#associatedconstant.VALUE
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="associatedconstant.VALUE"]//a[@class="anchor"]/@href' #associatedconstant.VALUE
const VALUE: u32 = 20;
- // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.trait_function"]//a[@class="fnname"]/@href' trait.MyTrait.html#tymethod.trait_function
+ // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.trait_function"]//a[@class="fn"]/@href' trait.MyTrait.html#tymethod.trait_function
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.trait_function"]//a[@class="anchor"]/@href' #method.trait_function
fn trait_function(&self) {}
- // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted_override"]//a[@class="fnname"]/@href' trait.MyTrait.html#method.defaulted_override
+ // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted_override"]//a[@class="fn"]/@href' trait.MyTrait.html#method.defaulted_override
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted_override"]//a[@class="anchor"]/@href' #method.defaulted_override
fn defaulted_override(&self) {}
- // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted"]//a[@class="fnname"]/@href' trait.MyTrait.html#method.defaulted
+ // @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted"]//a[@class="fn"]/@href' trait.MyTrait.html#method.defaulted
// @has trait_impl_items_links_and_anchors/struct.MyStruct.html '//*[@id="method.defaulted"]//a[@class="anchor"]/@href' #method.defaulted
}
diff --git a/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html
index 24ab77703..d5d6c556d 100644
--- a/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html
+++ b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html
@@ -1,8 +1,8 @@
<div class="item-decl"><pre class="rust trait"><code>pub trait TraitWhere {
type <a href="#associatedtype.Item" class="associatedtype">Item</a>&lt;'a&gt;<br />&#160;&#160;&#160;&#160;<span class="where">where<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Self: 'a</span>;
- fn <a href="#method.func" class="fnname">func</a>(self)<br />&#160;&#160;&#160;&#160;<span class="where">where<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>,
+ fn <a href="#method.func" class="fn">func</a>(self)<br />&#160;&#160;&#160;&#160;<span class="where">where<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>,
{ ... }
-<span class="item-spacer" /> fn <a href="#method.lines" class="fnname">lines</a>(self) -&gt; <a class="struct" href="{{channel}}/std/io/struct.Lines.html" title="struct std::io::Lines">Lines</a>&lt;Self&gt;<br />&#160;&#160;&#160;&#160;<span class="where">where<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>,
+<span class="item-spacer" /> fn <a href="#method.lines" class="fn">lines</a>(self) -&gt; <a class="struct" href="{{channel}}/std/io/struct.Lines.html" title="struct std::io::Lines">Lines</a>&lt;Self&gt;<br />&#160;&#160;&#160;&#160;<span class="where">where<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Self: <a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a></span>,
{ ... }
}</code></pre></div> \ No newline at end of file
diff --git a/src/test/rustdoc/whitespace-after-where-clause.enum.html b/src/test/rustdoc/whitespace-after-where-clause.enum.html
index c74866f4a..f7663e461 100644
--- a/src/test/rustdoc/whitespace-after-where-clause.enum.html
+++ b/src/test/rustdoc/whitespace-after-where-clause.enum.html
@@ -1,4 +1,4 @@
-<div class="item-decl"><pre class="rust enum"><code>pub enum Cow&lt;'a, B:&#160;?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt;,</span>{
+<div class="item-decl"><pre class="rust enum"><code>pub enum Cow&lt;'a, B&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a </a>B),
Whatever(<a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>),
}</code></pre></div> \ No newline at end of file
diff --git a/src/test/rustdoc/whitespace-after-where-clause.struct.html b/src/test/rustdoc/whitespace-after-where-clause.struct.html
index 1ba1367d2..fa3f224e7 100644
--- a/src/test/rustdoc/whitespace-after-where-clause.struct.html
+++ b/src/test/rustdoc/whitespace-after-where-clause.struct.html
@@ -1,4 +1,4 @@
-<div class="item-decl"><pre class="rust struct"><code>pub struct Struct&lt;'a, B:&#160;?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt;,</span>{
+<div class="item-decl"><pre class="rust struct"><code>pub struct Struct&lt;'a, B&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a </a>B,
pub b: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>,
}</code></pre></div> \ No newline at end of file
diff --git a/src/test/rustdoc/whitespace-after-where-clause.trait.html b/src/test/rustdoc/whitespace-after-where-clause.trait.html
index 16b558237..50cfe3623 100644
--- a/src/test/rustdoc/whitespace-after-where-clause.trait.html
+++ b/src/test/rustdoc/whitespace-after-where-clause.trait.html
@@ -1,6 +1,6 @@
<div class="item-decl"><pre class="rust trait"><code>pub trait ToOwned&lt;T&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</span>{
type <a href="#associatedtype.Owned" class="associatedtype">Owned</a>;
- fn <a href="#tymethod.to_owned" class="fnname">to_owned</a>(&amp;self) -&gt; Self::<a class="associatedtype" href="trait.ToOwned.html#associatedtype.Owned" title="type foo::ToOwned::Owned">Owned</a>;
-<span class="item-spacer" /> fn <a href="#tymethod.whatever" class="fnname">whatever</a>(&amp;self) -&gt; T;
+ fn <a href="#tymethod.to_owned" class="fn">to_owned</a>(&amp;self) -&gt; Self::<a class="associatedtype" href="trait.ToOwned.html#associatedtype.Owned" title="type foo::ToOwned::Owned">Owned</a>;
+<span class="item-spacer" /> fn <a href="#tymethod.whatever" class="fn">whatever</a>(&amp;self) -&gt; T;
}</code></pre></div> \ No newline at end of file
diff --git a/src/test/rustdoc/whitespace-after-where-clause.trait2.html b/src/test/rustdoc/whitespace-after-where-clause.trait2.html
index eeca6e1f5..21eb89b75 100644
--- a/src/test/rustdoc/whitespace-after-where-clause.trait2.html
+++ b/src/test/rustdoc/whitespace-after-where-clause.trait2.html
@@ -1,6 +1,6 @@
<div class="item-decl"><pre class="rust trait"><code>pub trait ToOwned2&lt;T:&#160;<a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; {
type <a href="#associatedtype.Owned" class="associatedtype">Owned</a>;
- fn <a href="#tymethod.to_owned" class="fnname">to_owned</a>(&amp;self) -&gt; Self::<a class="associatedtype" href="trait.ToOwned2.html#associatedtype.Owned" title="type foo::ToOwned2::Owned">Owned</a>;
-<span class="item-spacer" /> fn <a href="#tymethod.whatever" class="fnname">whatever</a>(&amp;self) -&gt; T;
+ fn <a href="#tymethod.to_owned" class="fn">to_owned</a>(&amp;self) -&gt; Self::<a class="associatedtype" href="trait.ToOwned2.html#associatedtype.Owned" title="type foo::ToOwned2::Owned">Owned</a>;
+<span class="item-spacer" /> fn <a href="#tymethod.whatever" class="fn">whatever</a>(&amp;self) -&gt; T;
}</code></pre></div> \ No newline at end of file
diff --git a/src/test/rustdoc/whitespace-after-where-clause.union.html b/src/test/rustdoc/whitespace-after-where-clause.union.html
index 0dfb6407d..7bb177deb 100644
--- a/src/test/rustdoc/whitespace-after-where-clause.union.html
+++ b/src/test/rustdoc/whitespace-after-where-clause.union.html
@@ -1,3 +1,3 @@
-<div class="item-decl"><pre class="rust union"><code>pub union Union&lt;'a, B:&#160;?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt;,</span>{
+<div class="item-decl"><pre class="rust union"><code>pub union Union&lt;'a, B&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
/* private fields */
}</code></pre></div> \ No newline at end of file
diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr b/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr
index 981631494..82679c9e1 100644
--- a/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-cmdline-load.stderr
@@ -1,11 +1,3 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
- --> <crate attribute>:1:1
- |
-LL | plugin(lint_plugin_test)
- | ^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
- |
- = note: `#[warn(deprecated)]` on by default
-
warning: item is named 'lintme'
--> $DIR/lint-plugin-cmdline-load.rs:8:1
|
@@ -14,5 +6,13 @@ LL | fn lintme() { }
|
= note: `#[warn(test_lint)]` on by default
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> <crate attribute>:1:1
+ |
+LL | plugin(lint_plugin_test)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
warning: 2 warnings emitted
diff --git a/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr b/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr
index b9774c044..5e8891bf1 100644
--- a/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-deny-attr.stderr
@@ -1,11 +1,3 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
- --> $DIR/lint-plugin-deny-attr.rs:5:1
- |
-LL | #![plugin(lint_plugin_test)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
- |
- = note: `#[warn(deprecated)]` on by default
-
error: item is named 'lintme'
--> $DIR/lint-plugin-deny-attr.rs:9:1
|
@@ -18,5 +10,13 @@ note: the lint level is defined here
LL | #![deny(test_lint)]
| ^^^^^^^^^
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin-deny-attr.rs:5:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
error: aborting due to previous error; 1 warning emitted
diff --git a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr
index cbabb09f6..d5d6b5352 100644
--- a/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-deny-cmdline.stderr
@@ -1,11 +1,3 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
- --> $DIR/lint-plugin-deny-cmdline.rs:6:1
- |
-LL | #![plugin(lint_plugin_test)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
- |
- = note: `#[warn(deprecated)]` on by default
-
error: item is named 'lintme'
--> $DIR/lint-plugin-deny-cmdline.rs:9:1
|
@@ -14,5 +6,13 @@ LL | fn lintme() { }
|
= note: requested on the command line with `-D test-lint`
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin-deny-cmdline.rs:6:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
error: aborting due to previous error; 1 warning emitted
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs
index 4833f6971..cf31b3ec1 100644
--- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs
@@ -11,7 +11,6 @@ fn lintme() {} //~ ERROR item is named 'lintme'
#[allow(test_lint)]
//~^ ERROR allow(test_lint) incompatible
//~| ERROR allow(test_lint) incompatible
-//~| ERROR allow(test_lint) incompatible
pub fn main() {
lintme();
}
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr
index e11a4f844..ae34b25cc 100644
--- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr
@@ -7,23 +7,6 @@ LL | #![forbid(test_lint)]
LL | #[allow(test_lint)]
| ^^^^^^^^^ overruled by previous forbid
-error[E0453]: allow(test_lint) incompatible with previous forbid
- --> $DIR/lint-plugin-forbid-attrs.rs:11:9
- |
-LL | #![forbid(test_lint)]
- | --------- `forbid` level set here
-...
-LL | #[allow(test_lint)]
- | ^^^^^^^^^ overruled by previous forbid
-
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
- --> $DIR/lint-plugin-forbid-attrs.rs:5:1
- |
-LL | #![plugin(lint_plugin_test)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
- |
- = note: `#[warn(deprecated)]` on by default
-
error: item is named 'lintme'
--> $DIR/lint-plugin-forbid-attrs.rs:9:1
|
@@ -45,6 +28,14 @@ LL | #![forbid(test_lint)]
LL | #[allow(test_lint)]
| ^^^^^^^^^ overruled by previous forbid
-error: aborting due to 4 previous errors; 1 warning emitted
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin-forbid-attrs.rs:5:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to 3 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
index ce034ee38..b9d1aa85a 100644
--- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs
@@ -9,7 +9,7 @@ fn lintme() { } //~ ERROR item is named 'lintme'
#[allow(test_lint)] //~ ERROR allow(test_lint) incompatible
//~| ERROR allow(test_lint) incompatible
- //~| ERROR allow(test_lint)
+
pub fn main() {
lintme();
}
diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr
index 09c19af61..491c4d206 100644
--- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr
@@ -6,22 +6,6 @@ LL | #[allow(test_lint)]
|
= note: `forbid` lint level was set on command line
-error[E0453]: allow(test_lint) incompatible with previous forbid
- --> $DIR/lint-plugin-forbid-cmdline.rs:10:9
- |
-LL | #[allow(test_lint)]
- | ^^^^^^^^^ overruled by previous forbid
- |
- = note: `forbid` lint level was set on command line
-
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
- --> $DIR/lint-plugin-forbid-cmdline.rs:6:1
- |
-LL | #![plugin(lint_plugin_test)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
- |
- = note: `#[warn(deprecated)]` on by default
-
error: item is named 'lintme'
--> $DIR/lint-plugin-forbid-cmdline.rs:8:1
|
@@ -38,6 +22,14 @@ LL | #[allow(test_lint)]
|
= note: `forbid` lint level was set on command line
-error: aborting due to 4 previous errors; 1 warning emitted
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin-forbid-cmdline.rs:6:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+error: aborting due to 3 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui-fulldeps/lint-plugin.stderr b/src/test/ui-fulldeps/lint-plugin.stderr
index 765832071..dd5d3d72e 100644
--- a/src/test/ui-fulldeps/lint-plugin.stderr
+++ b/src/test/ui-fulldeps/lint-plugin.stderr
@@ -1,11 +1,3 @@
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
- --> $DIR/lint-plugin.rs:5:1
- |
-LL | #![plugin(lint_plugin_test)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
- |
- = note: `#[warn(deprecated)]` on by default
-
warning: item is named 'lintme'
--> $DIR/lint-plugin.rs:8:1
|
@@ -14,5 +6,13 @@ LL | fn lintme() { }
|
= note: `#[warn(test_lint)]` on by default
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-plugin.rs:5:1
+ |
+LL | #![plugin(lint_plugin_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
warning: 2 warnings emitted
diff --git a/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
index b4fb9e22d..b060e3a3e 100644
--- a/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
+++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
@@ -6,18 +6,6 @@ warning: lint name `test_lint` is deprecated and does not have an effect anymore
|
= note: requested on the command line with `-A test_lint`
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
- --> $DIR/lint-tool-cmdline-allow.rs:7:1
- |
-LL | #![plugin(lint_tool_test)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
- |
- = note: `#[warn(deprecated)]` on by default
-
-warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint
- |
- = note: requested on the command line with `-A test_lint`
-
warning: item is named 'lintme'
--> $DIR/lint-tool-cmdline-allow.rs:9:1
|
@@ -26,9 +14,17 @@ LL | fn lintme() {}
|
= note: `#[warn(clippy::test_lint)]` on by default
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-tool-cmdline-allow.rs:7:1
+ |
+LL | #![plugin(lint_tool_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
warning: lint name `test_lint` is deprecated and does not have an effect anymore. Use: clippy::test_lint
|
= note: requested on the command line with `-A test_lint`
-warning: 6 warnings emitted
+warning: 5 warnings emitted
diff --git a/src/test/ui-fulldeps/lint-tool-test.rs b/src/test/ui-fulldeps/lint-tool-test.rs
index 0d04eb6fc..f92bcd213 100644
--- a/src/test/ui-fulldeps/lint-tool-test.rs
+++ b/src/test/ui-fulldeps/lint-tool-test.rs
@@ -10,12 +10,10 @@
//~^ WARNING lint name `test_lint` is deprecated and may not have an effect in the future
//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future
//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future
-//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future
#![deny(clippy_group)]
//~^ WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
//~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
//~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
-//~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
fn lintme() { } //~ ERROR item is named 'lintme'
@@ -32,7 +30,6 @@ pub fn main() {
//~^ WARNING lint name `test_group` is deprecated and may not have an effect in the future
//~| WARNING lint name `test_group` is deprecated and may not have an effect in the future
//~| WARNING lint name `test_group` is deprecated and may not have an effect in the future
-//~| WARNING lint name `test_group` is deprecated and may not have an effect in the future
#[deny(this_lint_does_not_exist)] //~ WARNING unknown lint: `this_lint_does_not_exist`
fn hello() {
fn lintmetoo() { }
diff --git a/src/test/ui-fulldeps/lint-tool-test.stderr b/src/test/ui-fulldeps/lint-tool-test.stderr
index af9b8dedc..027cf8f80 100644
--- a/src/test/ui-fulldeps/lint-tool-test.stderr
+++ b/src/test/ui-fulldeps/lint-tool-test.stderr
@@ -7,13 +7,13 @@ LL | #![cfg_attr(foo, warn(test_lint))]
= note: `#[warn(renamed_and_removed_lints)]` on by default
warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
- --> $DIR/lint-tool-test.rs:14:9
+ --> $DIR/lint-tool-test.rs:13:9
|
LL | #![deny(clippy_group)]
| ^^^^^^^^^^^^ help: change it to: `clippy::group`
warning: lint name `test_group` is deprecated and may not have an effect in the future.
- --> $DIR/lint-tool-test.rs:31:9
+ --> $DIR/lint-tool-test.rs:29:9
|
LL | #[allow(test_group)]
| ^^^^^^^^^^ help: change it to: `clippy::test_group`
@@ -25,60 +25,26 @@ LL | #![cfg_attr(foo, warn(test_lint))]
| ^^^^^^^^^ help: change it to: `clippy::test_lint`
warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
- --> $DIR/lint-tool-test.rs:14:9
- |
-LL | #![deny(clippy_group)]
- | ^^^^^^^^^^^^ help: change it to: `clippy::group`
-
-warning: lint name `test_group` is deprecated and may not have an effect in the future.
- --> $DIR/lint-tool-test.rs:31:9
- |
-LL | #[allow(test_group)]
- | ^^^^^^^^^^ help: change it to: `clippy::test_group`
-
-warning: unknown lint: `this_lint_does_not_exist`
- --> $DIR/lint-tool-test.rs:36:8
- |
-LL | #[deny(this_lint_does_not_exist)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(unknown_lints)]` on by default
-
-warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
- --> $DIR/lint-tool-test.rs:6:1
- |
-LL | #![plugin(lint_tool_test)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
- |
- = note: `#[warn(deprecated)]` on by default
-
-warning: lint name `test_lint` is deprecated and may not have an effect in the future.
- --> $DIR/lint-tool-test.rs:9:23
- |
-LL | #![cfg_attr(foo, warn(test_lint))]
- | ^^^^^^^^^ help: change it to: `clippy::test_lint`
-
-warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
- --> $DIR/lint-tool-test.rs:14:9
+ --> $DIR/lint-tool-test.rs:13:9
|
LL | #![deny(clippy_group)]
| ^^^^^^^^^^^^ help: change it to: `clippy::group`
error: item is named 'lintme'
- --> $DIR/lint-tool-test.rs:20:1
+ --> $DIR/lint-tool-test.rs:18:1
|
LL | fn lintme() { }
| ^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/lint-tool-test.rs:14:9
+ --> $DIR/lint-tool-test.rs:13:9
|
LL | #![deny(clippy_group)]
| ^^^^^^^^^^^^
= note: `#[deny(clippy::test_lint)]` implied by `#[deny(clippy::group)]`
error: item is named 'lintmetoo'
- --> $DIR/lint-tool-test.rs:28:5
+ --> $DIR/lint-tool-test.rs:26:5
|
LL | fn lintmetoo() { }
| ^^^^^^^^^^^^^^^^^^
@@ -86,11 +52,27 @@ LL | fn lintmetoo() { }
= note: `#[deny(clippy::test_group)]` implied by `#[deny(clippy::group)]`
warning: lint name `test_group` is deprecated and may not have an effect in the future.
- --> $DIR/lint-tool-test.rs:31:9
+ --> $DIR/lint-tool-test.rs:29:9
|
LL | #[allow(test_group)]
| ^^^^^^^^^^ help: change it to: `clippy::test_group`
+warning: unknown lint: `this_lint_does_not_exist`
+ --> $DIR/lint-tool-test.rs:33:8
+ |
+LL | #[deny(this_lint_does_not_exist)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(unknown_lints)]` on by default
+
+warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
+ --> $DIR/lint-tool-test.rs:6:1
+ |
+LL | #![plugin(lint_tool_test)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
+ |
+ = note: `#[warn(deprecated)]` on by default
+
warning: lint name `test_lint` is deprecated and may not have an effect in the future.
--> $DIR/lint-tool-test.rs:9:23
|
@@ -98,16 +80,16 @@ LL | #![cfg_attr(foo, warn(test_lint))]
| ^^^^^^^^^ help: change it to: `clippy::test_lint`
warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
- --> $DIR/lint-tool-test.rs:14:9
+ --> $DIR/lint-tool-test.rs:13:9
|
LL | #![deny(clippy_group)]
| ^^^^^^^^^^^^ help: change it to: `clippy::group`
warning: lint name `test_group` is deprecated and may not have an effect in the future.
- --> $DIR/lint-tool-test.rs:31:9
+ --> $DIR/lint-tool-test.rs:29:9
|
LL | #[allow(test_group)]
| ^^^^^^^^^^ help: change it to: `clippy::test_group`
-error: aborting due to 2 previous errors; 14 warnings emitted
+error: aborting due to 2 previous errors; 11 warnings emitted
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index 117b79871..a93ba8747 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -25,6 +25,7 @@ extern crate rustc_data_structures;
extern crate rustc_parse;
extern crate rustc_session;
extern crate rustc_span;
+extern crate thin_vec;
use rustc_ast::mut_visit::{self, visit_clobber, MutVisitor};
use rustc_ast::ptr::P;
@@ -35,6 +36,7 @@ use rustc_session::parse::ParseSess;
use rustc_span::source_map::FilePathMapping;
use rustc_span::source_map::{FileName, Spanned, DUMMY_SP};
use rustc_span::symbol::Ident;
+use thin_vec::thin_vec;
fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
let src_as_string = src.to_string();
@@ -51,7 +53,7 @@ fn expr(kind: ExprKind) -> P<Expr> {
fn make_x() -> P<Expr> {
let seg = PathSegment::from_ident(Ident::from_str("x"));
- let path = Path { segments: vec![seg], span: DUMMY_SP, tokens: None };
+ let path = Path { segments: thin_vec![seg], span: DUMMY_SP, tokens: None };
expr(ExprKind::Path(None, path))
}
@@ -73,11 +75,15 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
2 => {
let seg = PathSegment::from_ident(Ident::from_str("x"));
iter_exprs(depth - 1, &mut |e| {
- g(ExprKind::MethodCall(seg.clone(), e, vec![make_x()], DUMMY_SP))
- });
+ g(ExprKind::MethodCall(Box::new(MethodCall {
+ seg: seg.clone(), receiver: e, args: vec![make_x()], span: DUMMY_SP
+ }))
+ )});
iter_exprs(depth - 1, &mut |e| {
- g(ExprKind::MethodCall(seg.clone(), make_x(), vec![e], DUMMY_SP))
- });
+ g(ExprKind::MethodCall(Box::new(MethodCall {
+ seg: seg.clone(), receiver: make_x(), args: vec![e], span: DUMMY_SP
+ }))
+ )});
}
3..=8 => {
let op = Spanned {
@@ -112,15 +118,16 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
11 => {
let decl = P(FnDecl { inputs: vec![], output: FnRetTy::Default(DUMMY_SP) });
iter_exprs(depth - 1, &mut |e| {
- g(ExprKind::Closure(
- ClosureBinder::NotPresent,
- CaptureBy::Value,
- Async::No,
- Movability::Movable,
- decl.clone(),
- e,
- DUMMY_SP,
- ))
+ g(ExprKind::Closure(Box::new(Closure {
+ binder: ClosureBinder::NotPresent,
+ capture_clause: CaptureBy::Value,
+ asyncness: Async::No,
+ movability: Movability::Movable,
+ fn_decl: decl.clone(),
+ body: e,
+ fn_decl_span: DUMMY_SP,
+ fn_arg_span: DUMMY_SP,
+ })))
});
}
12 => {
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index ca77e483d..cb4cd4665 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -40,9 +40,9 @@ struct HelloWarn {}
//~^ ERROR unsupported type attribute for diagnostic derive enum
enum DiagnosticOnEnum {
Foo,
-//~^ ERROR diagnostic slug not specified
+ //~^ ERROR diagnostic slug not specified
Bar,
-//~^ ERROR diagnostic slug not specified
+ //~^ ERROR diagnostic slug not specified
}
#[derive(Diagnostic)]
@@ -211,9 +211,10 @@ struct LabelOnNonSpan {
#[diag(compiletest_example, code = "E0123")]
struct Suggest {
#[suggestion(suggestion, code = "This is the suggested code")]
- #[suggestion_short(suggestion, code = "This is the suggested code")]
- #[suggestion_hidden(suggestion, code = "This is the suggested code")]
- #[suggestion_verbose(suggestion, code = "This is the suggested code")]
+ #[suggestion(suggestion, code = "This is the suggested code", style = "normal")]
+ #[suggestion(suggestion, code = "This is the suggested code", style = "short")]
+ #[suggestion(suggestion, code = "This is the suggested code", style = "hidden")]
+ #[suggestion(suggestion, code = "This is the suggested code", style = "verbose")]
suggestion: (Span, Applicability),
}
@@ -470,7 +471,7 @@ struct NoApplicability {
}
#[derive(Subdiagnostic)]
-#[note(parser_add_paren)]
+#[note(parse_add_paren)]
struct Note;
#[derive(Diagnostic)]
@@ -536,8 +537,7 @@ struct LabelWithTrailingList {
#[derive(LintDiagnostic)]
#[diag(compiletest_example)]
-struct LintsGood {
-}
+struct LintsGood {}
#[derive(LintDiagnostic)]
#[diag(compiletest_example)]
@@ -683,7 +683,7 @@ struct RawIdentDiagnosticArg {
#[diag(compiletest_example)]
struct SubdiagnosticBad {
#[subdiagnostic(bad)]
-//~^ ERROR `#[subdiagnostic(bad)]` is not a valid attribute
+ //~^ ERROR `#[subdiagnostic(bad)]` is not a valid attribute
note: Note,
}
@@ -691,7 +691,7 @@ struct SubdiagnosticBad {
#[diag(compiletest_example)]
struct SubdiagnosticBadStr {
#[subdiagnostic = "bad"]
-//~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute
+ //~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute
note: Note,
}
@@ -699,7 +699,7 @@ struct SubdiagnosticBadStr {
#[diag(compiletest_example)]
struct SubdiagnosticBadTwice {
#[subdiagnostic(bad, bad)]
-//~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
+ //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
note: Note,
}
@@ -707,7 +707,7 @@ struct SubdiagnosticBadTwice {
#[diag(compiletest_example)]
struct SubdiagnosticBadLitStr {
#[subdiagnostic("bad")]
-//~^ ERROR `#[subdiagnostic("...")]` is not a valid attribute
+ //~^ ERROR `#[subdiagnostic("...")]` is not a valid attribute
note: Note,
}
@@ -715,7 +715,7 @@ struct SubdiagnosticBadLitStr {
#[diag(compiletest_example)]
struct SubdiagnosticEagerLint {
#[subdiagnostic(eager)]
-//~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
+ //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
note: Note,
}
@@ -731,11 +731,7 @@ struct SubdiagnosticEagerCorrect {
// after the `span_suggestion` call - which breaks eager translation.
#[derive(Subdiagnostic)]
-#[suggestion_short(
- use_instead,
- applicability = "machine-applicable",
- code = "{correct}"
-)]
+#[suggestion(use_instead, applicability = "machine-applicable", code = "{correct}")]
pub(crate) struct SubdiagnosticWithSuggestion {
#[primary_span]
span: Span,
@@ -796,3 +792,10 @@ struct SuggestionsInvalidLiteral {
//~^ ERROR `code = "..."`/`code(...)` must contain only string literals
sub: Span,
}
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example)]
+struct SuggestionStyleGood {
+ #[suggestion(code = "", style = "hidden")]
+ sub: Span,
+}
diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index 859c272b6..b4c211db4 100644
--- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -261,41 +261,41 @@ LL | #[label(label)]
| ^^^^^^^^^^^^^^^
error: suggestion without `code = "..."`
- --> $DIR/diagnostic-derive.rs:223:5
+ --> $DIR/diagnostic-derive.rs:224:5
|
LL | #[suggestion(suggestion)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: `#[suggestion(nonsense = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:231:18
+ --> $DIR/diagnostic-derive.rs:232:18
|
LL | #[suggestion(nonsense = "bar")]
| ^^^^^^^^^^^^^^^^
|
- = help: only `code` and `applicability` are valid nested attributes
+ = help: only `style`, `code` and `applicability` are valid nested attributes
error: suggestion without `code = "..."`
- --> $DIR/diagnostic-derive.rs:231:5
+ --> $DIR/diagnostic-derive.rs:232:5
|
LL | #[suggestion(nonsense = "bar")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `#[suggestion(msg = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:240:18
+ --> $DIR/diagnostic-derive.rs:241:18
|
LL | #[suggestion(msg = "bar")]
| ^^^^^^^^^^^
|
- = help: only `code` and `applicability` are valid nested attributes
+ = help: only `style`, `code` and `applicability` are valid nested attributes
error: suggestion without `code = "..."`
- --> $DIR/diagnostic-derive.rs:240:5
+ --> $DIR/diagnostic-derive.rs:241:5
|
LL | #[suggestion(msg = "bar")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: wrong field type for suggestion
- --> $DIR/diagnostic-derive.rs:263:5
+ --> $DIR/diagnostic-derive.rs:264:5
|
LL | / #[suggestion(suggestion, code = "This is suggested code")]
LL | |
@@ -305,55 +305,55 @@ LL | | suggestion: Applicability,
= help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:279:24
+ --> $DIR/diagnostic-derive.rs:280:24
|
LL | suggestion: (Span, Span, Applicability),
| ^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:279:18
+ --> $DIR/diagnostic-derive.rs:280:18
|
LL | suggestion: (Span, Span, Applicability),
| ^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:287:33
+ --> $DIR/diagnostic-derive.rs:288:33
|
LL | suggestion: (Applicability, Applicability, Span),
| ^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:287:18
+ --> $DIR/diagnostic-derive.rs:288:18
|
LL | suggestion: (Applicability, Applicability, Span),
| ^^^^^^^^^^^^^
error: `#[label = ...]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:294:5
+ --> $DIR/diagnostic-derive.rs:295:5
|
LL | #[label = "bar"]
| ^^^^^^^^^^^^^^^^
error: specified multiple times
- --> $DIR/diagnostic-derive.rs:445:44
+ --> $DIR/diagnostic-derive.rs:446:44
|
LL | #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/diagnostic-derive.rs:447:24
+ --> $DIR/diagnostic-derive.rs:448:24
|
LL | suggestion: (Span, Applicability),
| ^^^^^^^^^^^^^
error: invalid applicability
- --> $DIR/diagnostic-derive.rs:453:44
+ --> $DIR/diagnostic-derive.rs:454:44
|
LL | #[suggestion(suggestion, code = "...", applicability = "batman")]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: `#[label(foo)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:516:20
+ --> $DIR/diagnostic-derive.rs:517:20
|
LL | #[label(label, foo)]
| ^^^
@@ -361,13 +361,13 @@ LL | #[label(label, foo)]
= help: a diagnostic slug must be the first argument to the attribute
error: `#[label(foo = ...)]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:524:20
+ --> $DIR/diagnostic-derive.rs:525:20
|
LL | #[label(label, foo = "...")]
| ^^^^^^^^^^^
error: `#[label(foo(...))]` is not a valid attribute
- --> $DIR/diagnostic-derive.rs:532:20
+ --> $DIR/diagnostic-derive.rs:533:20
|
LL | #[label(label, foo("..."))]
| ^^^^^^^^^^
@@ -574,19 +574,19 @@ LL | #[subdiagnostic(eager)]
= help: eager subdiagnostics are not supported on lints
error: expected at least one string literal for `code(...)`
- --> $DIR/diagnostic-derive.rs:779:18
+ --> $DIR/diagnostic-derive.rs:775:18
|
LL | #[suggestion(code())]
| ^^^^^^
error: `code(...)` must contain only string literals
- --> $DIR/diagnostic-derive.rs:787:23
+ --> $DIR/diagnostic-derive.rs:783:23
|
LL | #[suggestion(code(foo))]
| ^^^
error: `code = "..."`/`code(...)` must contain only string literals
- --> $DIR/diagnostic-derive.rs:795:18
+ --> $DIR/diagnostic-derive.rs:791:18
|
LL | #[suggestion(code = 3)]
| ^^^^^^^^
@@ -652,7 +652,7 @@ LL | #[diag(nonsense, code = "E0123")]
| ^^^^^^^^ not found in `rustc_errors::fluent`
error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
- --> $DIR/diagnostic-derive.rs:338:10
+ --> $DIR/diagnostic-derive.rs:339:10
|
LL | #[derive(Diagnostic)]
| ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
diff --git a/src/test/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs b/src/test/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs
new file mode 100644
index 000000000..a0a8114e0
--- /dev/null
+++ b/src/test/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs
@@ -0,0 +1,24 @@
+// rustc-env:CARGO_CRATE_NAME=rustc_dummy
+
+#![feature(rustc_private)]
+#![crate_type = "lib"]
+
+extern crate rustc_span;
+use rustc_span::symbol::Ident;
+use rustc_span::Span;
+
+extern crate rustc_macros;
+use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
+
+extern crate rustc_middle;
+use rustc_middle::ty::Ty;
+
+extern crate rustc_errors;
+use rustc_errors::{Applicability, MultiSpan};
+
+extern crate rustc_session;
+
+#[derive(Diagnostic)]
+#[diag(compiletest_example, code = "E0123")]
+//~^ ERROR diagnostic slug and crate name do not match
+struct Hello {}
diff --git a/src/test/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr b/src/test/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr
new file mode 100644
index 000000000..dcf4af5df
--- /dev/null
+++ b/src/test/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr
@@ -0,0 +1,11 @@
+error: diagnostic slug and crate name do not match
+ --> $DIR/enforce_slug_naming.rs:22:8
+ |
+LL | #[diag(compiletest_example, code = "E0123")]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: slug is `compiletest_example` but the crate name is `rustc_dummy`
+ = help: expected a slug starting with `dummy_...`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
index efec85eb5..61ac456a6 100644
--- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
+++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
@@ -11,16 +11,16 @@
#![crate_type = "lib"]
extern crate rustc_errors;
+extern crate rustc_macros;
extern crate rustc_session;
extern crate rustc_span;
-extern crate rustc_macros;
use rustc_errors::Applicability;
-use rustc_span::Span;
use rustc_macros::Subdiagnostic;
+use rustc_span::Span;
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
struct A {
#[primary_span]
span: Span,
@@ -29,22 +29,22 @@ struct A {
#[derive(Subdiagnostic)]
enum B {
- #[label(parser_add_paren)]
+ #[label(parse_add_paren)]
A {
#[primary_span]
span: Span,
var: String,
},
- #[label(parser_add_paren)]
+ #[label(parse_add_paren)]
B {
#[primary_span]
span: Span,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
//~^ ERROR label without `#[primary_span]` field
struct C {
var: String,
@@ -138,7 +138,7 @@ struct M {
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren, code = "...")]
+#[label(parse_add_paren, code = "...")]
//~^ ERROR `#[label(code = ...)]` is not a valid attribute
struct N {
#[primary_span]
@@ -147,7 +147,7 @@ struct N {
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren, applicability = "machine-applicable")]
+#[label(parse_add_paren, applicability = "machine-applicable")]
//~^ ERROR `#[label(applicability = ...)]` is not a valid attribute
struct O {
#[primary_span]
@@ -160,12 +160,12 @@ struct O {
//~^ ERROR cannot find attribute `foo` in this scope
//~^^ ERROR unsupported type attribute for subdiagnostic enum
enum P {
- #[label(parser_add_paren)]
+ #[label(parse_add_paren)]
A {
#[primary_span]
span: Span,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
@@ -177,7 +177,7 @@ enum Q {
#[primary_span]
span: Span,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
@@ -189,7 +189,7 @@ enum R {
#[primary_span]
span: Span,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
@@ -201,7 +201,7 @@ enum S {
#[primary_span]
span: Span,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
@@ -213,7 +213,7 @@ enum T {
#[primary_span]
span: Span,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
@@ -225,12 +225,12 @@ enum U {
#[primary_span]
span: Span,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
enum V {
- #[label(parser_add_paren)]
+ #[label(parse_add_paren)]
A {
#[primary_span]
span: Span,
@@ -240,11 +240,11 @@ enum V {
#[primary_span]
span: Span,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
//~^ ERROR label without `#[primary_span]` field
struct W {
#[primary_span]
@@ -253,7 +253,7 @@ struct W {
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
struct X {
#[primary_span]
span: Span,
@@ -263,7 +263,7 @@ struct X {
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
struct Y {
#[primary_span]
span: Span,
@@ -274,7 +274,7 @@ struct Y {
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
struct Z {
#[primary_span]
span: Span,
@@ -285,7 +285,7 @@ struct Z {
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
struct AA {
#[primary_span]
span: Span,
@@ -296,39 +296,39 @@ struct AA {
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
struct AB {
#[primary_span]
span: Span,
#[skip_arg]
- z: Z
+ z: Z,
}
#[derive(Subdiagnostic)]
union AC {
-//~^ ERROR unexpected unsupported untagged union
+ //~^ ERROR unexpected unsupported untagged union
span: u32,
- b: u64
+ b: u64,
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
+#[label(parse_add_paren)]
struct AD {
#[primary_span]
span: Span,
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren, parser_add_paren)]
-//~^ ERROR `#[label(parser_add_paren)]` is not a valid attribute
+#[label(parse_add_paren, parse_add_paren)]
+//~^ ERROR `#[label(parse_add_paren)]` is not a valid attribute
struct AE {
#[primary_span]
span: Span,
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
struct AF {
#[primary_span]
//~^ NOTE previously specified here
@@ -346,7 +346,7 @@ struct AG {
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code = "...")]
+#[suggestion(parse_add_paren, code = "...")]
struct AH {
#[primary_span]
span: Span,
@@ -357,7 +357,7 @@ struct AH {
#[derive(Subdiagnostic)]
enum AI {
- #[suggestion(parser_add_paren, code = "...")]
+ #[suggestion(parse_add_paren, code = "...")]
A {
#[primary_span]
span: Span,
@@ -365,18 +365,18 @@ enum AI {
applicability: Applicability,
var: String,
},
- #[suggestion(parser_add_paren, code = "...")]
+ #[suggestion(parse_add_paren, code = "...")]
B {
#[primary_span]
span: Span,
#[applicability]
applicability: Applicability,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code = "...", code = "...")]
+#[suggestion(parse_add_paren, code = "...", code = "...")]
//~^ ERROR specified multiple times
//~^^ NOTE previously specified here
struct AJ {
@@ -387,7 +387,7 @@ struct AJ {
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code = "...")]
+#[suggestion(parse_add_paren, code = "...")]
struct AK {
#[primary_span]
span: Span,
@@ -400,7 +400,7 @@ struct AK {
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code = "...")]
+#[suggestion(parse_add_paren, code = "...")]
struct AL {
#[primary_span]
span: Span,
@@ -410,14 +410,14 @@ struct AL {
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code = "...")]
+#[suggestion(parse_add_paren, code = "...")]
struct AM {
#[primary_span]
span: Span,
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren)]
+#[suggestion(parse_add_paren)]
//~^ ERROR suggestion without `code = "..."`
struct AN {
#[primary_span]
@@ -427,7 +427,7 @@ struct AN {
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code ="...", applicability = "foo")]
+#[suggestion(parse_add_paren, code = "...", applicability = "foo")]
//~^ ERROR invalid applicability
struct AO {
#[primary_span]
@@ -435,24 +435,24 @@ struct AO {
}
#[derive(Subdiagnostic)]
-#[help(parser_add_paren)]
+#[help(parse_add_paren)]
struct AP {
- var: String
+ var: String,
}
#[derive(Subdiagnostic)]
-#[note(parser_add_paren)]
+#[note(parse_add_paren)]
struct AQ;
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code = "...")]
+#[suggestion(parse_add_paren, code = "...")]
//~^ ERROR suggestion without `#[primary_span]` field
struct AR {
var: String,
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code ="...", applicability = "machine-applicable")]
+#[suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
struct AS {
#[primary_span]
span: Span,
@@ -462,16 +462,16 @@ struct AS {
#[label]
//~^ ERROR unsupported type attribute for subdiagnostic enum
enum AT {
- #[label(parser_add_paren)]
+ #[label(parse_add_paren)]
A {
#[primary_span]
span: Span,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
+#[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
struct AU {
#[primary_span]
span: Span,
@@ -479,7 +479,7 @@ struct AU {
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
+#[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
//~^ ERROR `var` doesn't refer to a field on this type
struct AV {
#[primary_span]
@@ -488,37 +488,37 @@ struct AV {
#[derive(Subdiagnostic)]
enum AW {
- #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
+ #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
A {
#[primary_span]
span: Span,
var: String,
- }
+ },
}
#[derive(Subdiagnostic)]
enum AX {
- #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
-//~^ ERROR `var` doesn't refer to a field on this type
+ #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
+ //~^ ERROR `var` doesn't refer to a field on this type
A {
#[primary_span]
span: Span,
- }
+ },
}
#[derive(Subdiagnostic)]
-#[warning(parser_add_paren)]
+#[warning(parse_add_paren)]
struct AY {}
#[derive(Subdiagnostic)]
-#[warning(parser_add_paren)]
+#[warning(parse_add_paren)]
struct AZ {
#[primary_span]
span: Span,
}
#[derive(Subdiagnostic)]
-#[suggestion(parser_add_paren, code = "...")]
+#[suggestion(parse_add_paren, code = "...")]
//~^ ERROR suggestion without `#[primary_span]` field
struct BA {
#[suggestion_part]
@@ -533,7 +533,7 @@ struct BA {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren, code = "...", applicability = "machine-applicable")]
+#[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
//~| ERROR `#[multipart_suggestion(code = ...)]` is not a valid attribute
struct BBa {
@@ -541,7 +541,7 @@ struct BBa {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
struct BBb {
#[suggestion_part]
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
@@ -549,7 +549,7 @@ struct BBb {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
struct BBc {
#[suggestion_part()]
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
@@ -557,7 +557,7 @@ struct BBc {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren)]
+#[multipart_suggestion(parse_add_paren)]
//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
struct BC {
#[primary_span]
@@ -566,7 +566,7 @@ struct BC {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren)]
+#[multipart_suggestion(parse_add_paren)]
struct BD {
#[suggestion_part]
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
@@ -586,7 +586,7 @@ struct BD {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
struct BE {
#[suggestion_part(code = "...", code = ",,,")]
//~^ ERROR specified multiple times
@@ -595,7 +595,7 @@ struct BE {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
struct BF {
#[suggestion_part(code = "(")]
first: Span,
@@ -604,7 +604,7 @@ struct BF {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren)]
+#[multipart_suggestion(parse_add_paren)]
struct BG {
#[applicability]
appl: Applicability,
@@ -615,7 +615,7 @@ struct BG {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
struct BH {
#[applicability]
//~^ ERROR `#[applicability]` has no effect
@@ -627,14 +627,14 @@ struct BH {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren, applicability = "machine-applicable")]
+#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
struct BI {
#[suggestion_part(code = "")]
spans: Vec<Span>,
}
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
struct BJ {
#[primary_span]
span: Span,
@@ -643,7 +643,7 @@ struct BJ {
/// with a doc comment on the type..
#[derive(Subdiagnostic)]
-#[label(parser_add_paren)]
+#[label(parse_add_paren)]
struct BK {
/// ..and the field
#[primary_span]
@@ -654,16 +654,16 @@ struct BK {
#[derive(Subdiagnostic)]
enum BL {
/// ..and the variant..
- #[label(parser_add_paren)]
+ #[label(parse_add_paren)]
Foo {
/// ..and the field
#[primary_span]
span: Span,
- }
+ },
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren)]
+#[multipart_suggestion(parse_add_paren)]
struct BM {
#[suggestion_part(code("foo"))]
//~^ ERROR expected exactly one string literal for `code = ...`
@@ -672,7 +672,7 @@ struct BM {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren)]
+#[multipart_suggestion(parse_add_paren)]
struct BN {
#[suggestion_part(code("foo", "bar"))]
//~^ ERROR expected exactly one string literal for `code = ...`
@@ -681,7 +681,7 @@ struct BN {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren)]
+#[multipart_suggestion(parse_add_paren)]
struct BO {
#[suggestion_part(code(3))]
//~^ ERROR expected exactly one string literal for `code = ...`
@@ -690,7 +690,7 @@ struct BO {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren)]
+#[multipart_suggestion(parse_add_paren)]
struct BP {
#[suggestion_part(code())]
//~^ ERROR expected exactly one string literal for `code = ...`
@@ -699,10 +699,102 @@ struct BP {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser_add_paren)]
+#[multipart_suggestion(parse_add_paren)]
struct BQ {
#[suggestion_part(code = 3)]
//~^ ERROR `code = "..."`/`code(...)` must contain only string literals
span: Span,
r#type: String,
}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "")]
+struct SuggestionStyleDefault {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "short")]
+struct SuggestionStyleShort {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "hidden")]
+struct SuggestionStyleHidden {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "verbose")]
+struct SuggestionStyleVerbose {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "tool-only")]
+struct SuggestionStyleToolOnly {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")]
+//~^ ERROR specified multiple times
+//~| NOTE previously specified here
+struct SuggestionStyleTwice {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion_hidden(parse_add_paren, code = "")]
+//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute
+struct SuggestionStyleOldSyntax {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion_hidden(parse_add_paren, code = "", style = "normal")]
+//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute
+struct SuggestionStyleOldAndNewSyntax {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = "foo")]
+//~^ ERROR invalid suggestion style
+struct SuggestionStyleInvalid1 {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style = 42)]
+//~^ ERROR `#[suggestion(style = ...)]` is not a valid attribute
+struct SuggestionStyleInvalid2 {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style)]
+//~^ ERROR `#[suggestion(style)]` is not a valid attribute
+struct SuggestionStyleInvalid3 {
+ #[primary_span]
+ sub: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(parse_add_paren, code = "", style("foo"))]
+//~^ ERROR `#[suggestion(style(...))]` is not a valid attribute
+struct SuggestionStyleInvalid4 {
+ #[primary_span]
+ sub: Span,
+}
diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
index a85a8711e..b594fa6cd 100644
--- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
+++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr
@@ -1,7 +1,7 @@
error: label without `#[primary_span]` field
--> $DIR/subdiagnostic-derive.rs:47:1
|
-LL | / #[label(parser_add_paren)]
+LL | / #[label(parse_add_paren)]
LL | |
LL | | struct C {
LL | | var: String,
@@ -81,16 +81,16 @@ LL | #[label()]
| ^^^^^^^^^^
error: `#[label(code = ...)]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:141:27
+ --> $DIR/subdiagnostic-derive.rs:141:26
|
-LL | #[label(parser_add_paren, code = "...")]
- | ^^^^^^^^^^^^
+LL | #[label(parse_add_paren, code = "...")]
+ | ^^^^^^^^^^^^
error: `#[label(applicability = ...)]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:150:27
+ --> $DIR/subdiagnostic-derive.rs:150:26
|
-LL | #[label(parser_add_paren, applicability = "machine-applicable")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[label(parse_add_paren, applicability = "machine-applicable")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsupported type attribute for subdiagnostic enum
--> $DIR/subdiagnostic-derive.rs:159:1
@@ -143,7 +143,7 @@ LL | #[primary_span]
error: label without `#[primary_span]` field
--> $DIR/subdiagnostic-derive.rs:247:1
|
-LL | / #[label(parser_add_paren)]
+LL | / #[label(parse_add_paren)]
LL | |
LL | | struct W {
LL | | #[primary_span]
@@ -186,15 +186,15 @@ error: unexpected unsupported untagged union
LL | / union AC {
LL | |
LL | | span: u32,
-LL | | b: u64
+LL | | b: u64,
LL | | }
| |_^
-error: `#[label(parser_add_paren)]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:323:27
+error: `#[label(parse_add_paren)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:323:26
|
-LL | #[label(parser_add_paren, parser_add_paren)]
- | ^^^^^^^^^^^^^^^^
+LL | #[label(parse_add_paren, parse_add_paren)]
+ | ^^^^^^^^^^^^^^^
|
= help: a diagnostic slug must be the first argument to the attribute
@@ -217,16 +217,16 @@ LL | struct AG {
| ^^
error: specified multiple times
- --> $DIR/subdiagnostic-derive.rs:379:46
+ --> $DIR/subdiagnostic-derive.rs:379:45
|
-LL | #[suggestion(parser_add_paren, code = "...", code = "...")]
- | ^^^^^^^^^^^^
+LL | #[suggestion(parse_add_paren, code = "...", code = "...")]
+ | ^^^^^^^^^^^^
|
note: previously specified here
- --> $DIR/subdiagnostic-derive.rs:379:32
+ --> $DIR/subdiagnostic-derive.rs:379:31
|
-LL | #[suggestion(parser_add_paren, code = "...", code = "...")]
- | ^^^^^^^^^^^^
+LL | #[suggestion(parse_add_paren, code = "...", code = "...")]
+ | ^^^^^^^^^^^^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:397:5
@@ -249,19 +249,19 @@ LL | #[applicability]
error: suggestion without `code = "..."`
--> $DIR/subdiagnostic-derive.rs:420:1
|
-LL | #[suggestion(parser_add_paren)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[suggestion(parse_add_paren)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: invalid applicability
--> $DIR/subdiagnostic-derive.rs:430:45
|
-LL | #[suggestion(parser_add_paren, code ="...", applicability = "foo")]
+LL | #[suggestion(parse_add_paren, code = "...", applicability = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^
error: suggestion without `#[primary_span]` field
--> $DIR/subdiagnostic-derive.rs:448:1
|
-LL | / #[suggestion(parser_add_paren, code = "...")]
+LL | / #[suggestion(parse_add_paren, code = "...")]
LL | |
LL | | struct AR {
LL | | var: String,
@@ -277,13 +277,13 @@ LL | #[label]
error: `var` doesn't refer to a field on this type
--> $DIR/subdiagnostic-derive.rs:482:38
|
-LL | #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
+LL | #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
| ^^^^^^^
error: `var` doesn't refer to a field on this type
--> $DIR/subdiagnostic-derive.rs:501:42
|
-LL | #[suggestion(parser_add_paren, code ="{var}", applicability = "machine-applicable")]
+LL | #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")]
| ^^^^^^^
error: `#[suggestion_part]` is not a valid attribute
@@ -305,7 +305,7 @@ LL | #[suggestion_part(code = "...")]
error: suggestion without `#[primary_span]` field
--> $DIR/subdiagnostic-derive.rs:521:1
|
-LL | / #[suggestion(parser_add_paren, code = "...")]
+LL | / #[suggestion(parse_add_paren, code = "...")]
LL | |
LL | | struct BA {
LL | | #[suggestion_part]
@@ -315,17 +315,17 @@ LL | | }
| |_^
error: `#[multipart_suggestion(code = ...)]` is not a valid attribute
- --> $DIR/subdiagnostic-derive.rs:536:42
+ --> $DIR/subdiagnostic-derive.rs:536:41
|
-LL | #[multipart_suggestion(parser_add_paren, code = "...", applicability = "machine-applicable")]
- | ^^^^^^^^^^^^
+LL | #[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
+ | ^^^^^^^^^^^^
|
- = help: only `applicability` is a valid nested attributes
+ = help: only `style` and `applicability` are valid nested attributes
error: multipart suggestion without any `#[suggestion_part(...)]` fields
--> $DIR/subdiagnostic-derive.rs:536:1
|
-LL | / #[multipart_suggestion(parser_add_paren, code = "...", applicability = "machine-applicable")]
+LL | / #[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")]
LL | |
LL | |
LL | | struct BBa {
@@ -356,7 +356,7 @@ LL | #[primary_span]
error: multipart suggestion without any `#[suggestion_part(...)]` fields
--> $DIR/subdiagnostic-derive.rs:560:1
|
-LL | / #[multipart_suggestion(parser_add_paren)]
+LL | / #[multipart_suggestion(parse_add_paren)]
LL | |
LL | | struct BC {
LL | | #[primary_span]
@@ -445,6 +445,62 @@ error: `code = "..."`/`code(...)` must contain only string literals
LL | #[suggestion_part(code = 3)]
| ^^^^^^^^
+error: specified multiple times
+ --> $DIR/subdiagnostic-derive.rs:746:60
+ |
+LL | #[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")]
+ | ^^^^^^^^^^^^^^^^
+ |
+note: previously specified here
+ --> $DIR/subdiagnostic-derive.rs:746:42
+ |
+LL | #[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")]
+ | ^^^^^^^^^^^^^^^^
+
+error: `#[suggestion_hidden(...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:755:1
+ |
+LL | #[suggestion_hidden(parse_add_paren, code = "")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: Use `#[suggestion(..., style = "hidden")]` instead
+
+error: `#[suggestion_hidden(...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:763:1
+ |
+LL | #[suggestion_hidden(parse_add_paren, code = "", style = "normal")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: Use `#[suggestion(..., style = "hidden")]` instead
+
+error: invalid suggestion style
+ --> $DIR/subdiagnostic-derive.rs:771:50
+ |
+LL | #[suggestion(parse_add_paren, code = "", style = "foo")]
+ | ^^^^^
+ |
+ = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only`
+
+error: `#[suggestion(style = ...)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:779:42
+ |
+LL | #[suggestion(parse_add_paren, code = "", style = 42)]
+ | ^^^^^^^^^^
+
+error: `#[suggestion(style)]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:787:42
+ |
+LL | #[suggestion(parse_add_paren, code = "", style)]
+ | ^^^^^
+ |
+ = help: a diagnostic slug must be the first argument to the attribute
+
+error: `#[suggestion(style(...))]` is not a valid attribute
+ --> $DIR/subdiagnostic-derive.rs:795:42
+ |
+LL | #[suggestion(parse_add_paren, code = "", style("foo"))]
+ | ^^^^^^^^^^^^
+
error: cannot find attribute `foo` in this scope
--> $DIR/subdiagnostic-derive.rs:63:3
|
@@ -505,6 +561,6 @@ error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
LL | #[label(slug)]
| ^^^^ not found in `rustc_errors::fluent`
-error: aborting due to 72 previous errors
+error: aborting due to 79 previous errors
For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui-fulldeps/uninit_mask.rs b/src/test/ui-fulldeps/uninit_mask.rs
deleted file mode 100644
index 84ce29101..000000000
--- a/src/test/ui-fulldeps/uninit_mask.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-// run-pass
-// ignore-cross-compile
-// ignore-stage1
-
-#![feature(rustc_private)]
-
-extern crate rustc_middle;
-extern crate rustc_target;
-
-use rustc_middle::mir::interpret::InitMask;
-use rustc_target::abi::Size;
-
-fn main() {
- let mut mask = InitMask::new(Size::from_bytes(500), false);
- assert!(!mask.get(Size::from_bytes(499)));
- mask.set(Size::from_bytes(499), true);
- assert!(mask.get(Size::from_bytes(499)));
- mask.set_range_inbounds(Size::from_bytes(100), Size::from_bytes(256), true);
- for i in 0..100 {
- assert!(!mask.get(Size::from_bytes(i)));
- }
- for i in 100..256 {
- assert!(mask.get(Size::from_bytes(i)));
- }
- for i in 256..499 {
- assert!(!mask.get(Size::from_bytes(i)));
- }
-}
diff --git a/src/test/ui/abi/homogenous-floats-target-feature-mixup.rs b/src/test/ui/abi/homogenous-floats-target-feature-mixup.rs
new file mode 100644
index 000000000..d7f5e1921
--- /dev/null
+++ b/src/test/ui/abi/homogenous-floats-target-feature-mixup.rs
@@ -0,0 +1,192 @@
+// This test check that even if we mixup target feature of function with homogenous floats,
+// the abi is sound and still produce the right answer.
+//
+// This is basically the same test as src/test/ui/simd/target-feature-mixup.rs but for floats and
+// without #[repr(simd)]
+
+// run-pass
+// ignore-emscripten
+// ignore-sgx no processes
+
+#![feature(avx512_target_feature)]
+
+#![allow(overflowing_literals)]
+#![allow(unused_variables)]
+
+use std::process::{Command, ExitStatus};
+use std::env;
+
+fn main() {
+ if let Some(level) = env::args().nth(1) {
+ return test::main(&level)
+ }
+
+ match std::env::var("TARGET") {
+ Ok(s) => {
+ // Skip this tests on i586-unknown-linux-gnu where sse2 is disabled
+ if s.contains("i586") {
+ return
+ }
+ }
+ Err(_) => return,
+ }
+
+ let me = env::current_exe().unwrap();
+ for level in ["sse", "avx", "avx512"].iter() {
+ let status = Command::new(&me).arg(level).status().unwrap();
+ if status.success() {
+ println!("success with {}", level);
+ continue
+ }
+
+ // We don't actually know if our computer has the requisite target features
+ // for the test below. Testing for that will get added to libstd later so
+ // for now just assume sigill means this is a machine that can't run this test.
+ if is_sigill(status) {
+ println!("sigill with {}, assuming spurious", level);
+ continue
+ }
+ panic!("invalid status at {}: {}", level, status);
+ }
+}
+
+#[cfg(unix)]
+fn is_sigill(status: ExitStatus) -> bool {
+ use std::os::unix::prelude::*;
+ status.signal() == Some(4)
+}
+
+#[cfg(windows)]
+fn is_sigill(status: ExitStatus) -> bool {
+ status.code() == Some(0xc000001d)
+}
+
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+#[allow(nonstandard_style)]
+mod test {
+ #[derive(PartialEq, Debug, Clone, Copy)]
+ struct f32x2(f32, f32);
+
+ #[derive(PartialEq, Debug, Clone, Copy)]
+ struct f32x4(f32, f32, f32, f32);
+
+ #[derive(PartialEq, Debug, Clone, Copy)]
+ struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
+
+ pub fn main(level: &str) {
+ unsafe {
+ main_normal(level);
+ main_sse(level);
+ if level == "sse" {
+ return
+ }
+ main_avx(level);
+ if level == "avx" {
+ return
+ }
+ main_avx512(level);
+ }
+ }
+
+ macro_rules! mains {
+ ($(
+ $(#[$attr:meta])*
+ unsafe fn $main:ident(level: &str) {
+ ...
+ }
+ )*) => ($(
+ $(#[$attr])*
+ unsafe fn $main(level: &str) {
+ let m128 = f32x2(1., 2.);
+ let m256 = f32x4(3., 4., 5., 6.);
+ let m512 = f32x8(7., 8., 9., 10., 11., 12., 13., 14.);
+ assert_eq!(id_sse_128(m128), m128);
+ assert_eq!(id_sse_256(m256), m256);
+ assert_eq!(id_sse_512(m512), m512);
+
+ if level == "sse" {
+ return
+ }
+ assert_eq!(id_avx_128(m128), m128);
+ assert_eq!(id_avx_256(m256), m256);
+ assert_eq!(id_avx_512(m512), m512);
+
+ if level == "avx" {
+ return
+ }
+ assert_eq!(id_avx512_128(m128), m128);
+ assert_eq!(id_avx512_256(m256), m256);
+ assert_eq!(id_avx512_512(m512), m512);
+ }
+ )*)
+ }
+
+ mains! {
+ unsafe fn main_normal(level: &str) { ... }
+ #[target_feature(enable = "sse2")]
+ unsafe fn main_sse(level: &str) { ... }
+ #[target_feature(enable = "avx")]
+ unsafe fn main_avx(level: &str) { ... }
+ #[target_feature(enable = "avx512bw")]
+ unsafe fn main_avx512(level: &str) { ... }
+ }
+
+ #[target_feature(enable = "sse2")]
+ unsafe fn id_sse_128(a: f32x2) -> f32x2 {
+ assert_eq!(a, f32x2(1., 2.));
+ a.clone()
+ }
+
+ #[target_feature(enable = "sse2")]
+ unsafe fn id_sse_256(a: f32x4) -> f32x4 {
+ assert_eq!(a, f32x4(3., 4., 5., 6.));
+ a.clone()
+ }
+
+ #[target_feature(enable = "sse2")]
+ unsafe fn id_sse_512(a: f32x8) -> f32x8 {
+ assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx")]
+ unsafe fn id_avx_128(a: f32x2) -> f32x2 {
+ assert_eq!(a, f32x2(1., 2.));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx")]
+ unsafe fn id_avx_256(a: f32x4) -> f32x4 {
+ assert_eq!(a, f32x4(3., 4., 5., 6.));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx")]
+ unsafe fn id_avx_512(a: f32x8) -> f32x8 {
+ assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx512bw")]
+ unsafe fn id_avx512_128(a: f32x2) -> f32x2 {
+ assert_eq!(a, f32x2(1., 2.));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx512bw")]
+ unsafe fn id_avx512_256(a: f32x4) -> f32x4 {
+ assert_eq!(a, f32x4(3., 4., 5., 6.));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx512bw")]
+ unsafe fn id_avx512_512(a: f32x8) -> f32x8 {
+ assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.));
+ a.clone()
+ }
+}
+
+#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+mod test {
+ pub fn main(level: &str) {}
+}
diff --git a/src/test/ui/abi/issues/issue-22565-rust-call.rs b/src/test/ui/abi/issues/issue-22565-rust-call.rs
index a08e0bfb5..a572666c8 100644
--- a/src/test/ui/abi/issues/issue-22565-rust-call.rs
+++ b/src/test/ui/abi/issues/issue-22565-rust-call.rs
@@ -1,32 +1,31 @@
#![feature(unboxed_closures)]
extern "rust-call" fn b(_i: i32) {}
-//~^ ERROR functions with the "rust-call" ABI must take a single non-self argument that is a tuple
+//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
trait Tr {
extern "rust-call" fn a();
+ //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
extern "rust-call" fn b() {}
- //~^ ERROR functions with the "rust-call" ABI must take a single non-self argument
+ //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
}
struct Foo;
impl Foo {
extern "rust-call" fn bar() {}
- //~^ ERROR functions with the "rust-call" ABI must take a single non-self argument
+ //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
}
impl Tr for Foo {
extern "rust-call" fn a() {}
- //~^ ERROR functions with the "rust-call" ABI must take a single non-self argument
+ //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
}
-fn main () {
+fn main() {
b(10);
-
Foo::bar();
-
<Foo as Tr>::a();
<Foo as Tr>::b();
}
diff --git a/src/test/ui/abi/issues/issue-22565-rust-call.stderr b/src/test/ui/abi/issues/issue-22565-rust-call.stderr
index 3eee10bc5..9d205b444 100644
--- a/src/test/ui/abi/issues/issue-22565-rust-call.stderr
+++ b/src/test/ui/abi/issues/issue-22565-rust-call.stderr
@@ -1,26 +1,33 @@
-error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple
+error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
--> $DIR/issue-22565-rust-call.rs:3:1
|
LL | extern "rust-call" fn b(_i: i32) {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `i32`
-error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple
- --> $DIR/issue-22565-rust-call.rs:9:5
- |
-LL | extern "rust-call" fn b() {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple
- --> $DIR/issue-22565-rust-call.rs:16:5
+error: functions with the "rust-call" ABI must take a single non-self tuple argument
+ --> $DIR/issue-22565-rust-call.rs:17:5
|
LL | extern "rust-call" fn bar() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple
- --> $DIR/issue-22565-rust-call.rs:21:5
+error: functions with the "rust-call" ABI must take a single non-self tuple argument
+ --> $DIR/issue-22565-rust-call.rs:22:5
|
LL | extern "rust-call" fn a() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 4 previous errors
+error: functions with the "rust-call" ABI must take a single non-self tuple argument
+ --> $DIR/issue-22565-rust-call.rs:7:5
+ |
+LL | extern "rust-call" fn a();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: functions with the "rust-call" ABI must take a single non-self tuple argument
+ --> $DIR/issue-22565-rust-call.rs:10:5
+ |
+LL | extern "rust-call" fn b() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/abi/rustcall-generic.rs b/src/test/ui/abi/rustcall-generic.rs
index 411c98e10..6eaccc436 100644
--- a/src/test/ui/abi/rustcall-generic.rs
+++ b/src/test/ui/abi/rustcall-generic.rs
@@ -2,9 +2,9 @@
// check-pass
//[opt] compile-flags: -Zmir-opt-level=3
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, tuple_trait)]
-extern "rust-call" fn foo<T>(_: T) {}
+extern "rust-call" fn foo<T: std::marker::Tuple>(_: T) {}
fn main() {
foo(());
diff --git a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-1.rs b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-1.rs
index 41c9a265c..cd06423e3 100644
--- a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-1.rs
+++ b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-1.rs
@@ -8,8 +8,8 @@ use core::alloc::Layout;
#[alloc_error_handler]
fn oom(
- info: &Layout, //~ ERROR argument should be `Layout`
-) -> () //~ ERROR return type should be `!`
+ info: &Layout, //~^ ERROR mismatched types
+) -> () //~^^ ERROR mismatched types
{
loop {}
}
diff --git a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr
index 34e09da45..dd3665f22 100644
--- a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr
+++ b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr
@@ -1,14 +1,50 @@
-error: return type should be `!`
- --> $DIR/alloc-error-handler-bad-signature-1.rs:12:6
+error[E0308]: mismatched types
+ --> $DIR/alloc-error-handler-bad-signature-1.rs:10:1
|
-LL | ) -> ()
- | ^^
-
-error: argument should be `Layout`
- --> $DIR/alloc-error-handler-bad-signature-1.rs:11:11
+LL | #[alloc_error_handler]
+ | ---------------------- in this procedural macro expansion
+LL | fn oom(
+ | __^
+ | | _|
+ | ||
+LL | || info: &Layout,
+LL | || ) -> ()
+ | ||_______- arguments to this function are incorrect
+LL | | {
+LL | | loop {}
+LL | | }
+ | |__^ expected `&Layout`, found struct `Layout`
+ |
+note: function defined here
+ --> $DIR/alloc-error-handler-bad-signature-1.rs:10:4
|
+LL | fn oom(
+ | ^^^
LL | info: &Layout,
- | ^^^^^^^
+ | -------------
+ = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0308]: mismatched types
+ --> $DIR/alloc-error-handler-bad-signature-1.rs:10:1
+ |
+LL | #[alloc_error_handler]
+ | ---------------------- in this procedural macro expansion
+LL | fn oom(
+ | __^
+ | | _|
+ | ||
+LL | || info: &Layout,
+LL | || ) -> ()
+ | ||_______^ expected `!`, found `()`
+LL | | {
+LL | | loop {}
+LL | | }
+ | |__- expected `!` because of return type
+ |
+ = note: expected type `!`
+ found unit type `()`
+ = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-2.rs b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-2.rs
index 49ea3105f..4f76257fc 100644
--- a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-2.rs
+++ b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-2.rs
@@ -8,8 +8,8 @@ struct Layout;
#[alloc_error_handler]
fn oom(
- info: Layout, //~ ERROR argument should be `Layout`
-) { //~ ERROR return type should be `!`
+ info: Layout, //~^ ERROR mismatched types
+) { //~^^ ERROR mismatched types
loop {}
}
diff --git a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr
index 85544b0c3..adb652fe6 100644
--- a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr
+++ b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr
@@ -1,14 +1,59 @@
-error: return type should be `!`
- --> $DIR/alloc-error-handler-bad-signature-2.rs:12:3
+error[E0308]: mismatched types
+ --> $DIR/alloc-error-handler-bad-signature-2.rs:10:1
|
-LL | ) {
- | ^
-
-error: argument should be `Layout`
- --> $DIR/alloc-error-handler-bad-signature-2.rs:11:11
+LL | #[alloc_error_handler]
+ | ---------------------- in this procedural macro expansion
+LL | fn oom(
+ | __^
+ | | _|
+ | ||
+LL | || info: Layout,
+LL | || ) {
+ | ||_- arguments to this function are incorrect
+LL | | loop {}
+LL | | }
+ | |__^ expected struct `Layout`, found struct `core::alloc::Layout`
+ |
+ = note: struct `core::alloc::Layout` and struct `Layout` have similar names, but are actually distinct types
+note: struct `core::alloc::Layout` is defined in crate `core`
+ --> $SRC_DIR/core/src/alloc/layout.rs:LL:COL
+ |
+LL | pub struct Layout {
+ | ^^^^^^^^^^^^^^^^^
+note: struct `Layout` is defined in the current crate
+ --> $DIR/alloc-error-handler-bad-signature-2.rs:7:1
+ |
+LL | struct Layout;
+ | ^^^^^^^^^^^^^
+note: function defined here
+ --> $DIR/alloc-error-handler-bad-signature-2.rs:10:4
|
+LL | fn oom(
+ | ^^^
LL | info: Layout,
- | ^^^^^^
+ | ------------
+ = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0308]: mismatched types
+ --> $DIR/alloc-error-handler-bad-signature-2.rs:10:1
+ |
+LL | #[alloc_error_handler]
+ | ---------------------- in this procedural macro expansion
+LL | fn oom(
+ | __^
+ | | _|
+ | ||
+LL | || info: Layout,
+LL | || ) {
+ | ||_^ expected `!`, found `()`
+LL | | loop {}
+LL | | }
+ | |__- expected `!` because of return type
+ |
+ = note: expected type `!`
+ found unit type `()`
+ = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.rs b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.rs
index 321fd954d..8430fabe8 100644
--- a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.rs
+++ b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.rs
@@ -7,7 +7,7 @@
struct Layout;
#[alloc_error_handler]
-fn oom() -> ! { //~ ERROR function should have one argument
+fn oom() -> ! { //~ ERROR this function takes 0 arguments but 1 argument was supplied
loop {}
}
diff --git a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr
index 8575e7508..77ea8ef05 100644
--- a/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr
+++ b/src/test/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr
@@ -1,8 +1,25 @@
-error: function should have one argument
+error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/alloc-error-handler-bad-signature-3.rs:10:1
|
+LL | #[alloc_error_handler]
+ | ---------------------- in this procedural macro expansion
+LL | fn oom() -> ! {
+ | _-^^^^^^^^^^^^
+LL | | loop {}
+LL | | }
+ | |_- argument of type `core::alloc::Layout` unexpected
+ |
+note: function defined here
+ --> $DIR/alloc-error-handler-bad-signature-3.rs:10:4
+ |
LL | fn oom() -> ! {
- | ^^^^^^^^^^^^^
+ | ^^^
+ = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: remove the extra argument
+ |
+LL | fn oom() -> !() {
+ | ++
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/argument-suggestions/formal-and-expected-differ.rs b/src/test/ui/argument-suggestions/formal-and-expected-differ.rs
new file mode 100644
index 000000000..5e3b55ca5
--- /dev/null
+++ b/src/test/ui/argument-suggestions/formal-and-expected-differ.rs
@@ -0,0 +1,25 @@
+pub trait Foo {
+ type T;
+}
+
+impl Foo for i32 {
+ type T = f32;
+}
+
+pub struct U<T1, T2>(T1, S<T2>)
+where
+ T1: Foo<T = T2>;
+
+pub struct S<T>(T);
+
+fn main() {
+ // The error message here isn't great -- it has to do with the fact that the
+ // `expected_inputs_for_expected_output` deduced inputs differs from the inputs
+ // that we infer from the constraints of the signature.
+ //
+ // I am not really sure what the best way of presenting this error message is,
+ // since right now it just suggests changing `3u32` <=> `3f32` back and forth.
+ let _: U<_, u32> = U(1, S(3u32));
+ //~^ ERROR mismatched types
+ //~| ERROR mismatched types
+}
diff --git a/src/test/ui/argument-suggestions/formal-and-expected-differ.stderr b/src/test/ui/argument-suggestions/formal-and-expected-differ.stderr
new file mode 100644
index 000000000..905875b52
--- /dev/null
+++ b/src/test/ui/argument-suggestions/formal-and-expected-differ.stderr
@@ -0,0 +1,30 @@
+error[E0308]: mismatched types
+ --> $DIR/formal-and-expected-differ.rs:22:29
+ |
+LL | let _: U<_, u32> = U(1, S(3u32));
+ | - ^^^^^^^ expected `f32`, found `u32`
+ | |
+ | arguments to this struct are incorrect
+ |
+ = note: expected struct `S<f32>`
+ found struct `S<u32>`
+note: tuple struct defined here
+ --> $DIR/formal-and-expected-differ.rs:9:12
+ |
+LL | pub struct U<T1, T2>(T1, S<T2>)
+ | ^
+
+error[E0308]: mismatched types
+ --> $DIR/formal-and-expected-differ.rs:22:24
+ |
+LL | let _: U<_, u32> = U(1, S(3u32));
+ | --------- ^^^^^^^^^^^^^ expected `u32`, found `f32`
+ | |
+ | expected due to this
+ |
+ = note: expected struct `U<_, u32>`
+ found struct `U<i32, f32>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/array-slice-vec/array-break-length.stderr b/src/test/ui/array-slice-vec/array-break-length.stderr
index 93f1c238b..2df7b6d7f 100644
--- a/src/test/ui/array-slice-vec/array-break-length.stderr
+++ b/src/test/ui/array-slice-vec/array-break-length.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/array-break-length.rs:3:17
|
LL | |_: [_; break]| {}
- | ^^^^^ cannot `break` outside of a loop
+ | ^^^^^ cannot `break` outside of a loop or labeled block
error[E0268]: `continue` outside of a loop
--> $DIR/array-break-length.rs:7:17
diff --git a/src/test/ui/array-slice-vec/slice_is_sorted_by_borrow.rs b/src/test/ui/array-slice-vec/slice_is_sorted_by_borrow.rs
new file mode 100644
index 000000000..073280d0f
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice_is_sorted_by_borrow.rs
@@ -0,0 +1,20 @@
+// check-pass
+// regression test for https://github.com/rust-lang/rust/issues/53485#issuecomment-885393452
+
+#![feature(is_sorted)]
+
+struct A {
+ name: String,
+}
+
+fn main() {
+ let a = &[
+ A {
+ name: "1".to_string(),
+ },
+ A {
+ name: "2".to_string(),
+ },
+ ];
+ assert!(a.is_sorted_by_key(|a| a.name.as_str()));
+}
diff --git a/src/test/ui/array-slice-vec/vec-macro-with-comma-only.stderr b/src/test/ui/array-slice-vec/vec-macro-with-comma-only.stderr
index abbee347c..ec4a001f4 100644
--- a/src/test/ui/array-slice-vec/vec-macro-with-comma-only.stderr
+++ b/src/test/ui/array-slice-vec/vec-macro-with-comma-only.stderr
@@ -3,6 +3,8 @@ error: no rules expected the token `,`
|
LL | vec![,];
| ^ no rules expected this token in macro call
+ |
+ = note: while trying to match end of macro
error: aborting due to previous error
diff --git a/src/test/ui/asm/aarch64/llvm-58384.rs b/src/test/ui/asm/aarch64/llvm-58384.rs
new file mode 100644
index 000000000..308f78908
--- /dev/null
+++ b/src/test/ui/asm/aarch64/llvm-58384.rs
@@ -0,0 +1,16 @@
+// only-aarch64
+// run-pass
+// needs-asm-support
+
+// Test that we properly work around this LLVM issue:
+// https://github.com/llvm/llvm-project/issues/58384
+
+use std::arch::asm;
+
+fn main() {
+ let a: i32;
+ unsafe {
+ asm!("", inout("x0") 435 => a);
+ }
+ assert_eq!(a, 435);
+}
diff --git a/src/test/ui/asm/issue-92378.rs b/src/test/ui/asm/issue-92378.rs
index 6e3c26e98..809b0d155 100644
--- a/src/test/ui/asm/issue-92378.rs
+++ b/src/test/ui/asm/issue-92378.rs
@@ -3,7 +3,7 @@
// needs-asm-support
// build-pass
-#![feature(no_core, lang_items, rustc_attrs, isa_attribute)]
+#![feature(no_core, lang_items, rustc_attrs)]
#![no_core]
#![crate_type = "rlib"]
diff --git a/src/test/ui/asm/naked-invalid-attr.stderr b/src/test/ui/asm/naked-invalid-attr.stderr
index 58344be93..e8ddccc85 100644
--- a/src/test/ui/asm/naked-invalid-attr.stderr
+++ b/src/test/ui/asm/naked-invalid-attr.stderr
@@ -36,7 +36,7 @@ error: attribute should be applied to a function definition
--> $DIR/naked-invalid-attr.rs:5:1
|
LL | #![naked]
- | ^^^^^^^^^
+ | ^^^^^^^^^ cannot be applied to crates
error: aborting due to 5 previous errors
diff --git a/src/test/ui/assoc-inherent.rs b/src/test/ui/assoc-inherent.rs
deleted file mode 100644
index c579c962f..000000000
--- a/src/test/ui/assoc-inherent.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Test that inherent associated types work with
-// inherent_associated_types feature gate.
-
-#![feature(inherent_associated_types)]
-#![allow(incomplete_features)]
-
-struct Foo;
-
-impl Foo {
- type Bar = isize;
-}
-
-impl Foo {
- type Baz; //~ ERROR associated type in `impl` without body
-}
-
-fn main() {
- let x : Foo::Bar; //~ERROR ambiguous associated type
- x = 0isize;
-}
diff --git a/src/test/ui/assoc-inherent.stderr b/src/test/ui/assoc-inherent.stderr
deleted file mode 100644
index b703453fa..000000000
--- a/src/test/ui/assoc-inherent.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error: associated type in `impl` without body
- --> $DIR/assoc-inherent.rs:14:5
- |
-LL | type Baz;
- | ^^^^^^^^-
- | |
- | help: provide a definition for the type: `= <type>;`
-
-error[E0223]: ambiguous associated type
- --> $DIR/assoc-inherent.rs:18:13
- |
-LL | let x : Foo::Bar;
- | ^^^^^^^^ help: use fully-qualified syntax: `<Foo as Trait>::Bar`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0223`.
diff --git a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr
index c4cd9c2a4..a1483911b 100644
--- a/src/test/ui/associated-consts/defaults-cyclic-fail.stderr
+++ b/src/test/ui/associated-consts/defaults-cyclic-fail.stderr
@@ -1,14 +1,14 @@
error[E0391]: cycle detected when const-evaluating + checking `Tr::A`
- --> $DIR/defaults-cyclic-fail.rs:5:5
+ --> $DIR/defaults-cyclic-fail.rs:5:19
|
LL | const A: u8 = Self::B;
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^
|
note: ...which requires const-evaluating + checking `Tr::B`...
- --> $DIR/defaults-cyclic-fail.rs:8:5
+ --> $DIR/defaults-cyclic-fail.rs:8:19
|
LL | const B: u8 = Self::A;
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^
= note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle
note: cycle used when const-evaluating + checking `main::promoted[1]`
--> $DIR/defaults-cyclic-fail.rs:16:16
diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.rs b/src/test/ui/associated-consts/defaults-not-assumed-fail.rs
index 6762d7583..495dfb338 100644
--- a/src/test/ui/associated-consts/defaults-not-assumed-fail.rs
+++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.rs
@@ -31,8 +31,7 @@ impl Tr for u32 {
fn main() {
assert_eq!(<() as Tr>::A, 255);
assert_eq!(<() as Tr>::B, 0); // causes the error above
- //~^ ERROR evaluation of constant value failed
- //~| ERROR erroneous constant used
+ //~^ constant
assert_eq!(<u8 as Tr>::A, 254);
assert_eq!(<u8 as Tr>::B, 255);
diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr
index aa130f438..fb7159e40 100644
--- a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr
+++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr
@@ -4,20 +4,36 @@ error[E0080]: evaluation of `<() as Tr>::B` failed
LL | const B: u8 = Self::A + 1;
| ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/defaults-not-assumed-fail.rs:33:16
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
- | ^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/defaults-not-assumed-fail.rs:33:5
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to 3 previous errors
+note: erroneous constant used
+ --> $DIR/defaults-not-assumed-fail.rs:33:5
+ |
+LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/defaults-not-assumed-fail.rs:33:5
+ |
+LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
index c8c57bccb..be5781761 100644
--- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
+++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.stderr
@@ -10,10 +10,10 @@ note: ...which requires const-evaluating + checking `IMPL_REF_BAR`...
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `IMPL_REF_BAR`...
- --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
+ --> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:27
|
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 11:19>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
index 76ed8d4a6..8347b260b 100644
--- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
+++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.stderr
@@ -10,10 +10,10 @@ note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`...
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`...
- --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:30
|
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `FooDefault::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
|
diff --git a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
index 6a98f08f3..3955a3120 100644
--- a/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
+++ b/src/test/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.stderr
@@ -10,10 +10,10 @@ note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`...
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`...
- --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
+ --> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:28
|
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 11:28>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
|
diff --git a/src/test/ui/associated-consts/issue-47814.rs b/src/test/ui/associated-consts/issue-47814.rs
new file mode 100644
index 000000000..a28b1c001
--- /dev/null
+++ b/src/test/ui/associated-consts/issue-47814.rs
@@ -0,0 +1,14 @@
+struct ArpIPv4<'a> {
+ s: &'a u8
+}
+
+impl<'a> ArpIPv4<'a> {
+ const LENGTH: usize = 20;
+
+ pub fn to_buffer() -> [u8; Self::LENGTH] {
+ //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants
+ unimplemented!()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-consts/issue-47814.stderr b/src/test/ui/associated-consts/issue-47814.stderr
new file mode 100644
index 000000000..2e4ddb811
--- /dev/null
+++ b/src/test/ui/associated-consts/issue-47814.stderr
@@ -0,0 +1,14 @@
+error: generic `Self` types are currently not permitted in anonymous constants
+ --> $DIR/issue-47814.rs:8:32
+ |
+LL | pub fn to_buffer() -> [u8; Self::LENGTH] {
+ | ^^^^
+ |
+note: not a concrete type
+ --> $DIR/issue-47814.rs:5:10
+ |
+LL | impl<'a> ArpIPv4<'a> {
+ | ^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-58022.rs b/src/test/ui/associated-consts/issue-58022.rs
index 2a8a1eaa6..2a8a1eaa6 100644
--- a/src/test/ui/issues/issue-58022.rs
+++ b/src/test/ui/associated-consts/issue-58022.rs
diff --git a/src/test/ui/issues/issue-58022.stderr b/src/test/ui/associated-consts/issue-58022.stderr
index 56d85c066..56d85c066 100644
--- a/src/test/ui/issues/issue-58022.stderr
+++ b/src/test/ui/associated-consts/issue-58022.stderr
diff --git a/src/test/ui/associated-consts/issue-93835.rs b/src/test/ui/associated-consts/issue-93835.rs
index 5c7b06598..b2a437fcb 100644
--- a/src/test/ui/associated-consts/issue-93835.rs
+++ b/src/test/ui/associated-consts/issue-93835.rs
@@ -1,9 +1,11 @@
+#![feature(type_ascription)]
+
fn e() {
- p:a<p:p<e=6>>
- //~^ ERROR comparison operators
+ type_ascribe!(p, a<p:p<e=6>>);
+ //~^ ERROR cannot find type `a` in this scope
//~| ERROR cannot find value
//~| ERROR associated const equality
- //~| ERROR associated const equality
+ //~| ERROR cannot find trait `p` in this scope
//~| ERROR associated type bounds
}
diff --git a/src/test/ui/associated-consts/issue-93835.stderr b/src/test/ui/associated-consts/issue-93835.stderr
index 0406a16a3..be0573a13 100644
--- a/src/test/ui/associated-consts/issue-93835.stderr
+++ b/src/test/ui/associated-consts/issue-93835.stderr
@@ -1,65 +1,40 @@
-error: comparison operators cannot be chained
- --> $DIR/issue-93835.rs:2:8
- |
-LL | fn e() {
- | - while parsing this struct
-LL | p:a<p:p<e=6>>
- | ^ ^
- |
- = help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
- = help: or use `(...)` if you meant to specify fn arguments
-
error[E0425]: cannot find value `p` in this scope
- --> $DIR/issue-93835.rs:2:5
- |
-LL | p:a<p:p<e=6>>
- | ^ not found in this scope
- |
-help: you might have meant to write a `struct` literal
- |
-LL ~ fn e() { SomeStruct {
-LL | p:a<p:p<e=6>>
- ...
-LL |
-LL ~ }}
+ --> $DIR/issue-93835.rs:4:19
|
-help: maybe you meant to write a path separator here
- |
-LL | p::a<p:p<e=6>>
- | ~~
-help: maybe you meant to write an assignment here
- |
-LL | let p:a<p:p<e=6>>
- | ~~~~~
+LL | type_ascribe!(p, a<p:p<e=6>>);
+ | ^ not found in this scope
-error[E0658]: associated const equality is incomplete
- --> $DIR/issue-93835.rs:2:13
+error[E0412]: cannot find type `a` in this scope
+ --> $DIR/issue-93835.rs:4:22
|
-LL | p:a<p:p<e=6>>
- | ^^^
+LL | type_ascribe!(p, a<p:p<e=6>>);
+ | ^ not found in this scope
+
+error[E0405]: cannot find trait `p` in this scope
+ --> $DIR/issue-93835.rs:4:26
|
- = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
- = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+LL | type_ascribe!(p, a<p:p<e=6>>);
+ | ^ not found in this scope
error[E0658]: associated const equality is incomplete
- --> $DIR/issue-93835.rs:2:13
+ --> $DIR/issue-93835.rs:4:28
|
-LL | p:a<p:p<e=6>>
- | ^^^
+LL | type_ascribe!(p, a<p:p<e=6>>);
+ | ^^^
|
= note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
= help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
error[E0658]: associated type bounds are unstable
- --> $DIR/issue-93835.rs:2:9
+ --> $DIR/issue-93835.rs:4:24
|
-LL | p:a<p:p<e=6>>
- | ^^^^^^^^
+LL | type_ascribe!(p, a<p:p<e=6>>);
+ | ^^^^^^^^
|
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
error: aborting due to 5 previous errors
-Some errors have detailed explanations: E0425, E0658.
-For more information about an error, try `rustc --explain E0425`.
+Some errors have detailed explanations: E0405, E0412, E0425, E0658.
+For more information about an error, try `rustc --explain E0405`.
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs
new file mode 100644
index 000000000..71f65b92e
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.rs
@@ -0,0 +1,10 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Foo;
+
+impl Foo {
+ type Baz; //~ ERROR associated type in `impl` without body
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr
new file mode 100644
index 000000000..387a5658d
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-no-body.stderr
@@ -0,0 +1,10 @@
+error: associated type in `impl` without body
+ --> $DIR/assoc-inherent-no-body.rs:7:5
+ |
+LL | type Baz;
+ | ^^^^^^^^-
+ | |
+ | help: provide a definition for the type: `= <type>;`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-private.rs b/src/test/ui/associated-inherent-types/assoc-inherent-private.rs
new file mode 100644
index 000000000..531581954
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-private.rs
@@ -0,0 +1,23 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+mod m {
+ pub struct T;
+ impl T {
+ type P = ();
+ }
+}
+type U = m::T::P; //~ ERROR associated type `P` is private
+
+mod n {
+ pub mod n {
+ pub struct T;
+ impl T {
+ pub(super) type P = bool;
+ }
+ }
+ type U = n::T::P;
+}
+type V = n::n::T::P; //~ ERROR associated type `P` is private
+
+fn main() {}
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-private.stderr b/src/test/ui/associated-inherent-types/assoc-inherent-private.stderr
new file mode 100644
index 000000000..d67b45dae
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-private.stderr
@@ -0,0 +1,21 @@
+error[E0624]: associated type `P` is private
+ --> $DIR/assoc-inherent-private.rs:10:10
+ |
+LL | type P = ();
+ | ------ associated type defined here
+...
+LL | type U = m::T::P;
+ | ^^^^^^^ private associated type
+
+error[E0624]: associated type `P` is private
+ --> $DIR/assoc-inherent-private.rs:21:10
+ |
+LL | pub(super) type P = bool;
+ | ----------------- associated type defined here
+...
+LL | type V = n::n::T::P;
+ | ^^^^^^^^^^ private associated type
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0624`.
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-unstable.rs b/src/test/ui/associated-inherent-types/assoc-inherent-unstable.rs
new file mode 100644
index 000000000..34b4e47bf
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-unstable.rs
@@ -0,0 +1,6 @@
+// aux-crate:aux=assoc-inherent-unstable.rs
+// edition: 2021
+
+type Data = aux::Owner::Data; //~ ERROR use of unstable library feature 'data'
+
+fn main() {}
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-unstable.stderr b/src/test/ui/associated-inherent-types/assoc-inherent-unstable.stderr
new file mode 100644
index 000000000..c0be8bfd7
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-unstable.stderr
@@ -0,0 +1,11 @@
+error[E0658]: use of unstable library feature 'data'
+ --> $DIR/assoc-inherent-unstable.rs:4:13
+ |
+LL | type Data = aux::Owner::Data;
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(data)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/associated-inherent-types/assoc-inherent-use.rs b/src/test/ui/associated-inherent-types/assoc-inherent-use.rs
new file mode 100644
index 000000000..7ae425e2a
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/assoc-inherent-use.rs
@@ -0,0 +1,14 @@
+// check-pass
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Foo;
+
+impl Foo {
+ type Bar = isize;
+}
+
+fn main() {
+ let x: Foo::Bar;
+ x = 0isize;
+}
diff --git a/src/test/ui/associated-inherent-types/auxiliary/assoc-inherent-unstable.rs b/src/test/ui/associated-inherent-types/auxiliary/assoc-inherent-unstable.rs
new file mode 100644
index 000000000..6b71ffc97
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/auxiliary/assoc-inherent-unstable.rs
@@ -0,0 +1,11 @@
+#![feature(staged_api)]
+#![feature(inherent_associated_types)]
+#![stable(feature = "main", since = "1.0.0")]
+
+#[stable(feature = "main", since = "1.0.0")]
+pub struct Owner;
+
+impl Owner {
+ #[unstable(feature = "data", issue = "none")]
+ pub type Data = ();
+}
diff --git a/src/test/ui/associated-inherent-types/issue-104260.rs b/src/test/ui/associated-inherent-types/issue-104260.rs
new file mode 100644
index 000000000..a73cd1775
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/issue-104260.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Foo;
+
+impl Foo {
+ type Bar<T> = u8;
+}
+
+fn main() {
+ let a: Foo::Bar<()>;
+}
diff --git a/src/test/ui/associated-inherent-types/normalize-projection-0.rs b/src/test/ui/associated-inherent-types/normalize-projection-0.rs
new file mode 100644
index 000000000..50763ecdd
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/normalize-projection-0.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<T>(T);
+
+impl<T: O> S<T> {
+ type P = <T as O>::P;
+}
+
+trait O {
+ type P;
+}
+
+impl O for i32 {
+ type P = String;
+}
+
+fn main() {
+ let _: S<i32>::P = String::new();
+}
diff --git a/src/test/ui/associated-inherent-types/normalize-projection-1.rs b/src/test/ui/associated-inherent-types/normalize-projection-1.rs
new file mode 100644
index 000000000..2f7b2551a
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/normalize-projection-1.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S;
+
+impl S {
+ type P<T: O> = <T as O>::P;
+}
+
+trait O {
+ type P;
+}
+
+impl O for i32 {
+ type P = String;
+}
+
+fn main() {
+ let _: S::P<i32> = String::new();
+}
diff --git a/src/test/ui/associated-inherent-types/struct-generics.rs b/src/test/ui/associated-inherent-types/struct-generics.rs
new file mode 100644
index 000000000..8952b3791
--- /dev/null
+++ b/src/test/ui/associated-inherent-types/struct-generics.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<T>(T);
+
+impl<T> S<T> {
+ type P = T;
+}
+
+fn main() {
+ type A = S<()>::P;
+ let _: A = ();
+}
diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs
index 6e464f695..f67410986 100644
--- a/src/test/ui/associated-type-bounds/duplicate.rs
+++ b/src/test/ui/associated-type-bounds/duplicate.rs
@@ -132,12 +132,15 @@ where
}
fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
+ //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
iter::empty()
}
fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
+ //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
iter::empty()
}
fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
+ //~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
iter::empty()
}
fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr
index e4f4836f7..c3061327f 100644
--- a/src/test/ui/associated-type-bounds/duplicate.stderr
+++ b/src/test/ui/associated-type-bounds/duplicate.stderr
@@ -191,7 +191,31 @@ LL | T: Iterator<Item: 'static, Item: 'static>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:143:40
+ --> $DIR/duplicate.rs:134:42
+ |
+LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
+ | ---------- ^^^^^^^^^^ re-bound here
+ | |
+ | `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
+ --> $DIR/duplicate.rs:138:42
+ |
+LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
+ | ---------- ^^^^^^^^^^ re-bound here
+ | |
+ | `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
+ --> $DIR/duplicate.rs:142:45
+ |
+LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
+ | ------------- ^^^^^^^^^^^^^ re-bound here
+ | |
+ | `Item` bound here first
+
+error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
+ --> $DIR/duplicate.rs:146:40
|
LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
| ---------- ^^^^^^^^^^ re-bound here
@@ -199,7 +223,7 @@ LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:145:40
+ --> $DIR/duplicate.rs:148:40
|
LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
| ---------- ^^^^^^^^^^ re-bound here
@@ -207,7 +231,7 @@ LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:147:43
+ --> $DIR/duplicate.rs:150:43
|
LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -215,7 +239,7 @@ LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:150:35
+ --> $DIR/duplicate.rs:153:35
|
LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
| ---------- ^^^^^^^^^^ re-bound here
@@ -223,7 +247,7 @@ LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:152:35
+ --> $DIR/duplicate.rs:155:35
|
LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
| ---------- ^^^^^^^^^^ re-bound here
@@ -231,7 +255,7 @@ LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:154:38
+ --> $DIR/duplicate.rs:157:38
|
LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -239,7 +263,7 @@ LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:158:29
+ --> $DIR/duplicate.rs:161:29
|
LL | T: Iterator<Item: Copy, Item: Send>,
| ---------- ^^^^^^^^^^ re-bound here
@@ -247,7 +271,7 @@ LL | T: Iterator<Item: Copy, Item: Send>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:163:29
+ --> $DIR/duplicate.rs:166:29
|
LL | T: Iterator<Item: Copy, Item: Copy>,
| ---------- ^^^^^^^^^^ re-bound here
@@ -255,7 +279,7 @@ LL | T: Iterator<Item: Copy, Item: Copy>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:168:32
+ --> $DIR/duplicate.rs:171:32
|
LL | T: Iterator<Item: 'static, Item: 'static>,
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -263,7 +287,7 @@ LL | T: Iterator<Item: 'static, Item: 'static>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:172:36
+ --> $DIR/duplicate.rs:175:36
|
LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
| ---------- ^^^^^^^^^^ re-bound here
@@ -271,7 +295,7 @@ LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:174:36
+ --> $DIR/duplicate.rs:177:36
|
LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
| ---------- ^^^^^^^^^^ re-bound here
@@ -279,7 +303,7 @@ LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:176:39
+ --> $DIR/duplicate.rs:179:39
|
LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -287,7 +311,7 @@ LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:178:40
+ --> $DIR/duplicate.rs:181:40
|
LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
| ---------- ^^^^^^^^^^ re-bound here
@@ -295,7 +319,7 @@ LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:180:40
+ --> $DIR/duplicate.rs:183:40
|
LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
| ---------- ^^^^^^^^^^ re-bound here
@@ -303,7 +327,7 @@ LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:182:43
+ --> $DIR/duplicate.rs:185:43
|
LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -311,7 +335,7 @@ LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:185:36
+ --> $DIR/duplicate.rs:188:36
|
LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
| ---------- ^^^^^^^^^^ re-bound here
@@ -319,7 +343,7 @@ LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:187:36
+ --> $DIR/duplicate.rs:190:36
|
LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
| ---------- ^^^^^^^^^^ re-bound here
@@ -327,7 +351,7 @@ LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:189:39
+ --> $DIR/duplicate.rs:192:39
|
LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -335,7 +359,7 @@ LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:191:34
+ --> $DIR/duplicate.rs:194:34
|
LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
@@ -343,7 +367,7 @@ LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:193:34
+ --> $DIR/duplicate.rs:196:34
|
LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
@@ -351,7 +375,7 @@ LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:195:37
+ --> $DIR/duplicate.rs:198:37
|
LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -359,7 +383,7 @@ LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:199:29
+ --> $DIR/duplicate.rs:202:29
|
LL | T: Iterator<Item: Copy, Item: Send>,
| ---------- ^^^^^^^^^^ re-bound here
@@ -367,7 +391,7 @@ LL | T: Iterator<Item: Copy, Item: Send>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:205:29
+ --> $DIR/duplicate.rs:208:29
|
LL | T: Iterator<Item: Copy, Item: Copy>,
| ---------- ^^^^^^^^^^ re-bound here
@@ -375,7 +399,7 @@ LL | T: Iterator<Item: Copy, Item: Copy>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:211:32
+ --> $DIR/duplicate.rs:214:32
|
LL | T: Iterator<Item: 'static, Item: 'static>,
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -383,7 +407,7 @@ LL | T: Iterator<Item: 'static, Item: 'static>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:217:32
+ --> $DIR/duplicate.rs:220:32
|
LL | Self: Iterator<Item: Copy, Item: Send>,
| ---------- ^^^^^^^^^^ re-bound here
@@ -391,7 +415,7 @@ LL | Self: Iterator<Item: Copy, Item: Send>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:217:32
+ --> $DIR/duplicate.rs:220:32
|
LL | Self: Iterator<Item: Copy, Item: Send>,
| ---------- ^^^^^^^^^^ re-bound here
@@ -399,7 +423,7 @@ LL | Self: Iterator<Item: Copy, Item: Send>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:224:32
+ --> $DIR/duplicate.rs:227:32
|
LL | Self: Iterator<Item: Copy, Item: Copy>,
| ---------- ^^^^^^^^^^ re-bound here
@@ -407,7 +431,7 @@ LL | Self: Iterator<Item: Copy, Item: Copy>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:224:32
+ --> $DIR/duplicate.rs:227:32
|
LL | Self: Iterator<Item: Copy, Item: Copy>,
| ---------- ^^^^^^^^^^ re-bound here
@@ -415,7 +439,7 @@ LL | Self: Iterator<Item: Copy, Item: Copy>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:231:35
+ --> $DIR/duplicate.rs:234:35
|
LL | Self: Iterator<Item: 'static, Item: 'static>,
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -423,7 +447,7 @@ LL | Self: Iterator<Item: 'static, Item: 'static>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:231:35
+ --> $DIR/duplicate.rs:234:35
|
LL | Self: Iterator<Item: 'static, Item: 'static>,
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -431,7 +455,7 @@ LL | Self: Iterator<Item: 'static, Item: 'static>,
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:249:40
+ --> $DIR/duplicate.rs:252:40
|
LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
| ---------- ^^^^^^^^^^ re-bound here
@@ -439,7 +463,7 @@ LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:251:44
+ --> $DIR/duplicate.rs:254:44
|
LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
| ---------- ^^^^^^^^^^ re-bound here
@@ -447,7 +471,7 @@ LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:253:43
+ --> $DIR/duplicate.rs:256:43
|
LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
| ------------- ^^^^^^^^^^^^^ re-bound here
@@ -455,7 +479,7 @@ LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:237:34
+ --> $DIR/duplicate.rs:240:34
|
LL | type A: Iterator<Item: Copy, Item: Send>;
| ---------- ^^^^^^^^^^ re-bound here
@@ -463,7 +487,7 @@ LL | type A: Iterator<Item: Copy, Item: Send>;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:241:34
+ --> $DIR/duplicate.rs:244:34
|
LL | type A: Iterator<Item: Copy, Item: Copy>;
| ---------- ^^^^^^^^^^ re-bound here
@@ -471,13 +495,13 @@ LL | type A: Iterator<Item: Copy, Item: Copy>;
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:245:37
+ --> $DIR/duplicate.rs:248:37
|
LL | type A: Iterator<Item: 'static, Item: 'static>;
| ------------- ^^^^^^^^^^^^^ re-bound here
| |
| `Item` bound here first
-error: aborting due to 60 previous errors
+error: aborting due to 63 previous errors
For more information about this error, try `rustc --explain E0719`.
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
index 446212ca7..bc9d12793 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
@@ -15,7 +15,7 @@ fn return_targets_async_block_not_fn() -> u8 {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
- //~^ ERROR expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
+ //~^ ERROR to be a future that resolves to `()`, but it resolves to `u8`
}
async fn return_targets_async_block_not_async_fn() -> u8 {
@@ -24,7 +24,7 @@ async fn return_targets_async_block_not_async_fn() -> u8 {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
- //~^ ERROR expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
+ //~^ ERROR to be a future that resolves to `()`, but it resolves to `u8`
}
fn no_break_in_async_block() {
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
index 2a08d5d6c..c4487eb84 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -1,8 +1,7 @@
error[E0267]: `break` inside of an `async` block
--> $DIR/async-block-control-flow-static-semantics.rs:32:9
|
-LL | async {
- | ___________-
+LL | / async {
LL | | break 0u8;
| | ^^^^^^^^^ cannot `break` inside of an `async` block
LL | | };
@@ -11,8 +10,7 @@ LL | | };
error[E0267]: `break` inside of an `async` block
--> $DIR/async-block-control-flow-static-semantics.rs:39:13
|
-LL | async {
- | _______________-
+LL | / async {
LL | | break 0u8;
| | ^^^^^^^^^ cannot `break` inside of an `async` block
LL | | };
@@ -31,13 +29,13 @@ LL | |
LL | | }
| |_^ expected `u8`, found `()`
-error[E0271]: expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
+error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to be a future that resolves to `()`, but it resolves to `u8`
--> $DIR/async-block-control-flow-static-semantics.rs:26:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
- = note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
+ = note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to the object type `dyn Future<Output = ()>`
error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:12:43
@@ -47,13 +45,13 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
| |
| implicitly returns `()` as its body has no tail or `return` expression
-error[E0271]: expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
+error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to be a future that resolves to `()`, but it resolves to `u8`
--> $DIR/async-block-control-flow-static-semantics.rs:17:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
- = note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
+ = note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to the object type `dyn Future<Output = ()>`
error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:49:44
diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
index f21c81151..190c59e32 100644
--- a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
+++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
@@ -1,11 +1,11 @@
error[E0373]: async block may outlive the current function, but it borrows `x`, which is owned by the current function
- --> $DIR/async-borrowck-escaping-block-error.rs:6:20
+ --> $DIR/async-borrowck-escaping-block-error.rs:6:14
|
LL | Box::new(async { x } )
- | ^^-^^
- | | |
- | | `x` is borrowed here
- | may outlive borrowed value `x`
+ | ^^^^^^^^-^^
+ | | |
+ | | `x` is borrowed here
+ | may outlive borrowed value `x`
|
note: async block is returned here
--> $DIR/async-borrowck-escaping-block-error.rs:6:5
@@ -18,13 +18,13 @@ LL | Box::new(async move { x } )
| ++++
error[E0373]: async block may outlive the current function, but it borrows `x`, which is owned by the current function
- --> $DIR/async-borrowck-escaping-block-error.rs:11:11
+ --> $DIR/async-borrowck-escaping-block-error.rs:11:5
|
LL | async { *x }
- | ^^--^^
- | | |
- | | `x` is borrowed here
- | may outlive borrowed value `x`
+ | ^^^^^^^^--^^
+ | | |
+ | | `x` is borrowed here
+ | may outlive borrowed value `x`
|
note: async block is returned here
--> $DIR/async-borrowck-escaping-block-error.rs:11:5
diff --git a/src/test/ui/async-await/auxiliary/issue-107036.rs b/src/test/ui/async-await/auxiliary/issue-107036.rs
new file mode 100644
index 000000000..c3f6141b2
--- /dev/null
+++ b/src/test/ui/async-await/auxiliary/issue-107036.rs
@@ -0,0 +1,12 @@
+// edition:2021
+
+pub trait T {}
+impl T for () {}
+
+pub struct S {}
+
+impl S {
+ pub async fn f<'a>(&self) -> impl T + 'a {
+ ()
+ }
+}
diff --git a/src/test/ui/async-await/drop-track-bad-field-in-fru.rs b/src/test/ui/async-await/drop-track-bad-field-in-fru.rs
new file mode 100644
index 000000000..28ad77675
--- /dev/null
+++ b/src/test/ui/async-await/drop-track-bad-field-in-fru.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Zdrop-tracking
+// edition: 2021
+
+fn main() {}
+
+async fn foo() {
+ None { value: (), ..Default::default() }.await;
+ //~^ ERROR `Option<_>` is not a future
+ //~| ERROR variant `Option<_>::None` has no field named `value`
+}
diff --git a/src/test/ui/async-await/drop-track-bad-field-in-fru.stderr b/src/test/ui/async-await/drop-track-bad-field-in-fru.stderr
new file mode 100644
index 000000000..819b64ad7
--- /dev/null
+++ b/src/test/ui/async-await/drop-track-bad-field-in-fru.stderr
@@ -0,0 +1,23 @@
+error[E0559]: variant `Option<_>::None` has no field named `value`
+ --> $DIR/drop-track-bad-field-in-fru.rs:7:12
+ |
+LL | None { value: (), ..Default::default() }.await;
+ | ^^^^^ `Option<_>::None` does not have this field
+
+error[E0277]: `Option<_>` is not a future
+ --> $DIR/drop-track-bad-field-in-fru.rs:7:45
+ |
+LL | None { value: (), ..Default::default() }.await;
+ | ^^^^^^
+ | |
+ | `Option<_>` is not a future
+ | help: remove the `.await`
+ |
+ = help: the trait `Future` is not implemented for `Option<_>`
+ = note: Option<_> must be a future or must implement `IntoFuture` to be awaited
+ = note: required for `Option<_>` to implement `IntoFuture`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0559.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/drop-tracking-unresolved-typeck-results.rs b/src/test/ui/async-await/drop-tracking-unresolved-typeck-results.rs
new file mode 100644
index 000000000..7f7294295
--- /dev/null
+++ b/src/test/ui/async-await/drop-tracking-unresolved-typeck-results.rs
@@ -0,0 +1,106 @@
+// compile-flags: -Zdrop-tracking
+// incremental
+// edition: 2021
+
+use std::future::*;
+use std::marker::PhantomData;
+use std::pin::Pin;
+use std::task::*;
+
+fn send<T: Send>(_: T) {}
+
+pub trait Stream {
+ type Item;
+
+ fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
+}
+
+struct Empty<T>(PhantomData<fn() -> T>);
+
+impl<T> Stream for Empty<T> {
+ type Item = T;
+
+ fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ todo!()
+ }
+}
+
+pub trait FnOnce1<A> {
+ type Output;
+ fn call_once(self, arg: A) -> Self::Output;
+}
+
+impl<T, A, R> FnOnce1<A> for T
+where
+ T: FnOnce(A) -> R,
+{
+ type Output = R;
+ fn call_once(self, arg: A) -> R {
+ self(arg)
+ }
+}
+
+pub trait FnMut1<A>: FnOnce1<A> {
+ fn call_mut(&mut self, arg: A) -> Self::Output;
+}
+
+impl<T, A, R> FnMut1<A> for T
+where
+ T: FnMut(A) -> R,
+{
+ fn call_mut(&mut self, arg: A) -> R {
+ self(arg)
+ }
+}
+
+struct Map<St, F>(St, F);
+
+impl<St, F> Stream for Map<St, F>
+where
+ St: Stream,
+ F: FnMut1<St::Item>,
+{
+ type Item = F::Output;
+
+ fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ todo!()
+ }
+}
+
+struct FuturesOrdered<T: Future>(PhantomData<fn() -> T::Output>);
+
+pub struct Buffered<St: Stream>(St, FuturesOrdered<St::Item>, usize)
+where
+ St::Item: Future;
+
+impl<St> Stream for Buffered<St>
+where
+ St: Stream,
+ St::Item: Future,
+{
+ type Item = <St::Item as Future>::Output;
+
+ fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+ todo!()
+ }
+}
+
+struct Next<'a, T: ?Sized>(&'a T);
+
+impl<St: ?Sized + Stream + Unpin> Future for Next<'_, St> {
+ type Output = Option<St::Item>;
+
+ fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ todo!()
+ }
+}
+
+fn main() {
+ send(async {
+ //~^ ERROR implementation of `FnOnce` is not general enough
+ //~| ERROR implementation of `FnOnce` is not general enough
+ //~| ERROR implementation of `FnOnce` is not general enough
+ //~| ERROR implementation of `FnOnce` is not general enough
+ Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
+ });
+}
diff --git a/src/test/ui/async-await/drop-tracking-unresolved-typeck-results.stderr b/src/test/ui/async-await/drop-tracking-unresolved-typeck-results.stderr
new file mode 100644
index 000000000..aa9a22e9e
--- /dev/null
+++ b/src/test/ui/async-await/drop-tracking-unresolved-typeck-results.stderr
@@ -0,0 +1,62 @@
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/drop-tracking-unresolved-typeck-results.rs:99:5
+ |
+LL | / send(async {
+LL | |
+LL | |
+LL | |
+LL | |
+LL | | Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
+LL | | });
+ | |______^ implementation of `FnOnce` is not general enough
+ |
+ = note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
+ = note: ...but it actually implements `FnOnce<(&(),)>`
+
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/drop-tracking-unresolved-typeck-results.rs:99:5
+ |
+LL | / send(async {
+LL | |
+LL | |
+LL | |
+LL | |
+LL | | Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
+LL | | });
+ | |______^ implementation of `FnOnce` is not general enough
+ |
+ = note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
+ = note: ...but it actually implements `FnOnce<(&(),)>`
+
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/drop-tracking-unresolved-typeck-results.rs:99:5
+ |
+LL | / send(async {
+LL | |
+LL | |
+LL | |
+LL | |
+LL | | Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
+LL | | });
+ | |______^ implementation of `FnOnce` is not general enough
+ |
+ = note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
+ = note: ...but it actually implements `FnOnce<(&(),)>`
+
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/drop-tracking-unresolved-typeck-results.rs:99:5
+ |
+LL | / send(async {
+LL | |
+LL | |
+LL | |
+LL | |
+LL | | Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
+LL | | });
+ | |______^ implementation of `FnOnce` is not general enough
+ |
+ = note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
+ = note: ...but it actually implements `FnOnce<(&(),)>`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/async-await/feature-self-return-type.rs b/src/test/ui/async-await/feature-self-return-type.rs
new file mode 100644
index 000000000..41f887430
--- /dev/null
+++ b/src/test/ui/async-await/feature-self-return-type.rs
@@ -0,0 +1,28 @@
+// edition:2018
+#![feature(impl_trait_projections)]
+
+// This test checks that we emit the correct borrowck error when `Self` is used as a return type.
+// See #61949 for context.
+
+pub struct Foo<'a> {
+ pub bar: &'a i32,
+}
+
+impl<'a> Foo<'a> {
+ pub async fn new(_bar: &'a i32) -> Self {
+ Foo {
+ bar: &22
+ }
+ }
+}
+
+pub async fn foo() {
+ let x = {
+ let bar = 22;
+ Foo::new(&bar).await
+ //~^ ERROR `bar` does not live long enough
+ };
+ drop(x);
+}
+
+fn main() { }
diff --git a/src/test/ui/async-await/feature-self-return-type.stderr b/src/test/ui/async-await/feature-self-return-type.stderr
new file mode 100644
index 000000000..892468368
--- /dev/null
+++ b/src/test/ui/async-await/feature-self-return-type.stderr
@@ -0,0 +1,15 @@
+error[E0597]: `bar` does not live long enough
+ --> $DIR/feature-self-return-type.rs:22:18
+ |
+LL | let x = {
+ | - borrow later stored here
+LL | let bar = 22;
+LL | Foo::new(&bar).await
+ | ^^^^ borrowed value does not live long enough
+LL |
+LL | };
+ | - `bar` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/async-await/generator-desc.stderr b/src/test/ui/async-await/generator-desc.stderr
index 2494c3feb..1686153ac 100644
--- a/src/test/ui/async-await/generator-desc.stderr
+++ b/src/test/ui/async-await/generator-desc.stderr
@@ -1,20 +1,20 @@
error[E0308]: mismatched types
- --> $DIR/generator-desc.rs:10:25
+ --> $DIR/generator-desc.rs:10:19
|
LL | fun(async {}, async {});
- | -- ^^
- | | |
- | | expected `async` block, found a different `async` block
- | | arguments to this function are incorrect
- | the expected `async` block
+ | -------- ^^^^^^^^
+ | | |
+ | | expected `async` block, found a different `async` block
+ | | arguments to this function are incorrect
+ | the expected `async` block
|
- = note: expected `async` block `[static generator@$DIR/generator-desc.rs:10:15: 10:17]`
- found `async` block `[static generator@$DIR/generator-desc.rs:10:25: 10:27]`
+ = note: expected `async` block `[async block@$DIR/generator-desc.rs:10:9: 10:17]`
+ found `async` block `[async block@$DIR/generator-desc.rs:10:19: 10:27]`
note: function defined here
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
|
-LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
- | ^^^^^^^^^^^^^^
+LL | pub const fn identity_future<O, Fut: Future<Output = O>>(f: Fut) -> Fut {
+ | ^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/generator-desc.rs:12:16
@@ -53,16 +53,8 @@ LL | fun((async || {})(), (async || {})());
| | the expected `async` closure body
| arguments to this function are incorrect
|
- ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
- |
-LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
- | -------------------------------
- | |
- | the expected opaque type
- | the found opaque type
- |
- = note: expected opaque type `impl Future<Output = ()>` (`async` closure body)
- found opaque type `impl Future<Output = ()>` (`async` closure body)
+ = note: expected `async` closure body `[async closure body@$DIR/generator-desc.rs:14:19: 14:21]`
+ found `async` closure body `[async closure body@$DIR/generator-desc.rs:14:36: 14:38]`
note: function defined here
--> $DIR/generator-desc.rs:8:4
|
diff --git a/src/test/ui/async-await/generator-not-future.rs b/src/test/ui/async-await/generator-not-future.rs
new file mode 100644
index 000000000..37d7cfa6f
--- /dev/null
+++ b/src/test/ui/async-await/generator-not-future.rs
@@ -0,0 +1,45 @@
+// edition:2018
+#![feature(generators, generator_trait)]
+
+use std::future::Future;
+use std::ops::Generator;
+
+async fn async_fn() {}
+fn returns_async_block() -> impl Future<Output = ()> {
+ async {}
+}
+fn returns_generator() -> impl Generator<(), Yield = (), Return = ()> {
+ || {
+ let _: () = yield ();
+ }
+}
+
+fn takes_future(_f: impl Future<Output = ()>) {}
+fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {}
+
+fn main() {
+ // okay:
+ takes_future(async_fn());
+ takes_future(returns_async_block());
+ takes_future(async {});
+ takes_generator(returns_generator());
+ takes_generator(|| {
+ let _: () = yield ();
+ });
+
+ // async futures are not generators:
+ takes_generator(async_fn());
+ //~^ ERROR the trait bound
+ takes_generator(returns_async_block());
+ //~^ ERROR the trait bound
+ takes_generator(async {});
+ //~^ ERROR the trait bound
+
+ // generators are not futures:
+ takes_future(returns_generator());
+ //~^ ERROR is not a future
+ takes_future(|ctx| {
+ //~^ ERROR is not a future
+ ctx = yield ();
+ });
+}
diff --git a/src/test/ui/async-await/generator-not-future.stderr b/src/test/ui/async-await/generator-not-future.stderr
new file mode 100644
index 000000000..1b81b461f
--- /dev/null
+++ b/src/test/ui/async-await/generator-not-future.stderr
@@ -0,0 +1,81 @@
+error[E0277]: the trait bound `impl Future<Output = ()>: Generator<_>` is not satisfied
+ --> $DIR/generator-not-future.rs:31:21
+ |
+LL | takes_generator(async_fn());
+ | --------------- ^^^^^^^^^^ the trait `Generator<_>` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `takes_generator`
+ --> $DIR/generator-not-future.rs:18:39
+ |
+LL | fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_generator`
+
+error[E0277]: the trait bound `impl Future<Output = ()>: Generator<_>` is not satisfied
+ --> $DIR/generator-not-future.rs:33:21
+ |
+LL | takes_generator(returns_async_block());
+ | --------------- ^^^^^^^^^^^^^^^^^^^^^ the trait `Generator<_>` is not implemented for `impl Future<Output = ()>`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `takes_generator`
+ --> $DIR/generator-not-future.rs:18:39
+ |
+LL | fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_generator`
+
+error[E0277]: the trait bound `[async block@$DIR/generator-not-future.rs:35:21: 35:29]: Generator<_>` is not satisfied
+ --> $DIR/generator-not-future.rs:35:21
+ |
+LL | takes_generator(async {});
+ | --------------- ^^^^^^^^ the trait `Generator<_>` is not implemented for `[async block@$DIR/generator-not-future.rs:35:21: 35:29]`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `takes_generator`
+ --> $DIR/generator-not-future.rs:18:39
+ |
+LL | fn takes_generator<ResumeTy>(_g: impl Generator<ResumeTy, Yield = (), Return = ()>) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_generator`
+
+error[E0277]: `impl Generator<Yield = (), Return = ()>` is not a future
+ --> $DIR/generator-not-future.rs:39:18
+ |
+LL | takes_future(returns_generator());
+ | ------------ ^^^^^^^^^^^^^^^^^^^ `impl Generator<Yield = (), Return = ()>` is not a future
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Future` is not implemented for `impl Generator<Yield = (), Return = ()>`
+ = note: impl Generator<Yield = (), Return = ()> must be a future or must implement `IntoFuture` to be awaited
+note: required by a bound in `takes_future`
+ --> $DIR/generator-not-future.rs:17:26
+ |
+LL | fn takes_future(_f: impl Future<Output = ()>) {}
+ | ^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_future`
+
+error[E0277]: `[generator@$DIR/generator-not-future.rs:41:18: 41:23]` is not a future
+ --> $DIR/generator-not-future.rs:41:18
+ |
+LL | takes_future(|ctx| {
+ | _____------------_^
+ | | |
+ | | required by a bound introduced by this call
+LL | |
+LL | | ctx = yield ();
+LL | | });
+ | |_____^ `[generator@$DIR/generator-not-future.rs:41:18: 41:23]` is not a future
+ |
+ = help: the trait `Future` is not implemented for `[generator@$DIR/generator-not-future.rs:41:18: 41:23]`
+ = note: [generator@$DIR/generator-not-future.rs:41:18: 41:23] must be a future or must implement `IntoFuture` to be awaited
+note: required by a bound in `takes_future`
+ --> $DIR/generator-not-future.rs:17:26
+ |
+LL | fn takes_future(_f: impl Future<Output = ()>) {}
+ | ^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_future`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/in-trait/async-associated-types.rs b/src/test/ui/async-await/in-trait/async-associated-types.rs
index a6f928f3b..974f5aaff 100644
--- a/src/test/ui/async-await/in-trait/async-associated-types.rs
+++ b/src/test/ui/async-await/in-trait/async-associated-types.rs
@@ -1,8 +1,8 @@
-// check-fail
-// known-bug: #102682
+// check-pass
// edition: 2021
#![feature(async_fn_in_trait)]
+#![feature(impl_trait_projections)]
#![allow(incomplete_features)]
use std::fmt::Debug;
diff --git a/src/test/ui/async-await/in-trait/async-associated-types.stderr b/src/test/ui/async-await/in-trait/async-associated-types.stderr
deleted file mode 100644
index 0985150ee..000000000
--- a/src/test/ui/async-await/in-trait/async-associated-types.stderr
+++ /dev/null
@@ -1,57 +0,0 @@
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
- --> $DIR/async-associated-types.rs:19:43
- |
-LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
- | ^^^^^^^^^^^^^^
- |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
- --> $DIR/async-associated-types.rs:16:6
- |
-LL | impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
- | ^^
-note: ...so that the types are compatible
- --> $DIR/async-associated-types.rs:19:43
- |
-LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
- | ^^^^^^^^^^^^^^
- = note: expected `(&'a U, &'b T)`
- found `(&U, &T)`
- = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the types are compatible
- --> $DIR/async-associated-types.rs:19:43
- |
-LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
- | ^^^^^^^^^^^^^^
- = note: expected `MyTrait<'static, 'static, T>`
- found `MyTrait<'_, '_, T>`
-
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
- --> $DIR/async-associated-types.rs:19:43
- |
-LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
- | ^^^^^^^^^^^^^^
- |
-note: first, the lifetime cannot outlive the lifetime `'b` as defined here...
- --> $DIR/async-associated-types.rs:16:10
- |
-LL | impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
- | ^^
-note: ...so that the types are compatible
- --> $DIR/async-associated-types.rs:19:43
- |
-LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
- | ^^^^^^^^^^^^^^
- = note: expected `(&'a U, &'b T)`
- found `(&U, &T)`
- = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the types are compatible
- --> $DIR/async-associated-types.rs:19:43
- |
-LL | async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
- | ^^^^^^^^^^^^^^
- = note: expected `MyTrait<'static, 'static, T>`
- found `MyTrait<'_, '_, T>`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr
index 5c8d64fc6..f1f0d7e59 100644
--- a/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr
+++ b/src/test/ui/async-await/in-trait/async-generics-and-bounds.stderr
@@ -4,11 +4,11 @@ error[E0311]: the parameter type `U` may not live long enough
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^^^^^^^
|
-note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
+note: the parameter type `U` must be valid for the anonymous lifetime defined here...
--> $DIR/async-generics-and-bounds.rs:12:18
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
- | ^
+ | ^^^^^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics-and-bounds.rs:12:28
|
@@ -21,11 +21,11 @@ error[E0311]: the parameter type `T` may not live long enough
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
| ^^^^^^^
|
-note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
--> $DIR/async-generics-and-bounds.rs:12:18
|
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
- | ^
+ | ^^^^^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics-and-bounds.rs:12:28
|
diff --git a/src/test/ui/async-await/in-trait/async-generics.stderr b/src/test/ui/async-await/in-trait/async-generics.stderr
index 6ae73d9e3..2f0556456 100644
--- a/src/test/ui/async-await/in-trait/async-generics.stderr
+++ b/src/test/ui/async-await/in-trait/async-generics.stderr
@@ -4,11 +4,11 @@ error[E0311]: the parameter type `U` may not live long enough
LL | async fn foo(&self) -> &(T, U);
| ^^^^^^^
|
-note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
+note: the parameter type `U` must be valid for the anonymous lifetime defined here...
--> $DIR/async-generics.rs:9:18
|
LL | async fn foo(&self) -> &(T, U);
- | ^
+ | ^^^^^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics.rs:9:28
|
@@ -21,11 +21,11 @@ error[E0311]: the parameter type `T` may not live long enough
LL | async fn foo(&self) -> &(T, U);
| ^^^^^^^
|
-note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
--> $DIR/async-generics.rs:9:18
|
LL | async fn foo(&self) -> &(T, U);
- | ^
+ | ^^^^^
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
--> $DIR/async-generics.rs:9:28
|
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs
index 3f7448cec..d5481d277 100644
--- a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs
+++ b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.rs
@@ -1,5 +1,4 @@
-// check-fail
-// known-bug: #102682
+// check-pass
// edition: 2021
#![feature(async_fn_in_trait)]
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr b/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr
deleted file mode 100644
index 0f0242027..000000000
--- a/src/test/ui/async-await/in-trait/async-lifetimes-and-bounds.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0309]: the parameter type `Self` may not live long enough
- --> $DIR/async-lifetimes-and-bounds.rs:11:43
- |
-LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider adding an explicit lifetime bound `Self: 'a`...
- = note: ...so that the reference type `&'a Self` does not outlive the data it points at
-
-error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/async-lifetimes-and-bounds.rs:11:43
- |
-LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T) where T: Debug + Sized;
- | ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at
- |
-help: consider adding an explicit lifetime bound...
- |
-LL | trait MyTrait<'a, 'b, T: 'b> {
- | ++++
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.rs b/src/test/ui/async-await/in-trait/async-lifetimes.rs
index acbac471c..f298e45d2 100644
--- a/src/test/ui/async-await/in-trait/async-lifetimes.rs
+++ b/src/test/ui/async-await/in-trait/async-lifetimes.rs
@@ -1,5 +1,4 @@
-// check-fail
-// known-bug: #102682
+// check-pass
// edition: 2021
#![feature(async_fn_in_trait)]
diff --git a/src/test/ui/async-await/in-trait/async-lifetimes.stderr b/src/test/ui/async-await/in-trait/async-lifetimes.stderr
deleted file mode 100644
index 9a7d294bb..000000000
--- a/src/test/ui/async-await/in-trait/async-lifetimes.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0309]: the parameter type `Self` may not live long enough
- --> $DIR/async-lifetimes.rs:9:43
- |
-LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider adding an explicit lifetime bound `Self: 'a`...
- = note: ...so that the reference type `&'a Self` does not outlive the data it points at
-
-error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/async-lifetimes.rs:9:43
- |
-LL | async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
- | ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'b T` does not outlive the data it points at
- |
-help: consider adding an explicit lifetime bound...
- |
-LL | trait MyTrait<'a, 'b, T: 'b> {
- | ++++
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/async-await/in-trait/early-bound-1.rs b/src/test/ui/async-await/in-trait/early-bound-1.rs
new file mode 100644
index 000000000..6b3b14201
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/early-bound-1.rs
@@ -0,0 +1,17 @@
+// check-pass
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+pub trait Foo {
+ async fn foo(&mut self);
+}
+
+struct MyFoo<'a>(&'a mut ());
+
+impl<'a> Foo for MyFoo<'a> {
+ async fn foo(&mut self) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/early-bound-2.rs b/src/test/ui/async-await/in-trait/early-bound-2.rs
new file mode 100644
index 000000000..270443229
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/early-bound-2.rs
@@ -0,0 +1,15 @@
+// check-pass
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+pub trait Foo {
+ async fn foo(&mut self);
+}
+
+impl<T: Foo> Foo for &mut T {
+ async fn foo(&mut self) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/implied-bounds.rs b/src/test/ui/async-await/in-trait/implied-bounds.rs
new file mode 100644
index 000000000..52bceb3cc
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/implied-bounds.rs
@@ -0,0 +1,13 @@
+// check-pass
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait TcpStack {
+ type Connection<'a>: Sized where Self: 'a;
+ fn connect<'a>(&'a self) -> Self::Connection<'a>;
+ async fn async_connect<'a>(&'a self) -> Self::Connection<'a>;
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/lifetime-mismatch.rs b/src/test/ui/async-await/in-trait/lifetime-mismatch.rs
new file mode 100644
index 000000000..45ede193c
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/lifetime-mismatch.rs
@@ -0,0 +1,20 @@
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait MyTrait {
+ async fn foo<'a>(&self);
+ async fn bar(&self);
+}
+
+impl MyTrait for i32 {
+ async fn foo(&self) {}
+ //~^ ERROR lifetime parameters or bounds on method `foo` do not match the trait declaration
+
+ async fn bar(&self) {
+ self.foo();
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr b/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr
new file mode 100644
index 000000000..d87adcc78
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr
@@ -0,0 +1,21 @@
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/lifetime-mismatch.rs:3:12
+ |
+LL | #![feature(async_fn_in_trait)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+ --> $DIR/lifetime-mismatch.rs:12:17
+ |
+LL | async fn foo<'a>(&self);
+ | ---- lifetimes in impl do not match this method in trait
+...
+LL | async fn foo(&self) {}
+ | ^ lifetimes do not match method in trait
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0195`.
diff --git a/src/test/ui/async-await/in-trait/nested-rpit.rs b/src/test/ui/async-await/in-trait/nested-rpit.rs
new file mode 100644
index 000000000..41d72ebb4
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/nested-rpit.rs
@@ -0,0 +1,19 @@
+// edition: 2021
+// known-bug: #105197
+// failure-status:101
+// dont-check-compiler-stderr
+
+#![feature(async_fn_in_trait)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+use std::marker::PhantomData;
+
+trait Lockable<K, V> {
+ async fn lock_all_entries(&self) -> impl Future<Output = Guard<'_>>;
+}
+
+struct Guard<'a>(PhantomData<&'a ()>);
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/object-safety.rs b/src/test/ui/async-await/in-trait/object-safety.rs
new file mode 100644
index 000000000..a8bc35f7e
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/object-safety.rs
@@ -0,0 +1,13 @@
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait Foo {
+ async fn foo(&self);
+}
+
+fn main() {
+ let x: &dyn Foo = todo!();
+ //~^ ERROR the trait `Foo` cannot be made into an object
+}
diff --git a/src/test/ui/async-await/in-trait/object-safety.stderr b/src/test/ui/async-await/in-trait/object-safety.stderr
new file mode 100644
index 000000000..0b318f71f
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/object-safety.stderr
@@ -0,0 +1,27 @@
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/object-safety.rs:3:12
+ |
+LL | #![feature(async_fn_in_trait)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/object-safety.rs:11:12
+ |
+LL | let x: &dyn Foo = todo!();
+ | ^^^^^^^^ `Foo` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety.rs:7:14
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | async fn foo(&self);
+ | ^^^ ...because method `foo` is `async`
+ = help: consider moving `foo` to another trait
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/async-await/in-trait/return-type-suggestion.rs b/src/test/ui/async-await/in-trait/return-type-suggestion.rs
new file mode 100644
index 000000000..3446761d1
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/return-type-suggestion.rs
@@ -0,0 +1,14 @@
+// edition: 2021
+
+#![feature(async_fn_in_trait)]
+//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait A {
+ async fn e() {
+ Ok(())
+ //~^ ERROR mismatched types
+ //~| HELP consider using a semicolon here
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/return-type-suggestion.stderr b/src/test/ui/async-await/in-trait/return-type-suggestion.stderr
new file mode 100644
index 000000000..5a9b15e54
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/return-type-suggestion.stderr
@@ -0,0 +1,23 @@
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/return-type-suggestion.rs:3:12
+ |
+LL | #![feature(async_fn_in_trait)]
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+ --> $DIR/return-type-suggestion.rs:8:9
+ |
+LL | Ok(())
+ | ^^^^^^- help: consider using a semicolon here: `;`
+ | |
+ | expected `()`, found enum `Result`
+ |
+ = note: expected unit type `()`
+ found enum `Result<(), _>`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/async-await/issue-107036.rs b/src/test/ui/async-await/issue-107036.rs
new file mode 100644
index 000000000..6a22de2c9
--- /dev/null
+++ b/src/test/ui/async-await/issue-107036.rs
@@ -0,0 +1,14 @@
+// aux-build:issue-107036.rs
+// edition:2021
+// check-pass
+
+extern crate issue_107036;
+use issue_107036::S;
+
+async fn f() {
+ S{}.f().await;
+}
+
+fn main() {
+ let _ = f();
+}
diff --git a/src/test/ui/async-await/issue-61949-self-return-type.rs b/src/test/ui/async-await/issue-61949-self-return-type.rs
index 43429ba23..d73dbc6e8 100644
--- a/src/test/ui/async-await/issue-61949-self-return-type.rs
+++ b/src/test/ui/async-await/issue-61949-self-return-type.rs
@@ -1,4 +1,5 @@
// edition:2018
+// gate-test-impl_trait_projections
// This test checks that `Self` is prohibited as a return type. See #61949 for context.
@@ -19,6 +20,7 @@ async fn foo() {
let x = {
let bar = 22;
Foo::new(&bar).await
+ //~^ ERROR `bar` does not live long enough
};
drop(x);
}
diff --git a/src/test/ui/async-await/issue-61949-self-return-type.stderr b/src/test/ui/async-await/issue-61949-self-return-type.stderr
index 52b726e18..638b197bc 100644
--- a/src/test/ui/async-await/issue-61949-self-return-type.stderr
+++ b/src/test/ui/async-await/issue-61949-self-return-type.stderr
@@ -1,9 +1,25 @@
-error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
- --> $DIR/issue-61949-self-return-type.rs:10:40
+error[E0658]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+ --> $DIR/issue-61949-self-return-type.rs:11:40
|
LL | pub async fn new(_bar: &'a i32) -> Self {
| ^^^^ help: consider spelling out the type instead: `Foo<'a>`
+ |
+ = note: see issue #103532 <https://github.com/rust-lang/rust/issues/103532> for more information
+ = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable
+
+error[E0597]: `bar` does not live long enough
+ --> $DIR/issue-61949-self-return-type.rs:22:18
+ |
+LL | let x = {
+ | - borrow later stored here
+LL | let bar = 22;
+LL | Foo::new(&bar).await
+ | ^^^^ borrowed value does not live long enough
+LL |
+LL | };
+ | - `bar` dropped here while still borrowed
-error: aborting due to previous error
+error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0760`.
+Some errors have detailed explanations: E0597, E0658.
+For more information about an error, try `rustc --explain E0597`.
diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.stderr b/src/test/ui/async-await/issue-67252-unnamed-future.stderr
index af99b608c..fcba4410b 100644
--- a/src/test/ui/async-await/issue-67252-unnamed-future.stderr
+++ b/src/test/ui/async-await/issue-67252-unnamed-future.stderr
@@ -8,7 +8,7 @@ LL | | AFuture.await;
LL | | });
| |_____^ future created by async block is not `Send`
|
- = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*mut ()`
+ = help: within `[async block@$DIR/issue-67252-unnamed-future.rs:18:11: 21:6]`, the trait `Send` is not implemented for `*mut ()`
note: future is not `Send` as this value is used across an await
--> $DIR/issue-67252-unnamed-future.rs:20:16
|
diff --git a/src/test/ui/async-await/issue-68112.drop_tracking.stderr b/src/test/ui/async-await/issue-68112.drop_tracking.stderr
index c915164cf..f2802698f 100644
--- a/src/test/ui/async-await/issue-68112.drop_tracking.stderr
+++ b/src/test/ui/async-await/issue-68112.drop_tracking.stderr
@@ -59,10 +59,10 @@ LL | fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: required because it captures the following types: `ResumeTy`, `impl Future<Output = Arc<RefCell<i32>>>`, `()`, `Ready<i32>`
note: required because it's used within this `async` block
- --> $DIR/issue-68112.rs:60:26
+ --> $DIR/issue-68112.rs:60:20
|
LL | let send_fut = async {
- | __________________________^
+ | ____________________^
LL | | let non_send_fut = make_non_send_future2();
LL | | let _ = non_send_fut.await;
LL | | ready(0).await;
diff --git a/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr b/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr
index 11b7d1aaa..38eb85b30 100644
--- a/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr
+++ b/src/test/ui/async-await/issue-68112.no_drop_tracking.stderr
@@ -59,10 +59,10 @@ LL | fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: required because it captures the following types: `ResumeTy`, `impl Future<Output = Arc<RefCell<i32>>>`, `()`, `i32`, `Ready<i32>`
note: required because it's used within this `async` block
- --> $DIR/issue-68112.rs:60:26
+ --> $DIR/issue-68112.rs:60:20
|
LL | let send_fut = async {
- | __________________________^
+ | ____________________^
LL | | let non_send_fut = make_non_send_future2();
LL | | let _ = non_send_fut.await;
LL | | ready(0).await;
diff --git a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
index 7fb881166..721234aa4 100644
--- a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
+++ b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
@@ -20,10 +20,9 @@ LL | | }
| |_^
= note: required because it captures the following types: `ResumeTy`, `impl Future<Output = ()>`, `()`
note: required because it's used within this `async` block
- --> $DIR/issue-70935-complex-spans.rs:16:16
+ --> $DIR/issue-70935-complex-spans.rs:16:5
|
-LL | async move {
- | ________________^
+LL | / async move {
LL | | baz(|| async{
LL | | foo(tx.clone());
LL | | }).await;
diff --git a/src/test/ui/async-await/issue-86507.stderr b/src/test/ui/async-await/issue-86507.stderr
index 0e21dba98..8c2c06da2 100644
--- a/src/test/ui/async-await/issue-86507.stderr
+++ b/src/test/ui/async-await/issue-86507.stderr
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
LL | let x = x;
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
- = note: required for the cast from `impl Future<Output = ()>` to the object type `dyn Future<Output = ()> + Send`
+ = note: required for the cast from `[async block@$DIR/issue-86507.rs:18:17: 20:18]` to the object type `dyn Future<Output = ()> + Send`
help: consider further restricting this bound
|
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
diff --git a/src/test/ui/async-await/issues/issue-65159.rs b/src/test/ui/async-await/issues/issue-65159.rs
index 1dbf5db6c..df2ca0257 100644
--- a/src/test/ui/async-await/issues/issue-65159.rs
+++ b/src/test/ui/async-await/issues/issue-65159.rs
@@ -6,7 +6,6 @@ async fn copy() -> Result<()>
//~^ ERROR this enum takes 2 generic arguments
{
Ok(())
- //~^ ERROR type annotations needed
}
fn main() { }
diff --git a/src/test/ui/async-await/issues/issue-65159.stderr b/src/test/ui/async-await/issues/issue-65159.stderr
index 9918f569c..45f5ec40c 100644
--- a/src/test/ui/async-await/issues/issue-65159.stderr
+++ b/src/test/ui/async-await/issues/issue-65159.stderr
@@ -16,18 +16,6 @@ help: add missing generic argument
LL | async fn copy() -> Result<(), E>
| +++
-error[E0282]: type annotations needed
- --> $DIR/issue-65159.rs:8:5
- |
-LL | Ok(())
- | ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
- |
-help: consider specifying the generic arguments
- |
-LL | Ok::<(), E>(())
- | +++++++++
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-Some errors have detailed explanations: E0107, E0282.
-For more information about an error, try `rustc --explain E0107`.
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr
index a72350377..ab196dca2 100644
--- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr
+++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr
@@ -8,7 +8,7 @@ LL | | bar(Foo(std::ptr::null())).await;
LL | | })
| |_____^ future created by async block is not `Send`
|
- = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const u8`
+ = help: within `[async block@$DIR/issue-65436-raw-ptr-not-send.rs:16:17: 19:6]`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> $DIR/issue-65436-raw-ptr-not-send.rs:18:35
|
diff --git a/src/test/ui/async-await/issues/issue-78600.stderr b/src/test/ui/async-await/issues/issue-78600.stderr
index 92b661471..37eafa996 100644
--- a/src/test/ui/async-await/issues/issue-78600.stderr
+++ b/src/test/ui/async-await/issues/issue-78600.stderr
@@ -1,11 +1,14 @@
-error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+error[E0658]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
--> $DIR/issue-78600.rs:6:33
|
LL | async fn new(i: &'a i32) -> Result<Self, ()> {
| ^^^^^^^----^^^^^
| |
| help: consider spelling out the type instead: `S<'a>`
+ |
+ = note: see issue #103532 <https://github.com/rust-lang/rust/issues/103532> for more information
+ = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0760`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/async-await/issues/issue-78938-async-block.stderr b/src/test/ui/async-await/issues/issue-78938-async-block.stderr
index 29aa8372f..c1a4b467f 100644
--- a/src/test/ui/async-await/issues/issue-78938-async-block.stderr
+++ b/src/test/ui/async-await/issues/issue-78938-async-block.stderr
@@ -1,8 +1,8 @@
error[E0373]: async block may outlive the current function, but it borrows `room_ref`, which is owned by the current function
- --> $DIR/issue-78938-async-block.rs:8:39
+ --> $DIR/issue-78938-async-block.rs:8:33
|
LL | let gameloop_handle = spawn(async {
- | _______________________________________^
+ | _________________________________^
LL | | game_loop(Arc::clone(&room_ref))
| | -------- `room_ref` is borrowed here
LL | | });
diff --git a/src/test/ui/async-await/large_moves.attribute.stderr b/src/test/ui/async-await/large_moves.attribute.stderr
index da34f44b2..0c5452475 100644
--- a/src/test/ui/async-await/large_moves.attribute.stderr
+++ b/src/test/ui/async-await/large_moves.attribute.stderr
@@ -1,5 +1,5 @@
error: moving 10024 bytes
- --> $DIR/large_moves.rs:12:13
+ --> $DIR/large_moves.rs:13:13
|
LL | let x = async {
| _____________^
@@ -18,7 +18,7 @@ LL | #![deny(large_assignments)]
| ^^^^^^^^^^^^^^^^^
error: moving 10024 bytes
- --> $DIR/large_moves.rs:18:14
+ --> $DIR/large_moves.rs:19:14
|
LL | let z = (x, 42);
| ^ value moved from here
@@ -26,7 +26,7 @@ LL | let z = (x, 42);
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
error: moving 10024 bytes
- --> $DIR/large_moves.rs:18:13
+ --> $DIR/large_moves.rs:19:13
|
LL | let z = (x, 42);
| ^^^^^^^ value moved from here
@@ -34,7 +34,7 @@ LL | let z = (x, 42);
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
error: moving 10024 bytes
- --> $DIR/large_moves.rs:20:13
+ --> $DIR/large_moves.rs:21:13
|
LL | let a = z.0;
| ^^^ value moved from here
diff --git a/src/test/ui/async-await/large_moves.option.stderr b/src/test/ui/async-await/large_moves.option.stderr
index da34f44b2..0c5452475 100644
--- a/src/test/ui/async-await/large_moves.option.stderr
+++ b/src/test/ui/async-await/large_moves.option.stderr
@@ -1,5 +1,5 @@
error: moving 10024 bytes
- --> $DIR/large_moves.rs:12:13
+ --> $DIR/large_moves.rs:13:13
|
LL | let x = async {
| _____________^
@@ -18,7 +18,7 @@ LL | #![deny(large_assignments)]
| ^^^^^^^^^^^^^^^^^
error: moving 10024 bytes
- --> $DIR/large_moves.rs:18:14
+ --> $DIR/large_moves.rs:19:14
|
LL | let z = (x, 42);
| ^ value moved from here
@@ -26,7 +26,7 @@ LL | let z = (x, 42);
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
error: moving 10024 bytes
- --> $DIR/large_moves.rs:18:13
+ --> $DIR/large_moves.rs:19:13
|
LL | let z = (x, 42);
| ^^^^^^^ value moved from here
@@ -34,7 +34,7 @@ LL | let z = (x, 42);
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
error: moving 10024 bytes
- --> $DIR/large_moves.rs:20:13
+ --> $DIR/large_moves.rs:21:13
|
LL | let a = z.0;
| ^^^ value moved from here
diff --git a/src/test/ui/async-await/large_moves.rs b/src/test/ui/async-await/large_moves.rs
index 18bb538a8..d43d0eec0 100644
--- a/src/test/ui/async-await/large_moves.rs
+++ b/src/test/ui/async-await/large_moves.rs
@@ -7,6 +7,7 @@
// [option]compile-flags: -Zmove-size-limit=1000
// edition:2018
+// compile-flags: -Zmir-opt-level=0
fn main() {
let x = async { //~ ERROR large_assignments
diff --git a/src/test/ui/async-await/track-caller/async-closure-gate.rs b/src/test/ui/async-await/track-caller/async-closure-gate.rs
new file mode 100644
index 000000000..d9d556855
--- /dev/null
+++ b/src/test/ui/async-await/track-caller/async-closure-gate.rs
@@ -0,0 +1,9 @@
+// edition:2021
+
+#![feature(async_closure, stmt_expr_attributes)]
+
+fn main() {
+ let _ = #[track_caller] async || {
+ //~^ ERROR `#[track_caller]` on closures is currently unstable [E0658]
+ };
+}
diff --git a/src/test/ui/async-await/track-caller/async-closure-gate.stderr b/src/test/ui/async-await/track-caller/async-closure-gate.stderr
new file mode 100644
index 000000000..498f1b43b
--- /dev/null
+++ b/src/test/ui/async-await/track-caller/async-closure-gate.stderr
@@ -0,0 +1,12 @@
+error[E0658]: `#[track_caller]` on closures is currently unstable
+ --> $DIR/async-closure-gate.rs:6:13
+ |
+LL | let _ = #[track_caller] async || {
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
+ = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/async-await/track-caller/issue-105134.rs b/src/test/ui/async-await/track-caller/issue-105134.rs
new file mode 100644
index 000000000..4e52b8e25
--- /dev/null
+++ b/src/test/ui/async-await/track-caller/issue-105134.rs
@@ -0,0 +1,11 @@
+// check-pass
+// edition:2021
+
+#[track_caller]
+fn f() {
+ let _ = async {};
+}
+
+fn main() {
+ f();
+}
diff --git a/src/test/ui/async-await/track-caller/panic-track-caller.nofeat.stderr b/src/test/ui/async-await/track-caller/panic-track-caller.nofeat.stderr
new file mode 100644
index 000000000..51ea225f4
--- /dev/null
+++ b/src/test/ui/async-await/track-caller/panic-track-caller.nofeat.stderr
@@ -0,0 +1,29 @@
+warning: `#[track_caller]` on async functions is a no-op
+ --> $DIR/panic-track-caller.rs:50:1
+ |
+LL | #[track_caller]
+ | ^^^^^^^^^^^^^^^
+LL | / async fn bar_track_caller() {
+LL | | panic!()
+LL | | }
+ | |_- this function will not propagate the caller location
+ |
+ = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
+ = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
+ = note: `#[warn(ungated_async_fn_track_caller)]` on by default
+
+warning: `#[track_caller]` on async functions is a no-op
+ --> $DIR/panic-track-caller.rs:62:5
+ |
+LL | #[track_caller]
+ | ^^^^^^^^^^^^^^^
+LL | / async fn bar_assoc() {
+LL | | panic!();
+LL | | }
+ | |_____- this function will not propagate the caller location
+ |
+ = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
+ = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/async-await/track-caller/panic-track-caller.rs b/src/test/ui/async-await/track-caller/panic-track-caller.rs
new file mode 100644
index 000000000..118361d6c
--- /dev/null
+++ b/src/test/ui/async-await/track-caller/panic-track-caller.rs
@@ -0,0 +1,100 @@
+// run-pass
+// edition:2021
+// revisions: feat nofeat
+// needs-unwind
+#![feature(async_closure, stmt_expr_attributes)]
+#![cfg_attr(feat, feature(closure_track_caller))]
+
+use std::future::Future;
+use std::panic;
+use std::sync::{Arc, Mutex};
+use std::task::{Context, Poll, Wake};
+use std::thread::{self, Thread};
+
+/// A waker that wakes up the current thread when called.
+struct ThreadWaker(Thread);
+
+impl Wake for ThreadWaker {
+ fn wake(self: Arc<Self>) {
+ self.0.unpark();
+ }
+}
+
+/// Run a future to completion on the current thread.
+fn block_on<T>(fut: impl Future<Output = T>) -> T {
+ // Pin the future so it can be polled.
+ let mut fut = Box::pin(fut);
+
+ // Create a new context to be passed to the future.
+ let t = thread::current();
+ let waker = Arc::new(ThreadWaker(t)).into();
+ let mut cx = Context::from_waker(&waker);
+
+ // Run the future to completion.
+ loop {
+ match fut.as_mut().poll(&mut cx) {
+ Poll::Ready(res) => return res,
+ Poll::Pending => thread::park(),
+ }
+ }
+}
+
+async fn bar() {
+ panic!()
+}
+
+async fn foo() {
+ bar().await
+}
+
+#[track_caller] //[nofeat]~ WARN `#[track_caller]` on async functions is a no-op
+async fn bar_track_caller() {
+ panic!()
+}
+
+async fn foo_track_caller() {
+ bar_track_caller().await
+}
+
+struct Foo;
+
+impl Foo {
+ #[track_caller] //[nofeat]~ WARN `#[track_caller]` on async functions is a no-op
+ async fn bar_assoc() {
+ panic!();
+ }
+}
+
+async fn foo_assoc() {
+ Foo::bar_assoc().await
+}
+
+fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
+ let loc = Arc::new(Mutex::new(None));
+
+ let hook = panic::take_hook();
+ {
+ let loc = loc.clone();
+ panic::set_hook(Box::new(move |info| {
+ *loc.lock().unwrap() = info.location().map(|loc| loc.line())
+ }));
+ }
+ panic::catch_unwind(f).unwrap_err();
+ panic::set_hook(hook);
+ let x = loc.lock().unwrap().unwrap();
+ x
+}
+
+fn main() {
+ assert_eq!(panicked_at(|| block_on(foo())), 43);
+
+ #[cfg(feat)]
+ assert_eq!(panicked_at(|| block_on(foo_track_caller())), 56);
+ #[cfg(nofeat)]
+ assert_eq!(panicked_at(|| block_on(foo_track_caller())), 52);
+
+ #[cfg(feat)]
+ assert_eq!(panicked_at(|| block_on(foo_assoc())), 69);
+ #[cfg(nofeat)]
+ assert_eq!(panicked_at(|| block_on(foo_assoc())), 64);
+}
diff --git a/src/test/ui/async-await/try-on-option-in-async.stderr b/src/test/ui/async-await/try-on-option-in-async.stderr
index a55850d76..4c7b4fa41 100644
--- a/src/test/ui/async-await/try-on-option-in-async.stderr
+++ b/src/test/ui/async-await/try-on-option-in-async.stderr
@@ -1,8 +1,7 @@
error[E0277]: the `?` operator can only be used in an async block that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option-in-async.rs:8:10
|
-LL | async {
- | ___________-
+LL | / async {
LL | | let x: Option<u32> = None;
LL | | x?;
| | ^ cannot use the `?` operator in an async block that returns `{integer}`
diff --git a/src/test/ui/attributes/key-value-non-ascii.rs b/src/test/ui/attributes/key-value-non-ascii.rs
index 12942eabd..e14e2fc05 100644
--- a/src/test/ui/attributes/key-value-non-ascii.rs
+++ b/src/test/ui/attributes/key-value-non-ascii.rs
@@ -1,4 +1,4 @@
#![feature(rustc_attrs)]
-#[rustc_dummy = b"ffi.rs"] //~ ERROR non-ASCII character in byte constant
+#[rustc_dummy = b"ffi.rs"] //~ ERROR non-ASCII character in byte string literal
fn main() {}
diff --git a/src/test/ui/attributes/key-value-non-ascii.stderr b/src/test/ui/attributes/key-value-non-ascii.stderr
index 422107867..23d482de6 100644
--- a/src/test/ui/attributes/key-value-non-ascii.stderr
+++ b/src/test/ui/attributes/key-value-non-ascii.stderr
@@ -1,8 +1,8 @@
-error: non-ASCII character in byte constant
+error: non-ASCII character in byte string literal
--> $DIR/key-value-non-ascii.rs:3:19
|
LL | #[rustc_dummy = b"ffi.rs"]
- | ^ byte constant must be ASCII
+ | ^ must be ASCII
|
help: if you meant to use the UTF-8 encoding of 'ffi', use \xHH escapes
|
diff --git a/src/test/ui/attributes/unused-item-in-attr.rs b/src/test/ui/attributes/unused-item-in-attr.rs
new file mode 100644
index 000000000..70dcd5413
--- /dev/null
+++ b/src/test/ui/attributes/unused-item-in-attr.rs
@@ -0,0 +1,6 @@
+#[w = { extern crate alloc; }]
+//~^ ERROR unexpected expression: `{
+//~| ERROR cannot find attribute `w` in this scope
+fn f() {}
+
+fn main() {}
diff --git a/src/test/ui/attributes/unused-item-in-attr.stderr b/src/test/ui/attributes/unused-item-in-attr.stderr
new file mode 100644
index 000000000..92a8f5858
--- /dev/null
+++ b/src/test/ui/attributes/unused-item-in-attr.stderr
@@ -0,0 +1,16 @@
+error: unexpected expression: `{
+ extern crate alloc;
+ }`
+ --> $DIR/unused-item-in-attr.rs:1:7
+ |
+LL | #[w = { extern crate alloc; }]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: cannot find attribute `w` in this scope
+ --> $DIR/unused-item-in-attr.rs:1:3
+ |
+LL | #[w = { extern crate alloc; }]
+ | ^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/auto-traits/bad-generics-on-dyn.rs b/src/test/ui/auto-traits/bad-generics-on-dyn.rs
new file mode 100644
index 000000000..3f8ac14c7
--- /dev/null
+++ b/src/test/ui/auto-traits/bad-generics-on-dyn.rs
@@ -0,0 +1,11 @@
+#![feature(auto_traits)]
+
+auto trait Trait1<'a> {}
+//~^ ERROR auto traits cannot have generic parameters
+
+fn f<'a>(x: &dyn Trait1<'a>)
+{}
+
+fn main() {
+ f(&1);
+}
diff --git a/src/test/ui/auto-traits/bad-generics-on-dyn.stderr b/src/test/ui/auto-traits/bad-generics-on-dyn.stderr
new file mode 100644
index 000000000..ade69ced6
--- /dev/null
+++ b/src/test/ui/auto-traits/bad-generics-on-dyn.stderr
@@ -0,0 +1,11 @@
+error[E0567]: auto traits cannot have generic parameters
+ --> $DIR/bad-generics-on-dyn.rs:3:18
+ |
+LL | auto trait Trait1<'a> {}
+ | ------^^^^ help: remove the parameters
+ | |
+ | auto trait cannot have generic parameters
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0567`.
diff --git a/src/test/ui/binding/issue-53114-borrow-checks.stderr b/src/test/ui/binding/issue-53114-borrow-checks.stderr
index 489bf70d9..0ec2ae883 100644
--- a/src/test/ui/binding/issue-53114-borrow-checks.stderr
+++ b/src/test/ui/binding/issue-53114-borrow-checks.stderr
@@ -17,6 +17,10 @@ LL | match mm { (_, _y) => { } }
| ^^ value used here after partial move
|
= note: partial move occurs because `mm.0` has type `M`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | match mm { (ref _x, _) => { } }
+ | +++
error[E0382]: use of partially moved value: `mm`
--> $DIR/issue-53114-borrow-checks.rs:29:11
@@ -28,6 +32,10 @@ LL | match mm { (_, _) => { } }
| ^^ value used here after partial move
|
= note: partial move occurs because `mm.1` has type `M`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | match mm { (_, ref _y) => { } }
+ | +++
error[E0382]: use of moved value: `m`
--> $DIR/issue-53114-borrow-checks.rs:36:16
@@ -48,6 +56,10 @@ LL | if let (_, _y) = mm { }
| ^^ value used here after partial move
|
= note: partial move occurs because `mm.0` has type `M`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | if let (ref _x, _) = mm { }
+ | +++
error[E0382]: use of partially moved value: `mm`
--> $DIR/issue-53114-borrow-checks.rs:43:21
@@ -59,6 +71,10 @@ LL | if let (_, _) = mm { }
| ^^ value used here after partial move
|
= note: partial move occurs because `mm.1` has type `M`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | if let (_, ref _y) = mm { }
+ | +++
error: aborting due to 6 previous errors
diff --git a/src/test/ui/binop/binop-move-semantics.stderr b/src/test/ui/binop/binop-move-semantics.stderr
index 695b01d5e..994eaf9d8 100644
--- a/src/test/ui/binop/binop-move-semantics.stderr
+++ b/src/test/ui/binop/binop-move-semantics.stderr
@@ -32,6 +32,10 @@ LL | +
LL | x.clone();
| ^^^^^^^^^ value borrowed here after move
|
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | x.clone()
+ | ++++++++
help: consider further restricting this bound
|
LL | fn move_then_borrow<T: Add<Output=()> + Clone + Copy>(x: T) {
diff --git a/src/test/ui/binop/binop-mul-i32-f32.stderr b/src/test/ui/binop/binop-mul-i32-f32.stderr
index 21c490965..c986bc3fd 100644
--- a/src/test/ui/binop/binop-mul-i32-f32.stderr
+++ b/src/test/ui/binop/binop-mul-i32-f32.stderr
@@ -6,15 +6,10 @@ LL | x * y
|
= help: the trait `Mul<f32>` is not implemented for `i32`
= help: the following other types implement trait `Mul<Rhs>`:
- <&'a f32 as Mul<f32>>
- <&'a f64 as Mul<f64>>
- <&'a i128 as Mul<i128>>
- <&'a i16 as Mul<i16>>
<&'a i32 as Mul<i32>>
- <&'a i64 as Mul<i64>>
- <&'a i8 as Mul<i8>>
- <&'a isize as Mul<isize>>
- and 49 others
+ <&i32 as Mul<&i32>>
+ <i32 as Mul<&i32>>
+ <i32 as Mul>
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/async-reference-generality.rs b/src/test/ui/borrowck/async-reference-generality.rs
new file mode 100644
index 000000000..487d1ac81
--- /dev/null
+++ b/src/test/ui/borrowck/async-reference-generality.rs
@@ -0,0 +1,35 @@
+// check-fail
+// known-bug: #99492
+// edition: 2021
+
+use std::marker::PhantomData;
+
+pub struct Struct<I, T>(PhantomData<fn() -> <Self as It>::Item>)
+where
+ Self: It;
+
+impl<I> It for Struct<I, I::Item>
+where
+ I: It,
+{
+ type Item = ();
+}
+
+pub trait It {
+ type Item;
+}
+
+fn f() -> impl Send {
+ async {
+ let _x = Struct::<Empty<&'static ()>, _>(PhantomData);
+ async {}.await;
+ }
+}
+
+pub struct Empty<T>(PhantomData<fn() -> T>);
+
+impl<T> It for Empty<T> {
+ type Item = T;
+}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/async-reference-generality.stderr b/src/test/ui/borrowck/async-reference-generality.stderr
new file mode 100644
index 000000000..af720ad29
--- /dev/null
+++ b/src/test/ui/borrowck/async-reference-generality.stderr
@@ -0,0 +1,27 @@
+error[E0308]: mismatched types
+ --> $DIR/async-reference-generality.rs:23:5
+ |
+LL | / async {
+LL | | let _x = Struct::<Empty<&'static ()>, _>(PhantomData);
+LL | | async {}.await;
+LL | | }
+ | |_____^ one type is more general than the other
+ |
+ = note: expected reference `&()`
+ found reference `&()`
+
+error[E0308]: mismatched types
+ --> $DIR/async-reference-generality.rs:23:5
+ |
+LL | / async {
+LL | | let _x = Struct::<Empty<&'static ()>, _>(PhantomData);
+LL | | async {}.await;
+LL | | }
+ | |_____^ one type is more general than the other
+ |
+ = note: expected reference `&()`
+ found reference `&()`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr b/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr
index 1fd1eb128..50eee1049 100644
--- a/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr
+++ b/src/test/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr
@@ -27,6 +27,11 @@ LL | a @ [.., _] => (),
...
LL | &x;
| ^^ value borrowed here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref a @ [.., _] => (),
+ | +++
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:28:5
@@ -71,13 +76,15 @@ LL | fn bindings_after_at_or_patterns_move(x: Option<Test>) {
| - move occurs because `x` has type `Option<Test>`, which does not implement the `Copy` trait
LL | match x {
LL | foo @ Some(Test::Foo | Test::Bar) => (),
- | ---
- | |
- | value moved here
- | value moved here
+ | --- value moved here
...
LL | &x;
| ^^ value borrowed here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref foo @ Some(Test::Foo | Test::Bar) => (),
+ | +++
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:86:5
@@ -122,13 +129,15 @@ LL | fn bindings_after_at_slice_patterns_or_patterns_moves(x: [Option<Test>; 4])
| - move occurs because `x` has type `[Option<Test>; 4]`, which does not implement the `Copy` trait
LL | match x {
LL | a @ [.., Some(Test::Foo | Test::Bar)] => (),
- | -
- | |
- | value moved here
- | value moved here
+ | - value moved here
...
LL | &x;
| ^^ value borrowed here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref a @ [.., Some(Test::Foo | Test::Bar)] => (),
+ | +++
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
--> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:144:5
diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs
index e2f016614..a3350024e 100644
--- a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs
+++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs
@@ -1,4 +1,4 @@
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, tuple_trait)]
// Tests that we can't assign to or mutably borrow upvars from `Fn`
// closures (issue #17780)
@@ -7,10 +7,10 @@ fn set(x: &mut usize) {
*x = 5;
}
-fn to_fn<A, F: Fn<A>>(f: F) -> F {
+fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
f
}
-fn to_fn_mut<A, F: FnMut<A>>(f: F) -> F {
+fn to_fn_mut<A: std::marker::Tuple, F: FnMut<A>>(f: F) -> F {
f
}
diff --git a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr
index 093589ed0..a0eaf1f16 100644
--- a/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr
+++ b/src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr
@@ -1,8 +1,8 @@
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:21:27
|
-LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
- | - change this to accept `FnMut` instead of `Fn`
+LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
+ | - change this to accept `FnMut` instead of `Fn`
...
LL | let _f = to_fn(|| x = 42);
| ----- -- ^^^^^^ cannot assign
@@ -13,8 +13,8 @@ LL | let _f = to_fn(|| x = 42);
error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:24:31
|
-LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
- | - change this to accept `FnMut` instead of `Fn`
+LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
+ | - change this to accept `FnMut` instead of `Fn`
...
LL | let _g = to_fn(|| set(&mut y));
| ----- -- ^^^^^^ cannot borrow as mutable
@@ -25,8 +25,8 @@ LL | let _g = to_fn(|| set(&mut y));
error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:29:22
|
-LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
- | - change this to accept `FnMut` instead of `Fn`
+LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
+ | - change this to accept `FnMut` instead of `Fn`
...
LL | to_fn(|| z = 42);
| ----- -- ^^^^^^ cannot assign
@@ -37,8 +37,8 @@ LL | to_fn(|| z = 42);
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:36:32
|
-LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
- | - change this to accept `FnMut` instead of `Fn`
+LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
+ | - change this to accept `FnMut` instead of `Fn`
...
LL | let _f = to_fn(move || x = 42);
| ----- ------- ^^^^^^ cannot assign
@@ -49,8 +49,8 @@ LL | let _f = to_fn(move || x = 42);
error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:39:36
|
-LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
- | - change this to accept `FnMut` instead of `Fn`
+LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
+ | - change this to accept `FnMut` instead of `Fn`
...
LL | let _g = to_fn(move || set(&mut y));
| ----- ------- ^^^^^^ cannot borrow as mutable
@@ -61,8 +61,8 @@ LL | let _g = to_fn(move || set(&mut y));
error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-immutable-upvar-mutation.rs:44:27
|
-LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
- | - change this to accept `FnMut` instead of `Fn`
+LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
+ | - change this to accept `FnMut` instead of `Fn`
...
LL | to_fn(move || z = 42);
| ----- ------- ^^^^^^ cannot assign
diff --git a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr
index a6af129bf..4eeec09b9 100644
--- a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr
+++ b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let x = defer(&vec!["Goodbye", "world!"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
LL | x.x[0];
| ------ borrow later used here
|
diff --git a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr
index dea8ac90b..c62d5f903 100644
--- a/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr
+++ b/src/test/ui/borrowck/borrowck-borrowed-uniq-rvalue.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | buggy_map.insert(42, &*Box::new(1));
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | buggy_map.insert(43, &*tmp);
| --------------------------- borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-consume-unsize-vec.stderr b/src/test/ui/borrowck/borrowck-consume-unsize-vec.stderr
index 17b931066..d2e9497d0 100644
--- a/src/test/ui/borrowck/borrowck-consume-unsize-vec.stderr
+++ b/src/test/ui/borrowck/borrowck-consume-unsize-vec.stderr
@@ -7,6 +7,18 @@ LL | consume(b);
| - value moved here
LL | consume(b);
| ^ value used here after move
+ |
+note: consider changing this parameter type in function `consume` to borrow instead if owning the value isn't necessary
+ --> $DIR/borrowck-consume-unsize-vec.rs:3:15
+ |
+LL | fn consume(_: Box<[i32]>) {
+ | ------- ^^^^^^^^^^ this parameter takes ownership of the value
+ | |
+ | in this function
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | consume(b.clone());
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-consume-upcast-box.stderr b/src/test/ui/borrowck/borrowck-consume-upcast-box.stderr
index 4e20bbf17..ed7e883ca 100644
--- a/src/test/ui/borrowck/borrowck-consume-upcast-box.stderr
+++ b/src/test/ui/borrowck/borrowck-consume-upcast-box.stderr
@@ -7,6 +7,14 @@ LL | consume(b);
| - value moved here
LL | consume(b);
| ^ value used here after move
+ |
+note: consider changing this parameter type in function `consume` to borrow instead if owning the value isn't necessary
+ --> $DIR/borrowck-consume-upcast-box.rs:5:15
+ |
+LL | fn consume(_: Box<dyn Foo>) {
+ | ------- ^^^^^^^^^^^^ this parameter takes ownership of the value
+ | |
+ | in this function
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-drop-from-guard.stderr b/src/test/ui/borrowck/borrowck-drop-from-guard.stderr
index cd0d2fee9..eaf4bb38b 100644
--- a/src/test/ui/borrowck/borrowck-drop-from-guard.stderr
+++ b/src/test/ui/borrowck/borrowck-drop-from-guard.stderr
@@ -9,6 +9,11 @@ LL | Some(_) if { drop(my_str); false } => {}
LL | Some(_) => {}
LL | None => { foo(my_str); }
| ^^^^^^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | Some(_) if { drop(my_str.clone()); false } => {}
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-loan-in-overloaded-op.stderr b/src/test/ui/borrowck/borrowck-loan-in-overloaded-op.stderr
index 0dd720ff6..e1b991620 100644
--- a/src/test/ui/borrowck/borrowck-loan-in-overloaded-op.stderr
+++ b/src/test/ui/borrowck/borrowck-loan-in-overloaded-op.stderr
@@ -7,6 +7,11 @@ LL | let _y = {x} + x.clone(); // the `{x}` forces a move to occur
| - ^^^^^^^^^ value borrowed here after move
| |
| value moved here
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _y = {x.clone()} + x.clone(); // the `{x}` forces a move to occur
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-move-by-capture.rs b/src/test/ui/borrowck/borrowck-move-by-capture.rs
index f26edef17..6f0eb1870 100644
--- a/src/test/ui/borrowck/borrowck-move-by-capture.rs
+++ b/src/test/ui/borrowck/borrowck-move-by-capture.rs
@@ -1,7 +1,7 @@
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, tuple_trait)]
-fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
-fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
+fn to_fn_mut<A:std::marker::Tuple,F:FnMut<A>>(f: F) -> F { f }
+fn to_fn_once<A:std::marker::Tuple,F:FnOnce<A>>(f: F) -> F { f }
pub fn main() {
let bar: Box<_> = Box::new(3);
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr
index 346b82a26..67b00c1dd 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr
@@ -8,6 +8,10 @@ LL | [.., _y] => {}
| ^^ value used here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, ref _x] => {}
+ | +++
error[E0382]: use of partially moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-match.rs:23:14
@@ -19,6 +23,10 @@ LL | [.., _y] => {}
| ^^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, (ref _x, _)] => {}
+ | +++
error[E0382]: use of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array-match.rs:33:15
@@ -30,6 +38,10 @@ LL | [.., (_y, _)] => {}
| ^^ value used here after move
|
= note: move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, (ref _x, _)] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-match.rs:44:11
@@ -41,6 +53,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref _x, _, _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-match.rs:55:11
@@ -52,6 +68,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [.., ref _x] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-match.rs:66:11
@@ -63,6 +83,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [(ref _x, _), _, _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-match.rs:77:11
@@ -74,6 +98,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [.., (ref _x, _)] => {}
+ | +++
error[E0382]: use of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array-match.rs:89:11
@@ -85,6 +113,10 @@ LL | [(_x, _), _, _] => {}
| ^^ value used here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref _y @ .., _, _] => {}
+ | +++
error[E0382]: use of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array-match.rs:99:15
@@ -96,6 +128,10 @@ LL | [.., (_x, _)] => {}
| ^^ value used here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, ref _y @ ..] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-match.rs:110:11
@@ -107,6 +143,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref x @ .., _] => {}
+ | +++
error: aborting due to 10 previous errors
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
index 6c6a25c25..47429ea3e 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
@@ -8,6 +8,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, ref _x] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:28:11
@@ -19,6 +23,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, (ref _x, _)] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:41:11
@@ -30,6 +38,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref _x, _, _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:52:11
@@ -41,6 +53,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [.., ref _x] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:63:11
@@ -52,6 +68,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [(ref _x, _), _, _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:74:11
@@ -63,6 +83,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [.., (ref _x, _)] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:85:11
@@ -74,6 +98,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, ref _y @ ..] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:96:11
@@ -85,6 +113,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref _y @ .., _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:109:11
@@ -96,6 +128,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref x @ .., _, _] => {}
+ | +++
error: aborting due to 9 previous errors
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
index 77702e145..bfab13d42 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
@@ -8,6 +8,10 @@ LL | [.., ref _y] => {}
| ^^^^^^ value borrowed here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, ref _x] => {}
+ | +++
error[E0382]: borrow of partially moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-use-match.rs:23:14
@@ -19,6 +23,10 @@ LL | [.., ref _y] => {}
| ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, (ref _x, _)] => {}
+ | +++
error[E0382]: borrow of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array-use-match.rs:33:15
@@ -30,6 +38,10 @@ LL | [.., (ref _y, _)] => {}
| ^^^^^^ value borrowed here after move
|
= note: move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, (ref _x, _)] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:44:11
@@ -41,6 +53,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref _x, _, _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:55:11
@@ -52,6 +68,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [.., ref _x] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:66:11
@@ -63,6 +83,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [(ref _x, _), _, _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:77:11
@@ -74,6 +98,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [.., (ref _x, _)] => {}
+ | +++
error[E0382]: borrow of moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-use-match.rs:89:11
@@ -85,6 +113,10 @@ LL | [(ref _x, _), _, _] => {}
| ^^^^^^ value borrowed here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref _y @ .., _, _] => {}
+ | +++
error[E0382]: borrow of moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-use-match.rs:99:15
@@ -96,6 +128,10 @@ LL | [.., (ref _x, _)] => {}
| ^^^^^^ value borrowed here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, ref _y @ ..] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:110:11
@@ -107,6 +143,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref x @ .., _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:123:5
@@ -118,6 +158,10 @@ LL | a[2] = Default::default();
| ^^^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, ref _x] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:131:5
@@ -129,6 +173,10 @@ LL | a[2].1 = Default::default();
| ^^^^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, (ref _x, _)] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:139:5
@@ -140,6 +188,10 @@ LL | a[0] = Default::default();
| ^^^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, ref _x @ ..] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-match.rs:147:5
@@ -151,6 +203,10 @@ LL | a[0].1 = Default::default();
| ^^^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, ref _x @ ..] => {}
+ | +++
error: aborting due to 14 previous errors
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
index 6cc2c2f7a..8412c24fe 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
@@ -8,6 +8,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, ref _x] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:28:11
@@ -19,6 +23,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, _, (ref _x, _)] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:41:11
@@ -30,6 +38,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref _x, _, _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:52:11
@@ -41,6 +53,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [.., ref _x] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:63:11
@@ -52,6 +68,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [(ref _x, _), _, _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:74:11
@@ -63,6 +83,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [.., (ref _x, _)] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:85:11
@@ -74,6 +98,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [_, ref _y @ ..] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:96:11
@@ -85,6 +113,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref _y @ .., _] => {}
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:109:11
@@ -96,6 +128,10 @@ LL | match a {
| ^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | [ref x @ .., _, _] => {}
+ | +++
error: aborting due to 9 previous errors
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr
index 9add7553a..e2aeaafc6 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr
@@ -7,6 +7,10 @@ LL | let [.., ref _y] = a;
| ^^^^^^ value borrowed here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, ref _x] = a;
+ | +++
error[E0382]: borrow of partially moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-use.rs:16:14
@@ -17,6 +21,10 @@ LL | let [.., ref _y] = a;
| ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, (ref _x, _)] = a;
+ | +++
error[E0382]: borrow of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array-use.rs:22:15
@@ -27,6 +35,10 @@ LL | let [.., (ref _y, _)] = a;
| ^^^^^^ value borrowed here after move
|
= note: move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, (ref _x, _)] = a;
+ | +++
error[E0382]: borrow of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:30:10
@@ -37,6 +49,10 @@ LL | let [ref _y @ .., _, _] = a;
| ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [ref _x, _, _] = a;
+ | +++
error[E0382]: borrow of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:36:16
@@ -47,6 +63,10 @@ LL | let [_, _, ref _y @ ..] = a;
| ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [.., ref _x] = a;
+ | +++
error[E0382]: borrow of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:42:10
@@ -57,6 +77,10 @@ LL | let [ref _y @ .., _, _] = a;
| ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [(ref _x, _), _, _] = a;
+ | +++
error[E0382]: borrow of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:48:16
@@ -67,6 +91,10 @@ LL | let [_, _, ref _y @ ..] = a;
| ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [.., (ref _x, _)] = a;
+ | +++
error[E0382]: borrow of moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-use.rs:54:11
@@ -77,6 +105,10 @@ LL | let [(ref _x, _), _, _] = a;
| ^^^^^^ value borrowed here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [ref _y @ .., _, _] = a;
+ | +++
error[E0382]: borrow of moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array-use.rs:60:15
@@ -87,6 +119,10 @@ LL | let [.., (ref _x, _)] = a;
| ^^^^^^ value borrowed here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, ref _y @ ..] = a;
+ | +++
error[E0382]: borrow of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:68:13
@@ -97,6 +133,10 @@ LL | let [_, ref _y @ ..] = a;
| ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [ref x @ .., _] = a;
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:76:5
@@ -107,6 +147,10 @@ LL | a[2] = Default::default();
| ^^^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, ref _x] = a;
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:82:5
@@ -117,6 +161,10 @@ LL | a[2].1 = Default::default();
| ^^^^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, (ref _x, _)] = a;
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:88:5
@@ -127,6 +175,10 @@ LL | a[0] = Default::default();
| ^^^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, ref _x @ ..] = a;
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array-use.rs:94:5
@@ -137,6 +189,10 @@ LL | a[0].1 = Default::default();
| ^^^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, ref _x @ ..] = a;
+ | +++
error: aborting due to 14 previous errors
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
index 363effcfe..dd456681f 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
@@ -7,6 +7,10 @@ LL | let [.., _y] = a;
| ^^ value used here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, ref _x] = a;
+ | +++
error[E0382]: use of partially moved value: `a[..]`
--> $DIR/borrowck-move-out-from-array.rs:16:14
@@ -17,6 +21,10 @@ LL | let [.., _y] = a;
| ^^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, (ref _x, _)] = a;
+ | +++
error[E0382]: use of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array.rs:22:15
@@ -27,6 +35,10 @@ LL | let [.., (_y, _)] = a;
| ^^ value used here after move
|
= note: move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, (ref _x, _)] = a;
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array.rs:30:10
@@ -37,6 +49,10 @@ LL | let [_y @ .., _, _] = a;
| ^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [ref _x, _, _] = a;
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array.rs:36:16
@@ -47,6 +63,10 @@ LL | let [_, _, _y @ ..] = a;
| ^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [.., ref _x] = a;
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array.rs:42:10
@@ -57,6 +77,10 @@ LL | let [_y @ .., _, _] = a;
| ^^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [(ref _x, _), _, _] = a;
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array.rs:48:16
@@ -67,6 +91,10 @@ LL | let [_, _, _y @ ..] = a;
| ^^ value used here after partial move
|
= note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [.., (ref _x, _)] = a;
+ | +++
error[E0382]: use of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array.rs:54:11
@@ -77,6 +105,10 @@ LL | let [(_x, _), _, _] = a;
| ^^ value used here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [ref _y @ .., _, _] = a;
+ | +++
error[E0382]: use of moved value: `a[..].0`
--> $DIR/borrowck-move-out-from-array.rs:60:15
@@ -87,6 +119,10 @@ LL | let [.., (_x, _)] = a;
| ^^ value used here after move
|
= note: move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [_, _, ref _y @ ..] = a;
+ | +++
error[E0382]: use of partially moved value: `a`
--> $DIR/borrowck-move-out-from-array.rs:68:13
@@ -97,6 +133,10 @@ LL | let [_, _y @ ..] = a;
| ^^ value used here after partial move
|
= note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let [ref x @ .., _] = a;
+ | +++
error: aborting due to 10 previous errors
diff --git a/src/test/ui/borrowck/borrowck-multiple-captures.stderr b/src/test/ui/borrowck/borrowck-multiple-captures.stderr
index 86d2955e2..f94cbc30d 100644
--- a/src/test/ui/borrowck/borrowck-multiple-captures.stderr
+++ b/src/test/ui/borrowck/borrowck-multiple-captures.stderr
@@ -40,6 +40,11 @@ LL | thread::spawn(move|| {
...
LL | drop(x1);
| -- use occurs due to use in closure
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | drop(x1.clone());
+ | ++++++++
error[E0382]: use of moved value: `x2`
--> $DIR/borrowck-multiple-captures.rs:27:19
@@ -53,6 +58,11 @@ LL | thread::spawn(move|| {
...
LL | drop(x2);
| -- use occurs due to use in closure
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | drop(x2.clone());
+ | ++++++++
error[E0382]: use of moved value: `x`
--> $DIR/borrowck-multiple-captures.rs:41:14
@@ -100,6 +110,11 @@ LL | thread::spawn(move|| {
LL |
LL | drop(x);
| - use occurs due to use in closure
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | drop(x.clone());
+ | ++++++++
error: aborting due to 8 previous errors
diff --git a/src/test/ui/borrowck/borrowck-overloaded-index-move-index.stderr b/src/test/ui/borrowck/borrowck-overloaded-index-move-index.stderr
index e01c26adc..fb0e274c2 100644
--- a/src/test/ui/borrowck/borrowck-overloaded-index-move-index.stderr
+++ b/src/test/ui/borrowck/borrowck-overloaded-index-move-index.stderr
@@ -33,6 +33,11 @@ LL | println!("{}", f[s]);
...
LL | f[s] = 10;
| ^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | println!("{}", f[s.clone()]);
+ | ++++++++
error: aborting due to 3 previous errors
diff --git a/src/test/ui/borrowck/borrowck-reinit.stderr b/src/test/ui/borrowck/borrowck-reinit.stderr
index 22253cd96..f785900d5 100644
--- a/src/test/ui/borrowck/borrowck-reinit.stderr
+++ b/src/test/ui/borrowck/borrowck-reinit.stderr
@@ -8,6 +8,11 @@ LL | drop(x);
| - value moved here
LL | let _ = (1,x);
| ^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | drop(x.clone());
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/issue-11493.stderr b/src/test/ui/borrowck/issue-11493.stderr
index a5d1f2816..2720b09b0 100644
--- a/src/test/ui/borrowck/issue-11493.stderr
+++ b/src/test/ui/borrowck/issue-11493.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let y = x.as_ref().unwrap_or(&id(5));
| ^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
LL | let _ = &y;
| -- borrow later used here
|
diff --git a/src/test/ui/borrowck/issue-17545.stderr b/src/test/ui/borrowck/issue-17545.stderr
index 79a1e09bd..3ae7e64d2 100644
--- a/src/test/ui/borrowck/issue-17545.stderr
+++ b/src/test/ui/borrowck/issue-17545.stderr
@@ -5,7 +5,7 @@ LL | pub fn foo<'a, F: Fn(&'a ())>(bar: F) {
| -- lifetime `'a` defined here
LL | / bar.call((
LL | | &id(()),
- | | ^^^^^^ creates a temporary which is freed while still in use
+ | | ^^^^^^ creates a temporary value which is freed while still in use
LL | | ));
| | -- temporary value is freed at the end of this statement
| |______|
diff --git a/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr b/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr
index d33115988..ad898fcab 100644
--- a/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr
+++ b/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr
@@ -8,6 +8,11 @@ LL | Some(_) if { drop(a); false } => None,
| - value moved here
LL | x => x,
| ^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | Some(_) if { drop(a.clone()); false } => None,
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/issue-36082.fixed b/src/test/ui/borrowck/issue-36082.fixed
index 8640ca7a5..8fc963a85 100644
--- a/src/test/ui/borrowck/issue-36082.fixed
+++ b/src/test/ui/borrowck/issue-36082.fixed
@@ -10,7 +10,7 @@ fn main() {
let val: &_ = binding.0;
//~^ ERROR temporary value dropped while borrowed [E0716]
//~| NOTE temporary value is freed at the end of this statement
- //~| NOTE creates a temporary which is freed while still in use
+ //~| NOTE creates a temporary value which is freed while still in use
//~| HELP consider using a `let` binding to create a longer lived value
println!("{}", val);
//~^ borrow later used here
diff --git a/src/test/ui/borrowck/issue-36082.rs b/src/test/ui/borrowck/issue-36082.rs
index 877d372fb..20f66b4d4 100644
--- a/src/test/ui/borrowck/issue-36082.rs
+++ b/src/test/ui/borrowck/issue-36082.rs
@@ -9,7 +9,7 @@ fn main() {
let val: &_ = x.borrow().0;
//~^ ERROR temporary value dropped while borrowed [E0716]
//~| NOTE temporary value is freed at the end of this statement
- //~| NOTE creates a temporary which is freed while still in use
+ //~| NOTE creates a temporary value which is freed while still in use
//~| HELP consider using a `let` binding to create a longer lived value
println!("{}", val);
//~^ borrow later used here
diff --git a/src/test/ui/borrowck/issue-36082.stderr b/src/test/ui/borrowck/issue-36082.stderr
index 4bd586db1..a6357f818 100644
--- a/src/test/ui/borrowck/issue-36082.stderr
+++ b/src/test/ui/borrowck/issue-36082.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let val: &_ = x.borrow().0;
| ^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | println!("{}", val);
| --- borrow later used here
diff --git a/src/test/ui/borrowck/issue-41962.stderr b/src/test/ui/borrowck/issue-41962.stderr
index b20cc6d8c..716cc9d0c 100644
--- a/src/test/ui/borrowck/issue-41962.stderr
+++ b/src/test/ui/borrowck/issue-41962.stderr
@@ -5,7 +5,7 @@ LL | if let Some(thing) = maybe {
| ^^^^^ value moved here, in previous iteration of loop
|
= note: move occurs because value has type `Vec<bool>`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `maybe.0`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | if let Some(ref thing) = maybe {
| +++
diff --git a/src/test/ui/borrowck/issue-81899.rs b/src/test/ui/borrowck/issue-81899.rs
index 24b20b650..1f1af5c7e 100644
--- a/src/test/ui/borrowck/issue-81899.rs
+++ b/src/test/ui/borrowck/issue-81899.rs
@@ -2,13 +2,14 @@
// The `panic!()` below is important to trigger the fixed ICE.
const _CONST: &[u8] = &f(&[], |_| {});
-//~^ ERROR constant
+//~^ constant
const fn f<F>(_: &[u8], _: F) -> &[u8]
where
F: FnMut(&u8),
{
- panic!() //~ ERROR: evaluation of constant value failed
+ panic!() //~ ERROR evaluation of constant value failed
+ //~^ panic
}
fn main() {}
diff --git a/src/test/ui/borrowck/issue-81899.stderr b/src/test/ui/borrowck/issue-81899.stderr
index 12e80b9df..1b03bc3af 100644
--- a/src/test/ui/borrowck/issue-81899.stderr
+++ b/src/test/ui/borrowck/issue-81899.stderr
@@ -1,23 +1,27 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-81899.rs:11:5
|
-LL | const _CONST: &[u8] = &f(&[], |_| {});
- | -------------- inside `_CONST` at $DIR/issue-81899.rs:4:24
-...
+LL | panic!()
+ | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-81899.rs:11:5
+ |
+note: inside `f::<[closure@$DIR/issue-81899.rs:4:31: 4:34]>`
+ --> $DIR/issue-81899.rs:11:5
+ |
LL | panic!()
| ^^^^^^^^
- | |
- | the evaluated program panicked at 'explicit panic', $DIR/issue-81899.rs:11:5
- | inside `f::<[closure@$DIR/issue-81899.rs:4:31: 4:34]>` at $SRC_DIR/std/src/panic.rs:LL:COL
+note: inside `_CONST`
+ --> $DIR/issue-81899.rs:4:24
|
+LL | const _CONST: &[u8] = &f(&[], |_| {});
+ | ^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-81899.rs:4:23
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
- | ^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs
index 2c8a700bc..dd0320bc5 100644
--- a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs
+++ b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs
@@ -17,7 +17,6 @@ async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> {
//~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
//~^^ ERROR this struct takes 1 generic argument but 0 generic arguments were supplied
LockedMarket(generator.lock().unwrap().buy())
- //~^ ERROR cannot return value referencing temporary
}
struct LockedMarket<T>(T);
diff --git a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr
index 4bd066730..d2b927fb6 100644
--- a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr
+++ b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr
@@ -7,7 +7,7 @@ LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_>
| expected 0 lifetime arguments
|
note: struct defined here, with 0 lifetime parameters
- --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8
+ --> $DIR/issue-82126-mismatched-subst-and-hir.rs:22:8
|
LL | struct LockedMarket<T>(T);
| ^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_>
| ^^^^^^^^^^^^ expected 1 generic argument
|
note: struct defined here, with 1 generic parameter: `T`
- --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8
+ --> $DIR/issue-82126-mismatched-subst-and-hir.rs:22:8
|
LL | struct LockedMarket<T>(T);
| ^^^^^^^^^^^^ -
@@ -28,16 +28,6 @@ help: add missing generic argument
LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_, T> {
| +++
-error[E0515]: cannot return value referencing temporary value
- --> $DIR/issue-82126-mismatched-subst-and-hir.rs:19:5
- |
-LL | LockedMarket(generator.lock().unwrap().buy())
- | ^^^^^^^^^^^^^-------------------------^^^^^^^
- | | |
- | | temporary value created here
- | returns a value referencing data owned by the current function
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0107, E0515.
-For more information about an error, try `rustc --explain E0107`.
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/borrowck/issue-83760.stderr b/src/test/ui/borrowck/issue-83760.stderr
index beeda5685..2552fff86 100644
--- a/src/test/ui/borrowck/issue-83760.stderr
+++ b/src/test/ui/borrowck/issue-83760.stderr
@@ -8,6 +8,10 @@ LL | val = None;
| ---------- this reinitialization might get skipped
|
= note: move occurs because value has type `Struct`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | while let Some(ref foo) = val {
+ | +++
error[E0382]: use of moved value: `foo`
--> $DIR/issue-83760.rs:21:14
diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.rs b/src/test/ui/borrowck/issue-88434-minimal-example.rs
index 983a02310..b75abcb73 100644
--- a/src/test/ui/borrowck/issue-88434-minimal-example.rs
+++ b/src/test/ui/borrowck/issue-88434-minimal-example.rs
@@ -1,13 +1,14 @@
// Regression test related to issue 88434
const _CONST: &() = &f(&|_| {});
-//~^ ERROR constant
+//~^ constant
const fn f<F>(_: &F)
where
F: FnMut(&u8),
{
panic!() //~ ERROR evaluation of constant value failed
+ //~^ panic
}
fn main() { }
diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.stderr b/src/test/ui/borrowck/issue-88434-minimal-example.stderr
index dc87c4c2b..a5a571c6d 100644
--- a/src/test/ui/borrowck/issue-88434-minimal-example.stderr
+++ b/src/test/ui/borrowck/issue-88434-minimal-example.stderr
@@ -1,23 +1,27 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-88434-minimal-example.rs:10:5
|
-LL | const _CONST: &() = &f(&|_| {});
- | ---------- inside `_CONST` at $DIR/issue-88434-minimal-example.rs:3:22
-...
+LL | panic!()
+ | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:10:5
+ |
+note: inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:28]>`
+ --> $DIR/issue-88434-minimal-example.rs:10:5
+ |
LL | panic!()
| ^^^^^^^^
- | |
- | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:10:5
- | inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:28]>` at $SRC_DIR/std/src/panic.rs:LL:COL
+note: inside `_CONST`
+ --> $DIR/issue-88434-minimal-example.rs:3:22
|
+LL | const _CONST: &() = &f(&|_| {});
+ | ^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-88434-minimal-example.rs:3:21
|
LL | const _CONST: &() = &f(&|_| {});
- | ^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs
index a99c5b76a..f9134e669 100644
--- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs
+++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.rs
@@ -1,13 +1,14 @@
// Regression test for issue 88434
const _CONST: &[u8] = &f(&[], |_| {});
-//~^ ERROR constant
+//~^ constant
const fn f<F>(_: &[u8], _: F) -> &[u8]
where
F: FnMut(&u8),
{
panic!() //~ ERROR evaluation of constant value failed
+ //~^ panic
}
fn main() { }
diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
index 4b4a25d7b..00023c459 100644
--- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
+++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr
@@ -1,23 +1,27 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-88434-removal-index-should-be-less.rs:10:5
|
-LL | const _CONST: &[u8] = &f(&[], |_| {});
- | -------------- inside `_CONST` at $DIR/issue-88434-removal-index-should-be-less.rs:3:24
-...
+LL | panic!()
+ | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:10:5
+ |
+note: inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34]>`
+ --> $DIR/issue-88434-removal-index-should-be-less.rs:10:5
+ |
LL | panic!()
| ^^^^^^^^
- | |
- | the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:10:5
- | inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34]>` at $SRC_DIR/std/src/panic.rs:LL:COL
+note: inside `_CONST`
+ --> $DIR/issue-88434-removal-index-should-be-less.rs:3:24
|
+LL | const _CONST: &[u8] = &f(&[], |_| {});
+ | ^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-88434-removal-index-should-be-less.rs:3:23
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
- | ^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/borrowck/move-in-pattern-mut-in-loop.stderr b/src/test/ui/borrowck/move-in-pattern-mut-in-loop.stderr
index c6931ba72..55948afca 100644
--- a/src/test/ui/borrowck/move-in-pattern-mut-in-loop.stderr
+++ b/src/test/ui/borrowck/move-in-pattern-mut-in-loop.stderr
@@ -5,7 +5,7 @@ LL | if let Some(mut _x) = opt {}
| ^^^^^^ value moved here, in previous iteration of loop
|
= note: move occurs because value has type `&mut i32`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `opt.0`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | if let Some(ref mut _x) = opt {}
| +++
diff --git a/src/test/ui/borrowck/move-in-pattern-mut.stderr b/src/test/ui/borrowck/move-in-pattern-mut.stderr
index 2bf34b321..dd3471e2c 100644
--- a/src/test/ui/borrowck/move-in-pattern-mut.stderr
+++ b/src/test/ui/borrowck/move-in-pattern-mut.stderr
@@ -8,7 +8,7 @@ LL | foo(s);
| ^ value used here after partial move
|
= note: partial move occurs because value has type `S`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `s.0`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | if let Some(ref mut x) = s {
| +++
@@ -23,7 +23,7 @@ LL | bar(e);
| ^ value used here after partial move
|
= note: partial move occurs because value has type `S`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `e.s`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | let E::V { s: ref mut x } = e;
| +++
diff --git a/src/test/ui/borrowck/move-in-pattern.stderr b/src/test/ui/borrowck/move-in-pattern.stderr
index 6b84c0032..250acbe59 100644
--- a/src/test/ui/borrowck/move-in-pattern.stderr
+++ b/src/test/ui/borrowck/move-in-pattern.stderr
@@ -8,7 +8,7 @@ LL | foo(s);
| ^ value used here after partial move
|
= note: partial move occurs because value has type `S`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `s.0`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | if let Some(ref x) = s {
| +++
@@ -23,7 +23,7 @@ LL | bar(e);
| ^ value used here after partial move
|
= note: partial move occurs because value has type `S`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `e.s`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | let E::V { s: ref x } = e;
| +++
diff --git a/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr b/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr
index 8b05b2388..74e7067c9 100644
--- a/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr
+++ b/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr
@@ -4,9 +4,17 @@ error[E0382]: use of moved value: `value`
LL | fn this_does_not<'a, R>(value: &'a mut Events<R>) {
| ----- move occurs because `value` has type `&mut Events<R>`, which does not implement the `Copy` trait
LL | for _ in 0..3 {
+ | ------------- inside of this loop
LL | Other::handle(value);
| ^^^^^ value moved here, in previous iteration of loop
|
+note: consider changing this parameter type in function `handle` to borrow instead if owning the value isn't necessary
+ --> $DIR/mut-borrow-in-loop-2.rs:9:22
+ |
+LL | fn handle(value: T) -> Self;
+ | ------ ^ this parameter takes ownership of the value
+ | |
+ | in this function
help: consider creating a fresh reborrow of `value` here
|
LL | Other::handle(&mut *value);
diff --git a/src/test/ui/borrowck/or-patterns.stderr b/src/test/ui/borrowck/or-patterns.stderr
index dd5797c3f..9501798bb 100644
--- a/src/test/ui/borrowck/or-patterns.stderr
+++ b/src/test/ui/borrowck/or-patterns.stderr
@@ -8,6 +8,10 @@ LL | &x.0 .0;
| ^^^^^^^ value borrowed here after move
|
= note: move occurs because `x.0.0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ((ref y, _) | (_, y),) => (),
+ | +++
error[E0382]: borrow of moved value: `x.0.1`
--> $DIR/or-patterns.rs:10:5
@@ -19,6 +23,10 @@ LL | &x.0 .1;
| ^^^^^^^ value borrowed here after move
|
= note: move occurs because `x.0.1` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ((y, _) | (_, ref y),) => (),
+ | +++
error[E0502]: cannot borrow `x.0.0` as mutable because it is also borrowed as immutable
--> $DIR/or-patterns.rs:18:5
@@ -77,6 +85,10 @@ LL | &x.0 .0;
| ^^^^^^^ value borrowed here after move
|
= note: move occurs because `x.0.0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ((ref y, _) | (_, y),) = x;
+ | +++
error[E0382]: borrow of moved value: `x.0.1`
--> $DIR/or-patterns.rs:40:5
@@ -88,6 +100,10 @@ LL | &x.0 .1;
| ^^^^^^^ value borrowed here after move
|
= note: move occurs because `x.0.1` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ((y, _) | (_, ref y),) = x;
+ | +++
error[E0502]: cannot borrow `x.0.0` as mutable because it is also borrowed as immutable
--> $DIR/or-patterns.rs:46:5
diff --git a/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs b/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs
new file mode 100644
index 000000000..087743e50
--- /dev/null
+++ b/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs
@@ -0,0 +1,19 @@
+#![feature(abi_efiapi)]
+
+fn efiapi(f: extern "efiapi" fn(usize, ...)) {
+ //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+ //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+ f(22, 44);
+}
+fn sysv(f: extern "sysv64" fn(usize, ...)) {
+ //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+ //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+ f(22, 44);
+}
+fn win(f: extern "win64" fn(usize, ...)) {
+ //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+ //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+ f(22, 44);
+}
+
+fn main() {}
diff --git a/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr b/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr
new file mode 100644
index 000000000..007d7d795
--- /dev/null
+++ b/src/test/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr
@@ -0,0 +1,49 @@
+error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+ --> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14
+ |
+LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
+ = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
+
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+ --> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14
+ |
+LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+
+error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+ --> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12
+ |
+LL | fn sysv(f: extern "sysv64" fn(usize, ...)) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
+ = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
+
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+ --> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12
+ |
+LL | fn sysv(f: extern "sysv64" fn(usize, ...)) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+
+error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+ --> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11
+ |
+LL | fn win(f: extern "win64" fn(usize, ...)) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
+ = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
+
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+ --> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11
+ |
+LL | fn win(f: extern "win64" fn(usize, ...)) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0045, E0658.
+For more information about an error, try `rustc --explain E0045`.
diff --git a/src/test/ui/c-variadic/issue-86053-1.stderr b/src/test/ui/c-variadic/issue-86053-1.stderr
index 60b379faf..075bd1fc4 100644
--- a/src/test/ui/c-variadic/issue-86053-1.stderr
+++ b/src/test/ui/c-variadic/issue-86053-1.stderr
@@ -66,8 +66,8 @@ LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
-LL | pub trait Fn<Args>: FnMut<Args> {
- | ------------------------------- similarly named trait `Fn` defined here
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | -------------------------------------- similarly named trait `Fn` defined here
|
help: a trait with a similar name exists
|
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.rs b/src/test/ui/c-variadic/variadic-ffi-1.rs
index a76efd9a2..24407a71c 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.rs
+++ b/src/test/ui/c-variadic/variadic-ffi-1.rs
@@ -6,7 +6,9 @@
trait Sized { }
extern "stdcall" {
- fn printf(_: *const u8, ...); //~ ERROR: variadic function must have C or cdecl calling
+ fn printf(_: *const u8, ...);
+ //~^ ERROR: C-variadic function must have a compatible calling convention,
+ // like C, cdecl, win64, sysv64 or efiapi
}
extern "C" {
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.stderr b/src/test/ui/c-variadic/variadic-ffi-1.stderr
index 2ffb80f7e..4beea83d8 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-1.stderr
@@ -1,17 +1,17 @@
-error[E0045]: C-variadic function must have C or cdecl calling convention
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
--> $DIR/variadic-ffi-1.rs:9:5
|
LL | fn printf(_: *const u8, ...);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadics require C or cdecl calling convention
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
error[E0060]: this function takes at least 2 arguments but 0 arguments were supplied
- --> $DIR/variadic-ffi-1.rs:20:9
+ --> $DIR/variadic-ffi-1.rs:22:9
|
LL | foo();
| ^^^-- two arguments of type `isize` and `u8` are missing
|
note: function defined here
- --> $DIR/variadic-ffi-1.rs:13:8
+ --> $DIR/variadic-ffi-1.rs:15:8
|
LL | fn foo(f: isize, x: u8, ...);
| ^^^
@@ -21,13 +21,13 @@ LL | foo(/* isize */, /* u8 */);
| ~~~~~~~~~~~~~~~~~~~~~~~
error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
- --> $DIR/variadic-ffi-1.rs:21:9
+ --> $DIR/variadic-ffi-1.rs:23:9
|
LL | foo(1);
| ^^^--- an argument of type `u8` is missing
|
note: function defined here
- --> $DIR/variadic-ffi-1.rs:13:8
+ --> $DIR/variadic-ffi-1.rs:15:8
|
LL | fn foo(f: isize, x: u8, ...);
| ^^^
@@ -37,7 +37,7 @@ LL | foo(1, /* u8 */);
| ~~~~~~~~~~~~~
error[E0308]: mismatched types
- --> $DIR/variadic-ffi-1.rs:23:56
+ --> $DIR/variadic-ffi-1.rs:25:56
|
LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
| ------------------------------------- ^^^ expected non-variadic fn, found variadic function
@@ -48,7 +48,7 @@ LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
found fn item `unsafe extern "C" fn(_, _, ...) {foo}`
error[E0308]: mismatched types
- --> $DIR/variadic-ffi-1.rs:24:54
+ --> $DIR/variadic-ffi-1.rs:26:54
|
LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar;
| ----------------------------------- ^^^ expected variadic fn, found non-variadic function
@@ -59,37 +59,37 @@ LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar;
found fn item `extern "C" fn(_, _) {bar}`
error[E0617]: can't pass `f32` to variadic function
- --> $DIR/variadic-ffi-1.rs:26:19
+ --> $DIR/variadic-ffi-1.rs:28:19
|
LL | foo(1, 2, 3f32);
| ^^^^ help: cast the value to `c_double`: `3f32 as c_double`
error[E0617]: can't pass `bool` to variadic function
- --> $DIR/variadic-ffi-1.rs:27:19
+ --> $DIR/variadic-ffi-1.rs:29:19
|
LL | foo(1, 2, true);
| ^^^^ help: cast the value to `c_int`: `true as c_int`
error[E0617]: can't pass `i8` to variadic function
- --> $DIR/variadic-ffi-1.rs:28:19
+ --> $DIR/variadic-ffi-1.rs:30:19
|
LL | foo(1, 2, 1i8);
| ^^^ help: cast the value to `c_int`: `1i8 as c_int`
error[E0617]: can't pass `u8` to variadic function
- --> $DIR/variadic-ffi-1.rs:29:19
+ --> $DIR/variadic-ffi-1.rs:31:19
|
LL | foo(1, 2, 1u8);
| ^^^ help: cast the value to `c_uint`: `1u8 as c_uint`
error[E0617]: can't pass `i16` to variadic function
- --> $DIR/variadic-ffi-1.rs:30:19
+ --> $DIR/variadic-ffi-1.rs:32:19
|
LL | foo(1, 2, 1i16);
| ^^^^ help: cast the value to `c_int`: `1i16 as c_int`
error[E0617]: can't pass `u16` to variadic function
- --> $DIR/variadic-ffi-1.rs:31:19
+ --> $DIR/variadic-ffi-1.rs:33:19
|
LL | foo(1, 2, 1u16);
| ^^^^ help: cast the value to `c_uint`: `1u16 as c_uint`
diff --git a/src/test/ui/c-variadic/variadic-ffi-2.rs b/src/test/ui/c-variadic/variadic-ffi-2.rs
index 224ac16f4..96cea8754 100644
--- a/src/test/ui/c-variadic/variadic-ffi-2.rs
+++ b/src/test/ui/c-variadic/variadic-ffi-2.rs
@@ -1,7 +1,20 @@
// ignore-arm stdcall isn't supported
+#![feature(extended_varargs_abi_support)]
+#![feature(abi_efiapi)]
fn baz(f: extern "stdcall" fn(usize, ...)) {
- //~^ ERROR: variadic function must have C or cdecl calling convention
+ //~^ ERROR: C-variadic function must have a compatible calling convention,
+ // like C, cdecl, win64, sysv64 or efiapi
+ f(22, 44);
+}
+
+fn sysv(f: extern "sysv64" fn(usize, ...)) {
+ f(22, 44);
+}
+fn win(f: extern "win64" fn(usize, ...)) {
+ f(22, 44);
+}
+fn efiapi(f: extern "efiapi" fn(usize, ...)) {
f(22, 44);
}
diff --git a/src/test/ui/c-variadic/variadic-ffi-2.stderr b/src/test/ui/c-variadic/variadic-ffi-2.stderr
index 4c8b8d2b2..4e74c9d92 100644
--- a/src/test/ui/c-variadic/variadic-ffi-2.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-2.stderr
@@ -1,8 +1,8 @@
-error[E0045]: C-variadic function must have C or cdecl calling convention
- --> $DIR/variadic-ffi-2.rs:3:11
+error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `win64`, `sysv64` or `efiapi`
+ --> $DIR/variadic-ffi-2.rs:5:11
|
LL | fn baz(f: extern "stdcall" fn(usize, ...)) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadics require C or cdecl calling convention
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
error: aborting due to previous error
diff --git a/src/test/ui/cannot-mutate-captured-non-mut-var.rs b/src/test/ui/cannot-mutate-captured-non-mut-var.rs
index a83884acb..952dab25b 100644
--- a/src/test/ui/cannot-mutate-captured-non-mut-var.rs
+++ b/src/test/ui/cannot-mutate-captured-non-mut-var.rs
@@ -1,8 +1,8 @@
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, tuple_trait)]
use std::io::Read;
-fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
+fn to_fn_once<A:std::marker::Tuple,F:FnOnce<A>>(f: F) -> F { f }
fn main() {
let x = 1;
diff --git a/src/test/ui/cast/cast-pointee-projection.rs b/src/test/ui/cast/cast-pointee-projection.rs
new file mode 100644
index 000000000..f51c5f20f
--- /dev/null
+++ b/src/test/ui/cast/cast-pointee-projection.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+trait Tag<'a> {
+ type Type: ?Sized;
+}
+
+trait IntoRaw: for<'a> Tag<'a> {
+ fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type;
+}
+
+impl<T: for<'a> Tag<'a>> IntoRaw for T {
+ fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type {
+ this as *mut T::Type
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/chalkify/bugs/async.stderr b/src/test/ui/chalkify/bugs/async.stderr
index f53ed53f7..4804df133 100644
--- a/src/test/ui/chalkify/bugs/async.stderr
+++ b/src/test/ui/chalkify/bugs/async.stderr
@@ -1,39 +1,54 @@
-error[E0277]: the trait bound `[static generator@$DIR/async.rs:7:29: 9:2]: Generator<ResumeTy>` is not satisfied
+error[E0277]: `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
--> $DIR/async.rs:7:29
|
LL | async fn foo(x: u32) -> u32 {
- | _____________________________^
+ | _____________________________-
LL | | x
LL | | }
- | |_^ the trait `Generator<ResumeTy>` is not implemented for `[static generator@$DIR/async.rs:7:29: 9:2]`
+ | | ^
+ | | |
+ | |_`[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
+ | required by a bound introduced by this call
|
-note: required by a bound in `std::future::from_generator`
+ = help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:7:29: 9:2]`
+ = note: [async fn body@$DIR/async.rs:7:29: 9:2] must be a future or must implement `IntoFuture` to be awaited
+note: required by a bound in `identity_future`
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
|
-LL | T: Generator<ResumeTy, Yield = ()>,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `std::future::from_generator`
+LL | pub const fn identity_future<O, Fut: Future<Output = O>>(f: Fut) -> Fut {
+ | ^^^^^^^^^^^^^^^^^^ required by this bound in `identity_future`
-error[E0280]: the requirement `<[static generator@$DIR/async.rs:7:29: 9:2] as Generator<ResumeTy>>::Yield == ()` is not satisfied
+error[E0277]: the size for values of type `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output` cannot be known at compilation time
--> $DIR/async.rs:7:29
|
LL | async fn foo(x: u32) -> u32 {
| _____________________________^
LL | | x
LL | | }
- | |_^
+ | |_^ doesn't have a size known at compile-time
|
-note: required by a bound in `std::future::from_generator`
+ = help: the trait `Sized` is not implemented for `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output`
+note: required by a bound in `identity_future`
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
|
-LL | T: Generator<ResumeTy, Yield = ()>,
- | ^^^^^^^^^^ required by this bound in `std::future::from_generator`
+LL | pub const fn identity_future<O, Fut: Future<Output = O>>(f: Fut) -> Fut {
+ | ^ required by this bound in `identity_future`
+
+error[E0277]: `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
+ --> $DIR/async.rs:7:25
+ |
+LL | async fn foo(x: u32) -> u32 {
+ | ^^^ `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
+ |
+ = help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:7:29: 9:2]`
+ = note: [async fn body@$DIR/async.rs:7:29: 9:2] must be a future or must implement `IntoFuture` to be awaited
-error[E0280]: the requirement `<impl Future<Output = u32> as Future>::Output == u32` is not satisfied
+error[E0280]: the requirement `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output == u32` is not satisfied
--> $DIR/async.rs:7:25
|
LL | async fn foo(x: u32) -> u32 {
| ^^^
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/chalkify/closure.rs b/src/test/ui/chalkify/closure.rs
index 81114d491..568e2e30c 100644
--- a/src/test/ui/chalkify/closure.rs
+++ b/src/test/ui/chalkify/closure.rs
@@ -1,4 +1,3 @@
-// check-fail
// compile-flags: -Z chalk
fn main() -> () {
diff --git a/src/test/ui/chalkify/closure.stderr b/src/test/ui/chalkify/closure.stderr
index 515e0cf01..a33c0ba0d 100644
--- a/src/test/ui/chalkify/closure.stderr
+++ b/src/test/ui/chalkify/closure.stderr
@@ -1,5 +1,5 @@
error[E0382]: borrow of moved value: `b`
- --> $DIR/closure.rs:28:5
+ --> $DIR/closure.rs:27:5
|
LL | let mut c = b;
| - value moved here
@@ -8,7 +8,7 @@ LL | b();
| ^ value borrowed here after move
|
note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `a` out of its environment
- --> $DIR/closure.rs:21:9
+ --> $DIR/closure.rs:20:9
|
LL | a = 1;
| ^
diff --git a/src/test/ui/check-cfg/well-known-values.stderr b/src/test/ui/check-cfg/well-known-values.stderr
index 4ec74494f..29ececea5 100644
--- a/src/test/ui/check-cfg/well-known-values.stderr
+++ b/src/test/ui/check-cfg/well-known-values.stderr
@@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")]
| |
| help: did you mean: `"linux"`
|
- = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous
+ = note: expected values for `target_os` are: aix, android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous
= note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition value
diff --git a/src/test/ui/cleanup-rvalue-scopes-cf.stderr b/src/test/ui/cleanup-rvalue-scopes-cf.stderr
index 40f14c389..425cd7514 100644
--- a/src/test/ui/cleanup-rvalue-scopes-cf.stderr
+++ b/src/test/ui/cleanup-rvalue-scopes-cf.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let x1 = arg(&AddFlags(1));
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | (x1, x2, x3, x4, x5, x6, x7);
| -- borrow later used here
@@ -21,7 +21,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let x2 = AddFlags(1).get();
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | (x1, x2, x3, x4, x5, x6, x7);
| -- borrow later used here
@@ -38,7 +38,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let x3 = &*arg(&AddFlags(1));
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | (x1, x2, x3, x4, x5, x6, x7);
| -- borrow later used here
@@ -55,7 +55,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let ref x4 = *arg(&AddFlags(1));
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | (x1, x2, x3, x4, x5, x6, x7);
| -- borrow later used here
@@ -72,7 +72,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let &ref x5 = arg(&AddFlags(1));
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | (x1, x2, x3, x4, x5, x6, x7);
| -- borrow later used here
@@ -89,7 +89,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let x6 = AddFlags(1).get();
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | (x1, x2, x3, x4, x5, x6, x7);
| -- borrow later used here
@@ -106,7 +106,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let StackBox { f: x7 } = StackBox { f: AddFlags(1).get() };
| ^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
LL |
LL | (x1, x2, x3, x4, x5, x6, x7);
| -- borrow later used here
diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
index 384010859..39ec71ba2 100644
--- a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
@@ -16,7 +16,7 @@ LL | / || match out_ref {
LL | | Variant::A => (),
LL | | Variant::B => (),
LL | | };
- | |______^
+ | |_____^
|
= note: closures are lazy and do nothing unless called
= note: `#[warn(unused_must_use)]` on by default
@@ -28,7 +28,7 @@ LL | / || match here.field {
LL | | Variant::A => (),
LL | | Variant::B => (),
LL | | };
- | |______^
+ | |_____^
|
= note: closures are lazy and do nothing unless called
diff --git a/src/test/ui/closures/binder/late-bound-in-body.rs b/src/test/ui/closures/binder/late-bound-in-body.rs
new file mode 100644
index 000000000..bb5c7552f
--- /dev/null
+++ b/src/test/ui/closures/binder/late-bound-in-body.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![feature(closure_lifetime_binder)]
+
+fn main() {
+ let _ = for<'a> || -> () {
+ let _: &'a bool = &true;
+ };
+}
diff --git a/src/test/ui/closures/binder/nested-closures-regions.rs b/src/test/ui/closures/binder/nested-closures-regions.rs
new file mode 100644
index 000000000..6bfc6c80b
--- /dev/null
+++ b/src/test/ui/closures/binder/nested-closures-regions.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![feature(closure_lifetime_binder)]
+#![feature(rustc_attrs)]
+
+#[rustc_regions]
+fn main() {
+ for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
+}
diff --git a/src/test/ui/closures/binder/nested-closures-regions.stderr b/src/test/ui/closures/binder/nested-closures-regions.stderr
new file mode 100644
index 000000000..b385e0ed6
--- /dev/null
+++ b/src/test/ui/closures/binder/nested-closures-regions.stderr
@@ -0,0 +1,38 @@
+note: external requirements
+ --> $DIR/nested-closures-regions.rs:8:24
+ |
+LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: defining type: main::{closure#0}::{closure#0} with closure substs [
+ i8,
+ extern "rust-call" fn((&(),)),
+ (),
+ ]
+ = note: late-bound region is '_#4r
+ = note: late-bound region is '_#2r
+ = note: number of external vids: 3
+ = note: where '_#1r: '_#2r
+ = note: where '_#2r: '_#1r
+
+note: no external requirements
+ --> $DIR/nested-closures-regions.rs:8:5
+ |
+LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: defining type: main::{closure#0} with closure substs [
+ i8,
+ extern "rust-call" fn(()),
+ (),
+ ]
+ = note: late-bound region is '_#2r
+
+note: no external requirements
+ --> $DIR/nested-closures-regions.rs:7:1
+ |
+LL | fn main() {
+ | ^^^^^^^^^
+ |
+ = note: defining type: main
+
diff --git a/src/test/ui/closures/binder/nested-closures.rs b/src/test/ui/closures/binder/nested-closures.rs
new file mode 100644
index 000000000..b3c36e7ee
--- /dev/null
+++ b/src/test/ui/closures/binder/nested-closures.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+#![feature(closure_lifetime_binder)]
+
+fn main() {
+ for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
+}
diff --git a/src/test/ui/closures/closure-array-break-length.stderr b/src/test/ui/closures/closure-array-break-length.stderr
index 2b8ab9bfc..7e0b0027a 100644
--- a/src/test/ui/closures/closure-array-break-length.stderr
+++ b/src/test/ui/closures/closure-array-break-length.stderr
@@ -10,11 +10,11 @@ error[E0268]: `continue` outside of a loop
LL | while |_: [_; continue]| {} {}
| ^^^^^^^^ cannot `continue` outside of a loop
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/closure-array-break-length.rs:6:19
|
LL | while |_: [_; break]| {} {}
- | ^^^^^ cannot `break` outside of a loop
+ | ^^^^^ cannot `break` outside of a loop or labeled block
error: aborting due to 3 previous errors
diff --git a/src/test/ui/closures/issue-23012-supertrait-signature-inference.rs b/src/test/ui/closures/issue-23012-supertrait-signature-inference.rs
new file mode 100644
index 000000000..5899b703e
--- /dev/null
+++ b/src/test/ui/closures/issue-23012-supertrait-signature-inference.rs
@@ -0,0 +1,29 @@
+// check-pass
+// Checks that we can infer a closure signature even if the `FnOnce` bound is
+// a supertrait of the obligations we have currently registered for the Ty var.
+
+pub trait Receive<T, E>: FnOnce(Result<T, E>) {
+ fn receive(self, res: Result<T, E>);
+}
+
+impl<T, E, F: FnOnce(Result<T, E>)> Receive<T, E> for F {
+ fn receive(self, res: Result<T, E>) {
+ self(res)
+ }
+}
+
+pub trait Async<T, E> {
+ fn receive<F: Receive<T, E>>(self, f: F);
+}
+
+impl<T, E> Async<T, E> for Result<T, E> {
+ fn receive<F: Receive<T, E>>(self, f: F) {
+ f(self)
+ }
+}
+
+pub fn main() {
+ Ok::<u32, ()>(123).receive(|res| {
+ res.unwrap();
+ });
+}
diff --git a/src/test/ui/closures/issue-78720.stderr b/src/test/ui/closures/issue-78720.stderr
index 3dd138772..da3f539a0 100644
--- a/src/test/ui/closures/issue-78720.stderr
+++ b/src/test/ui/closures/issue-78720.stderr
@@ -12,8 +12,8 @@ LL | _func: F,
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
-LL | pub trait Fn<Args>: FnMut<Args> {
- | ------------------------------- similarly named trait `Fn` defined here
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | -------------------------------------- similarly named trait `Fn` defined here
|
help: a trait with a similar name exists
|
diff --git a/src/test/ui/closures/issue-90871.rs b/src/test/ui/closures/issue-90871.rs
index 9c70bbc85..7ce061cd3 100644
--- a/src/test/ui/closures/issue-90871.rs
+++ b/src/test/ui/closures/issue-90871.rs
@@ -1,5 +1,7 @@
+#![feature(type_ascription)]
+
fn main() {
- 2: n([u8; || 1])
+ type_ascribe!(2, n([u8; || 1]))
//~^ ERROR cannot find type `n` in this scope
//~| ERROR mismatched types
}
diff --git a/src/test/ui/closures/issue-90871.stderr b/src/test/ui/closures/issue-90871.stderr
index 1e102cc98..a482750fb 100644
--- a/src/test/ui/closures/issue-90871.stderr
+++ b/src/test/ui/closures/issue-90871.stderr
@@ -1,21 +1,26 @@
error[E0412]: cannot find type `n` in this scope
- --> $DIR/issue-90871.rs:2:8
+ --> $DIR/issue-90871.rs:4:22
|
-LL | 2: n([u8; || 1])
- | ^ expecting a type here because of type ascription
+LL | type_ascribe!(2, n([u8; || 1]))
+ | ^ help: a trait with a similar name exists: `Fn`
+ |
+ ::: $SRC_DIR/core/src/ops/function.rs:LL:COL
+ |
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | -------------------------------------- similarly named trait `Fn` defined here
error[E0308]: mismatched types
- --> $DIR/issue-90871.rs:2:15
+ --> $DIR/issue-90871.rs:4:29
|
-LL | 2: n([u8; || 1])
- | ^^^^ expected `usize`, found closure
+LL | type_ascribe!(2, n([u8; || 1]))
+ | ^^^^ expected `usize`, found closure
|
= note: expected type `usize`
- found closure `[closure@$DIR/issue-90871.rs:2:15: 2:17]`
+ found closure `[closure@$DIR/issue-90871.rs:4:29: 4:31]`
help: use parentheses to call this closure
|
-LL | 2: n([u8; (|| 1)()])
- | + +++
+LL | type_ascribe!(2, n([u8; (|| 1)()]))
+ | + +++
error: aborting due to 2 previous errors
diff --git a/src/test/ui/closures/supertrait-hint-references-assoc-ty.rs b/src/test/ui/closures/supertrait-hint-references-assoc-ty.rs
new file mode 100644
index 000000000..270bf14c3
--- /dev/null
+++ b/src/test/ui/closures/supertrait-hint-references-assoc-ty.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+pub trait Fn0: Fn(i32) -> Self::Out {
+ type Out;
+}
+
+impl<F: Fn(i32) -> ()> Fn0 for F {
+ type Out = ();
+}
+
+pub fn closure_typer(_: impl Fn0) {}
+
+fn main() {
+ closure_typer(move |x| {
+ let _: i64 = x.into();
+ });
+}
diff --git a/src/test/ui/codegen/issue-99551.rs b/src/test/ui/codegen/issue-99551.rs
index f24874c99..b223aff4e 100644
--- a/src/test/ui/codegen/issue-99551.rs
+++ b/src/test/ui/codegen/issue-99551.rs
@@ -1,6 +1,5 @@
// build-pass
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
pub trait A {}
pub trait B {}
diff --git a/src/test/ui/codemap_tests/tab_3.stderr b/src/test/ui/codemap_tests/tab_3.stderr
index 9072cc925..080f6c394 100644
--- a/src/test/ui/codemap_tests/tab_3.stderr
+++ b/src/test/ui/codemap_tests/tab_3.stderr
@@ -15,6 +15,10 @@ note: this function takes ownership of the receiver `self`, which moves `some_ve
LL | fn into_iter(self) -> Self::IntoIter;
| ^^^^
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | some_vec.clone().into_iter();
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/codemap_tests/unicode_2.stderr b/src/test/ui/codemap_tests/unicode_2.stderr
index a776a4a1e..19aae1d3c 100644
--- a/src/test/ui/codemap_tests/unicode_2.stderr
+++ b/src/test/ui/codemap_tests/unicode_2.stderr
@@ -1,3 +1,9 @@
+error[E0425]: cannot find value `aÌé` in this scope
+ --> $DIR/unicode_2.rs:4:13
+ |
+LL | let _ = aÌeÌ;
+ | ^^ not found in this scope
+
error: invalid width `7` for integer literal
--> $DIR/unicode_2.rs:2:25
|
@@ -14,12 +20,6 @@ LL | let _ = ("ì•„ã‚", 1i42);
|
= help: valid widths are 8, 16, 32, 64 and 128
-error[E0425]: cannot find value `aÌé` in this scope
- --> $DIR/unicode_2.rs:4:13
- |
-LL | let _ = aÌeÌ;
- | ^^ not found in this scope
-
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/coercion/coerce-block-tail-26978.rs b/src/test/ui/coercion/coerce-block-tail-26978.rs
new file mode 100644
index 000000000..01c8ab5a8
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-26978.rs
@@ -0,0 +1,11 @@
+// check-fail
+fn f(_: &i32) {}
+
+fn main() {
+ let x = Box::new(1i32);
+
+ f(&x);
+ f(&(x));
+ f(&{x});
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/coercion/coerce-block-tail-26978.stderr b/src/test/ui/coercion/coerce-block-tail-26978.stderr
new file mode 100644
index 000000000..384debd48
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-26978.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+ --> $DIR/coerce-block-tail-26978.rs:9:9
+ |
+LL | f(&{x});
+ | ^ expected `i32`, found struct `Box`
+ |
+ = note: expected type `i32`
+ found struct `Box<i32>`
+help: consider unboxing the value
+ |
+LL | f(&{*x});
+ | +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/coerce-block-tail-57749.rs b/src/test/ui/coercion/coerce-block-tail-57749.rs
new file mode 100644
index 000000000..79b5b3323
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-57749.rs
@@ -0,0 +1,35 @@
+// check-fail
+use std::ops::Deref;
+
+fn main() {
+ fn save(who: &str) {
+ println!("I'll save you, {}!", who);
+ }
+
+ struct Madoka;
+
+ impl Deref for Madoka {
+ type Target = str;
+ fn deref(&self) -> &Self::Target {
+ "Madoka"
+ }
+ }
+
+ save(&{ Madoka });
+
+ fn reset(how: &u32) {
+ println!("Reset {} times", how);
+ }
+
+ struct Homura;
+
+ impl Deref for Homura {
+ type Target = u32;
+ fn deref(&self) -> &Self::Target {
+ &42
+ }
+ }
+
+ reset(&{ Homura });
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/coercion/coerce-block-tail-57749.stderr b/src/test/ui/coercion/coerce-block-tail-57749.stderr
new file mode 100644
index 000000000..d5660c81d
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-57749.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/coerce-block-tail-57749.rs:33:14
+ |
+LL | reset(&{ Homura });
+ | ^^^^^^ expected `u32`, found struct `Homura`
+ |
+help: consider dereferencing the type
+ |
+LL | reset(&{ *Homura });
+ | +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/coerce-block-tail-83783.rs b/src/test/ui/coercion/coerce-block-tail-83783.rs
new file mode 100644
index 000000000..18c8ae3bb
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83783.rs
@@ -0,0 +1,13 @@
+// check-fail
+// edition:2018
+fn _consume_reference<T: ?Sized>(_: &T) {}
+
+async fn _foo() {
+ _consume_reference::<i32>(&Box::new(7_i32));
+ _consume_reference::<i32>(&async { Box::new(7_i32) }.await);
+ //~^ ERROR mismatched types
+ _consume_reference::<[i32]>(&vec![7_i32]);
+ _consume_reference::<[i32]>(&async { vec![7_i32] }.await);
+}
+
+fn main() { }
diff --git a/src/test/ui/coercion/coerce-block-tail-83783.stderr b/src/test/ui/coercion/coerce-block-tail-83783.stderr
new file mode 100644
index 000000000..5f53606ce
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83783.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/coerce-block-tail-83783.rs:7:32
+ |
+LL | _consume_reference::<i32>(&async { Box::new(7_i32) }.await);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct `Box`
+ |
+ = note: expected type `i32`
+ found struct `Box<i32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/coerce-block-tail-83850.rs b/src/test/ui/coercion/coerce-block-tail-83850.rs
new file mode 100644
index 000000000..77fdf9998
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83850.rs
@@ -0,0 +1,7 @@
+// check-fail
+fn f(_: &[i32]) {}
+
+fn main() {
+ f(&Box::new([1, 2]));
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/coercion/coerce-block-tail-83850.stderr b/src/test/ui/coercion/coerce-block-tail-83850.stderr
new file mode 100644
index 000000000..bbf607543
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail-83850.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+ --> $DIR/coerce-block-tail-83850.rs:5:7
+ |
+LL | f(&Box::new([1, 2]));
+ | - ^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found struct `Box`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected reference `&[i32]`
+ found reference `&Box<[{integer}; 2]>`
+note: function defined here
+ --> $DIR/coerce-block-tail-83850.rs:2:4
+ |
+LL | fn f(_: &[i32]) {}
+ | ^ ---------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/coerce-block-tail.rs b/src/test/ui/coercion/coerce-block-tail.rs
new file mode 100644
index 000000000..dcbcd3762
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail.rs
@@ -0,0 +1,6 @@
+// check-fail
+fn main() {
+ let _: &str = & { String::from("hahah")};
+ let _: &i32 = & { Box::new(1i32) };
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/coercion/coerce-block-tail.stderr b/src/test/ui/coercion/coerce-block-tail.stderr
new file mode 100644
index 000000000..318cf7586
--- /dev/null
+++ b/src/test/ui/coercion/coerce-block-tail.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+ --> $DIR/coerce-block-tail.rs:4:23
+ |
+LL | let _: &i32 = & { Box::new(1i32) };
+ | ^^^^^^^^^^^^^^ expected `i32`, found struct `Box`
+ |
+ = note: expected type `i32`
+ found struct `Box<i32>`
+help: consider unboxing the value
+ |
+LL | let _: &i32 = & { *Box::new(1i32) };
+ | +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/coercion/coerce-expect-unsized-ascribed.rs b/src/test/ui/coercion/coerce-expect-unsized-ascribed.rs
index c139e823c..d7b11317a 100644
--- a/src/test/ui/coercion/coerce-expect-unsized-ascribed.rs
+++ b/src/test/ui/coercion/coerce-expect-unsized-ascribed.rs
@@ -6,27 +6,27 @@
use std::fmt::Debug;
pub fn main() {
- let _ = box { [1, 2, 3] }: Box<[i32]>; //~ ERROR mismatched types
- let _ = box if true { [1, 2, 3] } else { [1, 3, 4] }: Box<[i32]>; //~ ERROR mismatched types
- let _ = box match true { true => [1, 2, 3], false => [1, 3, 4] }: Box<[i32]>;
+ let _ = type_ascribe!(box { [1, 2, 3] }, Box<[i32]>); //~ ERROR mismatched types
+ let _ = type_ascribe!(box if true { [1, 2, 3] } else { [1, 3, 4] }, Box<[i32]>); //~ ERROR mismatched types
+ let _ = type_ascribe!(box match true { true => [1, 2, 3], false => [1, 3, 4] }, Box<[i32]>);
//~^ ERROR mismatched types
- let _ = box { |x| (x as u8) }: Box<dyn Fn(i32) -> _>; //~ ERROR mismatched types
- let _ = box if true { false } else { true }: Box<dyn Debug>; //~ ERROR mismatched types
- let _ = box match true { true => 'a', false => 'b' }: Box<dyn Debug>; //~ ERROR mismatched types
+ let _ = type_ascribe!(box { |x| (x as u8) }, Box<dyn Fn(i32) -> _>); //~ ERROR mismatched types
+ let _ = type_ascribe!(box if true { false } else { true }, Box<dyn Debug>); //~ ERROR mismatched types
+ let _ = type_ascribe!(box match true { true => 'a', false => 'b' }, Box<dyn Debug>); //~ ERROR mismatched types
- let _ = &{ [1, 2, 3] }: &[i32]; //~ ERROR mismatched types
- let _ = &if true { [1, 2, 3] } else { [1, 3, 4] }: &[i32]; //~ ERROR mismatched types
- let _ = &match true { true => [1, 2, 3], false => [1, 3, 4] }: &[i32];
+ let _ = type_ascribe!(&{ [1, 2, 3] }, &[i32]); //~ ERROR mismatched types
+ let _ = type_ascribe!(&if true { [1, 2, 3] } else { [1, 3, 4] }, &[i32]); //~ ERROR mismatched types
+ let _ = type_ascribe!(&match true { true => [1, 2, 3], false => [1, 3, 4] }, &[i32]);
//~^ ERROR mismatched types
- let _ = &{ |x| (x as u8) }: &dyn Fn(i32) -> _; //~ ERROR mismatched types
- let _ = &if true { false } else { true }: &dyn Debug; //~ ERROR mismatched types
- let _ = &match true { true => 'a', false => 'b' }: &dyn Debug; //~ ERROR mismatched types
+ let _ = type_ascribe!(&{ |x| (x as u8) }, &dyn Fn(i32) -> _); //~ ERROR mismatched types
+ let _ = type_ascribe!(&if true { false } else { true }, &dyn Debug); //~ ERROR mismatched types
+ let _ = type_ascribe!(&match true { true => 'a', false => 'b' }, &dyn Debug); //~ ERROR mismatched types
- let _ = Box::new([1, 2, 3]): Box<[i32]>; //~ ERROR mismatched types
- let _ = Box::new(|x| (x as u8)): Box<dyn Fn(i32) -> _>; //~ ERROR mismatched types
+ let _ = type_ascribe!(Box::new([1, 2, 3]), Box<[i32]>); //~ ERROR mismatched types
+ let _ = type_ascribe!(Box::new(|x| (x as u8)), Box<dyn Fn(i32) -> _>); //~ ERROR mismatched types
- let _ = vec![
+ let _ = type_ascribe!(vec![
Box::new(|x| (x as u8)),
box |x| (x as i16 as u8),
- ]: Vec<Box<dyn Fn(i32) -> _>>;
+ ], Vec<Box<dyn Fn(i32) -> _>>);
}
diff --git a/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr b/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr
index 9d614e610..44968244c 100644
--- a/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr
+++ b/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr
@@ -1,128 +1,128 @@
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:9:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:9:27
|
-LL | let _ = box { [1, 2, 3] }: Box<[i32]>;
- | ^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
+LL | let _ = type_ascribe!(box { [1, 2, 3] }, Box<[i32]>);
+ | ^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
|
= note: expected struct `Box<[i32]>`
found struct `Box<[i32; 3]>`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:10:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:10:27
|
-LL | let _ = box if true { [1, 2, 3] } else { [1, 3, 4] }: Box<[i32]>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
+LL | let _ = type_ascribe!(box if true { [1, 2, 3] } else { [1, 3, 4] }, Box<[i32]>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
|
= note: expected struct `Box<[i32]>`
found struct `Box<[i32; 3]>`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:11:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:11:27
|
-LL | let _ = box match true { true => [1, 2, 3], false => [1, 3, 4] }: Box<[i32]>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
+LL | let _ = type_ascribe!(box match true { true => [1, 2, 3], false => [1, 3, 4] }, Box<[i32]>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
|
= note: expected struct `Box<[i32]>`
found struct `Box<[i32; 3]>`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:13:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:13:27
|
-LL | let _ = box { |x| (x as u8) }: Box<dyn Fn(i32) -> _>;
- | ^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure
+LL | let _ = type_ascribe!(box { |x| (x as u8) }, Box<dyn Fn(i32) -> _>);
+ | ^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure
|
= note: expected struct `Box<dyn Fn(i32) -> u8>`
- found struct `Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:13:19: 13:22]>`
+ found struct `Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:13:33: 13:36]>`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:14:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:14:27
|
-LL | let _ = box if true { false } else { true }: Box<dyn Debug>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `bool`
+LL | let _ = type_ascribe!(box if true { false } else { true }, Box<dyn Debug>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `bool`
|
= note: expected struct `Box<dyn Debug>`
found struct `Box<bool>`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:15:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:15:27
|
-LL | let _ = box match true { true => 'a', false => 'b' }: Box<dyn Debug>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `char`
+LL | let _ = type_ascribe!(box match true { true => 'a', false => 'b' }, Box<dyn Debug>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `char`
|
= note: expected struct `Box<dyn Debug>`
found struct `Box<char>`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:17:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:17:27
|
-LL | let _ = &{ [1, 2, 3] }: &[i32];
- | ^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
+LL | let _ = type_ascribe!(&{ [1, 2, 3] }, &[i32]);
+ | ^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
|
= note: expected reference `&[i32]`
found reference `&[i32; 3]`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:18:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:18:27
|
-LL | let _ = &if true { [1, 2, 3] } else { [1, 3, 4] }: &[i32];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
+LL | let _ = type_ascribe!(&if true { [1, 2, 3] } else { [1, 3, 4] }, &[i32]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
|
= note: expected reference `&[i32]`
found reference `&[i32; 3]`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:19:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:19:27
|
-LL | let _ = &match true { true => [1, 2, 3], false => [1, 3, 4] }: &[i32];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
+LL | let _ = type_ascribe!(&match true { true => [1, 2, 3], false => [1, 3, 4] }, &[i32]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
|
= note: expected reference `&[i32]`
found reference `&[i32; 3]`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:21:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:21:27
|
-LL | let _ = &{ |x| (x as u8) }: &dyn Fn(i32) -> _;
- | ^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure
+LL | let _ = type_ascribe!(&{ |x| (x as u8) }, &dyn Fn(i32) -> _);
+ | ^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure
|
= note: expected reference `&dyn Fn(i32) -> u8`
- found reference `&[closure@$DIR/coerce-expect-unsized-ascribed.rs:21:16: 21:19]`
+ found reference `&[closure@$DIR/coerce-expect-unsized-ascribed.rs:21:30: 21:33]`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:22:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:22:27
|
-LL | let _ = &if true { false } else { true }: &dyn Debug;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `bool`
+LL | let _ = type_ascribe!(&if true { false } else { true }, &dyn Debug);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `bool`
|
= note: expected reference `&dyn Debug`
found reference `&bool`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:23:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:23:27
|
-LL | let _ = &match true { true => 'a', false => 'b' }: &dyn Debug;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `char`
+LL | let _ = type_ascribe!(&match true { true => 'a', false => 'b' }, &dyn Debug);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Debug`, found `char`
|
= note: expected reference `&dyn Debug`
found reference `&char`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:25:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:25:27
|
-LL | let _ = Box::new([1, 2, 3]): Box<[i32]>;
- | ^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
+LL | let _ = type_ascribe!(Box::new([1, 2, 3]), Box<[i32]>);
+ | ^^^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found array `[i32; 3]`
|
= note: expected struct `Box<[i32]>`
found struct `Box<[i32; 3]>`
error[E0308]: mismatched types
- --> $DIR/coerce-expect-unsized-ascribed.rs:26:13
+ --> $DIR/coerce-expect-unsized-ascribed.rs:26:27
|
-LL | let _ = Box::new(|x| (x as u8)): Box<dyn Fn(i32) -> _>;
- | ^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure
+LL | let _ = type_ascribe!(Box::new(|x| (x as u8)), Box<dyn Fn(i32) -> _>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found closure
|
= note: expected struct `Box<dyn Fn(i32) -> u8>`
- found struct `Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:26:22: 26:25]>`
+ found struct `Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:26:36: 26:39]>`
error: aborting due to 14 previous errors
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr
index c25c43692..4d7872598 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `go_trait::GoMut` for type `MyThingy`
+error[E0119]: conflicting implementations of trait `GoMut` for type `MyThingy`
--> $DIR/coherence-blanket-conflicts-with-specific-cross-crate.rs:15:1
|
LL | impl GoMut for MyThingy {
diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
index 111019773..2463f38a9 100644
--- a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
+++ b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
@@ -1,4 +1,4 @@
-error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
+error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
--> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1
|
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
@@ -7,7 +7,7 @@ LL |
LL | impl<T: MyTrait> !Send for TestType<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
-error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`
+error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
--> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1
|
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
diff --git a/src/test/ui/coherence/coherence-impls-copy.stderr b/src/test/ui/coherence/coherence-impls-copy.stderr
index 86356af25..d40ffc48a 100644
--- a/src/test/ui/coherence/coherence-impls-copy.stderr
+++ b/src/test/ui/coherence/coherence-impls-copy.stderr
@@ -9,7 +9,7 @@ LL | impl Copy for i32 {}
|
= note: define and implement a trait or new type instead
-error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`
+error[E0119]: conflicting implementations of trait `Copy` for type `&NotSync`
--> $DIR/coherence-impls-copy.rs:28:1
|
LL | impl Copy for &'static NotSync {}
diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516.stderr b/src/test/ui/coherence/coherence-overlap-issue-23516.stderr
index 85eb189e1..cd3984267 100644
--- a/src/test/ui/coherence/coherence-overlap-issue-23516.stderr
+++ b/src/test/ui/coherence/coherence-overlap-issue-23516.stderr
@@ -1,10 +1,10 @@
-error[E0119]: conflicting implementations of trait `Sweet` for type `std::boxed::Box<_>`
+error[E0119]: conflicting implementations of trait `Sweet` for type `Box<_>`
--> $DIR/coherence-overlap-issue-23516.rs:8:1
|
LL | impl<T:Sugar> Sweet for T { }
| ------------------------- first implementation here
LL | impl<U:Sugar> Sweet for Box<U> { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::boxed::Box<_>`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
|
= note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>`
diff --git a/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr b/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr
index 6492747bb..94d242eaa 100644
--- a/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr
+++ b/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr
@@ -1,11 +1,11 @@
-error[E0119]: conflicting implementations of trait `Foo<_>` for type `std::option::Option<_>`
+error[E0119]: conflicting implementations of trait `Foo<_>` for type `Option<_>`
--> $DIR/coherence-projection-conflict-ty-param.rs:10:1
|
LL | impl <P, T: Foo<P>> Foo<P> for Option<T> {}
| ---------------------------------------- first implementation here
LL |
LL | impl<T, U> Foo<T> for Option<U> { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::option::Option<_>`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Option<_>`
error: aborting due to previous error
diff --git a/src/test/ui/coherence/coherence-wasm-bindgen.stderr b/src/test/ui/coherence/coherence-wasm-bindgen.stderr
index cfcc21240..89615f0fb 100644
--- a/src/test/ui/coherence/coherence-wasm-bindgen.stderr
+++ b/src/test/ui/coherence/coherence-wasm-bindgen.stderr
@@ -1,11 +1,11 @@
-error: conflicting implementations of trait `IntoWasmAbi` for type `&dyn std::ops::Fn(&_) -> _`
+error: conflicting implementations of trait `IntoWasmAbi` for type `&dyn Fn(&_) -> _`
--> $DIR/coherence-wasm-bindgen.rs:28:1
|
LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(A) -> R + 'b)
| ------------------------------------------------------------ first implementation here
...
LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn for<'x> Fn(&'x A) -> R + 'b)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&dyn std::ops::Fn(&_) -> _`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&dyn Fn(&_) -> _`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
diff --git a/src/test/ui/coherence/coherence-with-closure.rs b/src/test/ui/coherence/coherence-with-closure.rs
index 6e3281d85..5b6a62b24 100644
--- a/src/test/ui/coherence/coherence-with-closure.rs
+++ b/src/test/ui/coherence/coherence-with-closure.rs
@@ -8,7 +8,6 @@ fn defining_use() -> OpaqueClosure {
struct Wrapper<T>(T);
trait Trait {}
impl Trait for Wrapper<OpaqueClosure> {}
-//~^ ERROR cannot implement trait on type alias impl trait
impl<T: Sync> Trait for Wrapper<T> {}
//~^ ERROR conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
diff --git a/src/test/ui/coherence/coherence-with-closure.stderr b/src/test/ui/coherence/coherence-with-closure.stderr
index d2ca63fa1..431108e14 100644
--- a/src/test/ui/coherence/coherence-with-closure.stderr
+++ b/src/test/ui/coherence/coherence-with-closure.stderr
@@ -1,24 +1,11 @@
error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
- --> $DIR/coherence-with-closure.rs:12:1
+ --> $DIR/coherence-with-closure.rs:11:1
|
LL | impl Trait for Wrapper<OpaqueClosure> {}
| ------------------------------------- first implementation here
-LL |
LL | impl<T: Sync> Trait for Wrapper<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>`
-error: cannot implement trait on type alias impl trait
- --> $DIR/coherence-with-closure.rs:10:24
- |
-LL | impl Trait for Wrapper<OpaqueClosure> {}
- | ^^^^^^^^^^^^^
- |
-note: type alias impl trait defined here
- --> $DIR/coherence-with-closure.rs:3:22
- |
-LL | type OpaqueClosure = impl Sized;
- | ^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-with-generator.rs b/src/test/ui/coherence/coherence-with-generator.rs
index d34c391db..70665ba06 100644
--- a/src/test/ui/coherence/coherence-with-generator.rs
+++ b/src/test/ui/coherence/coherence-with-generator.rs
@@ -12,7 +12,6 @@ fn defining_use() -> OpaqueGenerator {
struct Wrapper<T>(T);
trait Trait {}
impl Trait for Wrapper<OpaqueGenerator> {}
-//~^ ERROR cannot implement trait on type alias impl trait
impl<T: Sync> Trait for Wrapper<T> {}
//~^ ERROR conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
diff --git a/src/test/ui/coherence/coherence-with-generator.stderr b/src/test/ui/coherence/coherence-with-generator.stderr
index 804bc1c3a..6d3be2e16 100644
--- a/src/test/ui/coherence/coherence-with-generator.stderr
+++ b/src/test/ui/coherence/coherence-with-generator.stderr
@@ -1,24 +1,11 @@
error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
- --> $DIR/coherence-with-generator.rs:16:1
+ --> $DIR/coherence-with-generator.rs:15:1
|
LL | impl Trait for Wrapper<OpaqueGenerator> {}
| --------------------------------------- first implementation here
-LL |
LL | impl<T: Sync> Trait for Wrapper<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>`
-error: cannot implement trait on type alias impl trait
- --> $DIR/coherence-with-generator.rs:14:24
- |
-LL | impl Trait for Wrapper<OpaqueGenerator> {}
- | ^^^^^^^^^^^^^^^
- |
-note: type alias impl trait defined here
- --> $DIR/coherence-with-generator.rs:3:24
- |
-LL | type OpaqueGenerator = impl Sized;
- | ^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr
index db7306501..93486fa5f 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr
@@ -1,11 +1,11 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyFundamentalStruct<(MyType,)>`
+error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFundamentalStruct<(MyType,)>`
--> $DIR/coherence_copy_like_err_fundamental_struct_tuple.rs:16:1
|
LL | impl<T: lib::MyCopy> MyTrait for T { }
| ---------------------------------- first implementation here
...
LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFundamentalStruct<(MyType,)>`
|
= note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.stderr b/src/test/ui/coherence/coherence_copy_like_err_struct.stderr
index 3bc3dffda..7432733b9 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_struct.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_struct.stderr
@@ -1,11 +1,11 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyStruct<MyType>`
+error[E0119]: conflicting implementations of trait `MyTrait` for type `MyStruct<MyType>`
--> $DIR/coherence_copy_like_err_struct.rs:19:1
|
LL | impl<T: lib::MyCopy> MyTrait for T { }
| ---------------------------------- first implementation here
...
LL | impl MyTrait for lib::MyStruct<MyType> { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyStruct<MyType>`
|
= note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
diff --git a/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr b/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
index 038a0199a..4ddd712b2 100644
--- a/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
+++ b/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::convert::From<()>` for type `S`
+error[E0119]: conflicting implementations of trait `From<()>` for type `S`
--> $DIR/inter-crate-ambiguity-causes-notes.rs:9:1
|
LL | impl From<()> for S {
diff --git a/src/test/ui/coherence/issue-100191-2.rs b/src/test/ui/coherence/issue-100191-2.rs
deleted file mode 100644
index 1c8316f87..000000000
--- a/src/test/ui/coherence/issue-100191-2.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//~ ERROR overflow evaluating the requirement `T: Trait<_>`
-
-#![feature(specialization, with_negative_coherence)]
-#![allow(incomplete_features)]
-
-pub trait Trait<T> {}
-
-default impl<T, U> Trait<T> for U {}
-
-impl<T> Trait<<T as Iterator>::Item> for T {}
-
-fn main() {}
diff --git a/src/test/ui/coherence/issue-100191.rs b/src/test/ui/coherence/issue-100191.rs
deleted file mode 100644
index e8597fde5..000000000
--- a/src/test/ui/coherence/issue-100191.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-#![crate_type = "lib"]
-#![feature(specialization, with_negative_coherence)]
-#![allow(incomplete_features)]
-
-trait X {}
-trait Y: X {}
-trait Z {
- type Assoc: Y;
-}
-struct A<T>(T);
-
-impl<T> Y for T where T: X {}
-impl<T: X> Z for A<T> {
- type Assoc = T;
-}
-
-// this impl is invalid, but causes an ICE anyway
-impl<T> From<<A<T> as Z>::Assoc> for T {}
-//~^ ERROR type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-
-fn main() {}
diff --git a/src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs
new file mode 100644
index 000000000..221683dd5
--- /dev/null
+++ b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs
@@ -0,0 +1,7 @@
+#![feature(rustc_attrs)]
+
+#[rustc_strict_coherence]
+trait Foo {}
+//~^ ERROR to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
+
+fn main() {}
diff --git a/src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr
new file mode 100644
index 000000000..b54729287
--- /dev/null
+++ b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr
@@ -0,0 +1,10 @@
+error: to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
+ --> $DIR/strict-coherence-needs-negative-coherence.rs:4:1
+ |
+LL | #[rustc_strict_coherence]
+ | ------------------------- due to this attribute
+LL | trait Foo {}
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/compiletest-self-test/compile-flags-last.rs b/src/test/ui/compiletest-self-test/compile-flags-last.rs
new file mode 100644
index 000000000..232df10f1
--- /dev/null
+++ b/src/test/ui/compiletest-self-test/compile-flags-last.rs
@@ -0,0 +1,7 @@
+// Check that the arguments provided through `// compile-flags` are added last to the command line
+// in UI tests. To ensure that we invoke rustc with a flag that expects an argument withut actually
+// providing it. If the compile-flags are not last, the test will fail as rustc will interpret the
+// next flag as the argument of this flag.
+//
+// compile-flags: --cap-lints
+// error-pattern: Argument to option 'cap-lints' missing
diff --git a/src/test/ui/compiletest-self-test/compile-flags-last.stderr b/src/test/ui/compiletest-self-test/compile-flags-last.stderr
new file mode 100644
index 000000000..d8d40a7d9
--- /dev/null
+++ b/src/test/ui/compiletest-self-test/compile-flags-last.stderr
@@ -0,0 +1,2 @@
+error: Argument to option 'cap-lints' missing
+
diff --git a/src/test/ui/ui-testing-optout.rs b/src/test/ui/compiletest-self-test/ui-testing-optout.rs
index 88e811583..88e811583 100644
--- a/src/test/ui/ui-testing-optout.rs
+++ b/src/test/ui/compiletest-self-test/ui-testing-optout.rs
diff --git a/src/test/ui/ui-testing-optout.stderr b/src/test/ui/compiletest-self-test/ui-testing-optout.stderr
index 652c472c0..652c472c0 100644
--- a/src/test/ui/ui-testing-optout.stderr
+++ b/src/test/ui/compiletest-self-test/ui-testing-optout.stderr
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
index 5f278f94b..fbfcd4565 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr
@@ -28,7 +28,7 @@ warning: unused `MustUseDeprecated` that must be used
--> $DIR/cfg-attr-multi-true.rs:19:5
|
LL | MustUseDeprecated::new();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/cfg-attr-multi-true.rs:7:9
diff --git a/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs b/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs
index d68acd245..99a7949db 100644
--- a/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs
+++ b/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs
@@ -46,7 +46,7 @@ const C: bool = true;
trait Trait {}
impl dyn Trait { fn existing() {} }
-// FIXME: Should be a error for edition > 2015
+// FIXME: Should be an error for edition > 2015
#[cfg_accessible(Trait::existing)] //~ ERROR not sure
const A: bool = true;
#[cfg_accessible(Trait::unresolved)] //~ ERROR not sure
diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
index f2e7777ce..a46bd5352 100644
--- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
+++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
@@ -18,9 +18,7 @@ LL |
LL | 1_u32
| ----- return type was inferred to be `u32` here
|
- = help: the following other types implement trait `Traitor<N, M>`:
- <u32 as Traitor<N, 2>>
- <u64 as Traitor<1, 2>>
+ = help: the trait `Traitor<N, 2>` is implemented for `u32`
error[E0277]: the trait bound `u64: Traitor` is not satisfied
--> $DIR/rp_impl_trait_fail.rs:21:13
@@ -31,9 +29,7 @@ LL |
LL | 1_u64
| ----- return type was inferred to be `u64` here
|
- = help: the following other types implement trait `Traitor<N, M>`:
- <u32 as Traitor<N, 2>>
- <u64 as Traitor<1, 2>>
+ = help: the trait `Traitor<1, 2>` is implemented for `u64`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/const-generics/defaults/self-referential.rs b/src/test/ui/const-generics/defaults/self-referential.rs
new file mode 100644
index 000000000..14a870dc3
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/self-referential.rs
@@ -0,0 +1,4 @@
+trait Foo<const M: u8, const M: u8 = M> {}
+//~^ ERROR the name `M` is already used for a generic parameter in this item's generic parameters
+impl Foo<2> for () {}
+fn main() {}
diff --git a/src/test/ui/const-generics/defaults/self-referential.stderr b/src/test/ui/const-generics/defaults/self-referential.stderr
new file mode 100644
index 000000000..170c1f7f7
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/self-referential.stderr
@@ -0,0 +1,11 @@
+error[E0403]: the name `M` is already used for a generic parameter in this item's generic parameters
+ --> $DIR/self-referential.rs:1:30
+ |
+LL | trait Foo<const M: u8, const M: u8 = M> {}
+ | - ^ already used
+ | |
+ | first use of `M`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0403`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs
new file mode 100644
index 000000000..e8f89cb1a
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/const_equate_assoc_consts.rs
@@ -0,0 +1,27 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {
+ const ASSOC: usize;
+}
+impl<T> Trait for T {
+ const ASSOC: usize = std::mem::size_of::<T>();
+}
+
+struct Foo<T: Trait>([u8; T::ASSOC])
+where
+ [(); T::ASSOC]:;
+
+fn bar<T: Trait>()
+where
+ [(); T::ASSOC]:,
+{
+ let _: Foo<T> = Foo::<_>(make());
+}
+
+fn make() -> ! {
+ todo!()
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.rs b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.rs
new file mode 100644
index 000000000..c8f7553da
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.rs
@@ -0,0 +1,15 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {
+ const ASSOC: usize;
+}
+
+fn foo<T: Trait, U: Trait>() where [(); U::ASSOC]:, {
+ bar::<{ T::ASSOC }>();
+ //~^ ERROR: unconstrained generic constant
+}
+
+fn bar<const N: usize>() {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr
new file mode 100644
index 000000000..e4a0cabe5
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr
@@ -0,0 +1,10 @@
+error: unconstrained generic constant
+ --> $DIR/doesnt_unify_evaluatable.rs:9:11
+ |
+LL | bar::<{ T::ASSOC }>();
+ | ^^^^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); { T::ASSOC }]:`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/dropck_unifies_assoc_consts.rs b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/dropck_unifies_assoc_consts.rs
new file mode 100644
index 000000000..274caa1e9
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/dropck_unifies_assoc_consts.rs
@@ -0,0 +1,20 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {
+ const ASSOC: usize;
+}
+
+struct Foo<T: Trait>(T)
+where
+ [(); T::ASSOC]:;
+
+impl<T: Trait> Drop for Foo<T>
+where
+ [(); T::ASSOC]:,
+{
+ fn drop(&mut self) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/unifies_evaluatable.rs b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/unifies_evaluatable.rs
new file mode 100644
index 000000000..6597b9f2b
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/assoc_const_unification/unifies_evaluatable.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Trait {
+ const ASSOC: usize;
+}
+
+fn foo<T: Trait, U: Trait>() where [(); T::ASSOC]:, {
+ bar::<{ T::ASSOC }>();
+}
+
+fn bar<const N: usize>() -> [(); N] {
+ [(); N]
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs b/src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs
new file mode 100644
index 000000000..6093fc70b
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.rs
@@ -0,0 +1,22 @@
+#![feature(generic_const_exprs, generic_arg_infer)]
+#![allow(incomplete_features)]
+
+// minimized repro for #105205
+//
+// the `foo::<_, L>` call results in a `WellFormed(_)` obligation and a
+// `ConstEvaluatable(Unevaluated(_ + 1 + L))` obligation. Attempting to fulfill the latter
+// unifies the `_` with `Expr(L - 1)` from the paramenv which turns the `WellFormed`
+// obligation into `WellFormed(Expr(L - 1))`
+
+fn foo<const N: usize, const M: usize>(_: [(); N + 1 + M]) {}
+
+fn ice<const L: usize>()
+where
+ [(); (L - 1) + 1 + L]:,
+{
+ foo::<_, L>([(); L + 1 + L]);
+ //~^ ERROR: mismatched types
+ //~^^ ERROR: unconstrained generic constant
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr b/src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr
new file mode 100644
index 000000000..da5194696
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/const_kind_expr/wf_obligation.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/wf_obligation.rs:17:17
+ |
+LL | foo::<_, L>([(); L + 1 + L]);
+ | ^^^^^^^^^^^^^^^ expected `N + 1 + M`, found `L + 1 + L`
+ |
+ = note: expected constant `N + 1 + M`
+ found constant `L + 1 + L`
+
+error: unconstrained generic constant
+ --> $DIR/wf_obligation.rs:17:22
+ |
+LL | foo::<_, L>([(); L + 1 + L]);
+ | ^^^^^^^^^
+ |
+ = help: try adding a `where` bound using this expression: `where [(); L + 1 + L]:`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-102768.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-102768.stderr
index 9deb9b265..8278edabe 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-102768.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-102768.stderr
@@ -11,7 +11,7 @@ LL | type Y<'a>;
| ^ --
help: add missing lifetime argument
|
-LL | fn f2<'a>(arg: Box<dyn X<Y<'a, 1> = &'a ()>>) {}
+LL | fn f2<'a>(arg: Box<dyn X<Y<'_, 1> = &'a ()>>) {}
| +++
error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr
index 1b502642e..bf1b411ee 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-80742.stderr
@@ -2,15 +2,18 @@ error[E0080]: evaluation of `Inline::<dyn std::fmt::Debug>::{constant#0}` failed
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | intrinsics::size_of::<T>()
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | size_of called on unsized type `dyn Debug`
- | inside `std::mem::size_of::<dyn Debug>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ size_of called on unsized type `dyn Debug`
+ |
+note: inside `std::mem::size_of::<dyn Debug>`
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
- ::: $DIR/issue-80742.rs:22:10
+LL | intrinsics::size_of::<T>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `Inline::<dyn Debug>::{constant#0}`
+ --> $DIR/issue-80742.rs:22:10
|
LL | [u8; size_of::<T>() + 1]: ,
- | -------------- inside `Inline::<dyn Debug>::{constant#0}` at $DIR/issue-80742.rs:22:10
+ | ^^^^^^^^^^^^^^
error[E0599]: the function or associated item `new` exists for struct `Inline<dyn Debug>`, but its trait bounds were not satisfied
--> $DIR/issue-80742.rs:30:36
@@ -33,15 +36,18 @@ error[E0080]: evaluation of `Inline::<dyn std::fmt::Debug>::{constant#0}` failed
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | intrinsics::size_of::<T>()
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | size_of called on unsized type `dyn Debug`
- | inside `std::mem::size_of::<dyn Debug>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ size_of called on unsized type `dyn Debug`
+ |
+note: inside `std::mem::size_of::<dyn Debug>`
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
- ::: $DIR/issue-80742.rs:14:10
+LL | intrinsics::size_of::<T>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `Inline::<dyn Debug>::{constant#0}`
+ --> $DIR/issue-80742.rs:14:10
|
LL | [u8; size_of::<T>() + 1]: ,
- | -------------- inside `Inline::<dyn Debug>::{constant#0}` at $DIR/issue-80742.rs:14:10
+ | ^^^^^^^^^^^^^^
error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
--> $DIR/issue-80742.rs:30:15
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-99705.rs b/src/test/ui/const-generics/generic_const_exprs/issue-99705.rs
new file mode 100644
index 000000000..75b57b621
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-99705.rs
@@ -0,0 +1,33 @@
+// check-pass
+#![crate_type = "lib"]
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+pub trait MyIterator {
+ type Output;
+}
+
+pub trait Foo {
+ const ABC: usize;
+}
+
+pub struct IteratorStruct<const N: usize>{
+
+}
+
+pub struct Bar<const N: usize> {
+ pub data: [usize; N]
+}
+
+impl<const N: usize> MyIterator for IteratorStruct<N> {
+ type Output = Bar<N>;
+}
+
+pub fn test1<T: Foo>() -> impl MyIterator<Output = Bar<{T::ABC}>> where [(); T::ABC]: Sized {
+ IteratorStruct::<{T::ABC}>{}
+}
+
+pub trait Baz<const N: usize>{}
+impl<const N: usize> Baz<N> for Bar<N> {}
+pub fn test2<T: Foo>() -> impl MyIterator<Output = impl Baz<{ T::ABC }>> where [(); T::ABC]: Sized {
+ IteratorStruct::<{T::ABC}>{}
+}
diff --git a/src/test/ui/const-generics/generic_const_exprs/normed_to_param_is_evaluatable.rs b/src/test/ui/const-generics/generic_const_exprs/normed_to_param_is_evaluatable.rs
new file mode 100644
index 000000000..b37b354ae
--- /dev/null
+++ b/src/test/ui/const-generics/generic_const_exprs/normed_to_param_is_evaluatable.rs
@@ -0,0 +1,12 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features, unused_braces)]
+
+#[rustfmt::skip]
+fn foo<const N: usize>() {
+ bar::<{{{{{{ N }}}}}}>();
+}
+
+fn bar<const N: usize>() {}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-1.rs b/src/test/ui/const-generics/inhabited-assoc-ty-ice-1.rs
index c9e26c302..b385406b0 100644
--- a/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-1.rs
+++ b/src/test/ui/const-generics/inhabited-assoc-ty-ice-1.rs
@@ -2,7 +2,7 @@
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
-// This tests that the `conservative_is_privately_uninhabited` fn doesn't cause
+// This tests that the inhabited check doesn't cause
// ICEs by trying to evaluate `T::ASSOC` with an incorrect `ParamEnv`.
trait Foo {
diff --git a/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-2.rs b/src/test/ui/const-generics/inhabited-assoc-ty-ice-2.rs
index 3017920fc..216d29c7c 100644
--- a/src/test/ui/const-generics/conservative_is_privately_uninhabited_uses_correct_param_env-2.rs
+++ b/src/test/ui/const-generics/inhabited-assoc-ty-ice-2.rs
@@ -2,7 +2,7 @@
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
-// This tests that the `conservative_is_privately_uninhabited` fn doesn't cause
+// This tests that the inhabited check doesn't cause
// ICEs by trying to evaluate `T::ASSOC` with an incorrect `ParamEnv`.
trait Foo {
diff --git a/src/test/ui/const-generics/invariant.rs b/src/test/ui/const-generics/invariant.rs
index ee191b65c..39d658be6 100644
--- a/src/test/ui/const-generics/invariant.rs
+++ b/src/test/ui/const-generics/invariant.rs
@@ -24,7 +24,8 @@ where
fn covariant(
v: &'static Foo<for<'a> fn(&'a ())>
) -> &'static Foo<fn(&'static ())> {
- v //~ ERROR mismatched types
+ v
+ //~^ ERROR mismatched types
}
fn main() {
diff --git a/src/test/ui/const-generics/issues/issue-100313.stderr b/src/test/ui/const-generics/issues/issue-100313.stderr
index f3ce357c2..d4b486376 100644
--- a/src/test/ui/const-generics/issues/issue-100313.stderr
+++ b/src/test/ui/const-generics/issues/issue-100313.stderr
@@ -2,13 +2,18 @@ error[E0080]: evaluation of constant value failed
--> $DIR/issue-100313.rs:10:13
|
LL | *(B as *const bool as *mut bool) = false;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to alloc7 which is read-only
+ |
+note: inside `T::<&true>::set_false`
+ --> $DIR/issue-100313.rs:10:13
+ |
+LL | *(B as *const bool as *mut bool) = false;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | writing to alloc7 which is read-only
- | inside `T::<&true>::set_false` at $DIR/issue-100313.rs:10:13
-...
+note: inside `_`
+ --> $DIR/issue-100313.rs:18:5
+ |
LL | x.set_false();
- | ------------- inside `_` at $DIR/issue-100313.rs:18:5
+ | ^^^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/const-generics/issues/issue-82956.stderr b/src/test/ui/const-generics/issues/issue-82956.stderr
index c8b999da9..d2320293e 100644
--- a/src/test/ui/const-generics/issues/issue-82956.stderr
+++ b/src/test/ui/const-generics/issues/issue-82956.stderr
@@ -2,7 +2,7 @@ error[E0433]: failed to resolve: use of undeclared type `IntoIter`
--> $DIR/issue-82956.rs:25:24
|
LL | let mut iter = IntoIter::new(self);
- | ^^^^^^^^ not found in this scope
+ | ^^^^^^^^ use of undeclared type `IntoIter`
|
help: consider importing one of these items
|
diff --git a/src/test/ui/const-generics/issues/issue-83765.stderr b/src/test/ui/const-generics/issues/issue-83765.stderr
index 4becf3a36..d7b2b006c 100644
--- a/src/test/ui/const-generics/issues/issue-83765.stderr
+++ b/src/test/ui/const-generics/issues/issue-83765.stderr
@@ -1,15 +1,15 @@
-error[E0391]: cycle detected when resolving instance `<LazyUpdim<'_, T, { T::DIM }, DIM> as TensorDimension>::DIM`
+error[E0391]: cycle detected when resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`
--> $DIR/issue-83765.rs:5:5
|
LL | const DIM: usize;
| ^^^^^^^^^^^^^^^^
|
-note: ...which requires computing candidate for `<LazyUpdim<'_, T, { T::DIM }, DIM> as TensorDimension>`...
+note: ...which requires computing candidate for `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>`...
--> $DIR/issue-83765.rs:4:1
|
LL | trait TensorDimension {
| ^^^^^^^^^^^^^^^^^^^^^
- = note: ...which again requires resolving instance `<LazyUpdim<'_, T, { T::DIM }, DIM> as TensorDimension>::DIM`, completing the cycle
+ = note: ...which again requires resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`, completing the cycle
note: cycle used when computing candidate for `<LazyUpdim<'_, T, { T::DIM }, DIM> as TensorDimension>`
--> $DIR/issue-83765.rs:4:1
|
diff --git a/src/test/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-85031-2.rs b/src/test/ui/const-generics/issues/issue-85031-2.rs
index db1e2fc2a..4908fb296 100644
--- a/src/test/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-85031-2.rs
+++ b/src/test/ui/const-generics/issues/issue-85031-2.rs
@@ -1,4 +1,8 @@
-// revisions: cfail
+// check-pass
+// known-bug
+
+// This should not compile, as the compiler should not know
+// `A - 0` is satisfied `?x - 0` if `?x` is inferred to `A`.
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
@@ -6,8 +10,8 @@ pub struct Ref<'a>(&'a i32);
impl<'a> Ref<'a> {
pub fn foo<const A: usize>() -> [(); A - 0] {
+ //~^ WARN function cannot
Self::foo()
- //~^ error: type annotations needed
}
}
diff --git a/src/test/ui/const-generics/issues/issue-85031-2.stderr b/src/test/ui/const-generics/issues/issue-85031-2.stderr
new file mode 100644
index 000000000..fc6905768
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-85031-2.stderr
@@ -0,0 +1,14 @@
+warning: function cannot return without recursing
+ --> $DIR/issue-85031-2.rs:12:5
+ |
+LL | pub fn foo<const A: usize>() -> [(); A - 0] {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL |
+LL | Self::foo()
+ | ----------- recursive call site
+ |
+ = help: a `loop` may express intention better if this is on purpose
+ = note: `#[warn(unconditional_recursion)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/const-generics/min_const_generics/macro-fail.rs b/src/test/ui/const-generics/min_const_generics/macro-fail.rs
index f83518fc9..7fb69032e 100644
--- a/src/test/ui/const-generics/min_const_generics/macro-fail.rs
+++ b/src/test/ui/const-generics/min_const_generics/macro-fail.rs
@@ -14,7 +14,6 @@ impl<const N: usize> Marker<N> for Example<N> {}
fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
//~^ ERROR: type provided when a constant was expected
Example::<gimme_a_const!(marker)>
- //~^ ERROR: type provided when a constant was expected
}
fn from_marker(_: impl Marker<{
@@ -34,9 +33,7 @@ fn main() {
}>;
let _fail = Example::<external_macro!()>;
- //~^ ERROR: type provided when a constant was expected
let _fail = Example::<gimme_a_const!()>;
- //~^ ERROR: type provided when a constant was expected
- //~| ERROR unexpected end of macro invocation
+ //~^ ERROR unexpected end of macro invocation
}
diff --git a/src/test/ui/const-generics/min_const_generics/macro-fail.stderr b/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
index d5dd70d9b..9f73b91aa 100644
--- a/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
+++ b/src/test/ui/const-generics/min_const_generics/macro-fail.stderr
@@ -1,5 +1,5 @@
error: expected type, found `{`
- --> $DIR/macro-fail.rs:29:27
+ --> $DIR/macro-fail.rs:28:27
|
LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
| ----------------------
@@ -13,7 +13,7 @@ LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
error: expected type, found `{`
- --> $DIR/macro-fail.rs:29:27
+ --> $DIR/macro-fail.rs:28:27
|
LL | Example::<gimme_a_const!(marker)>
| ----------------------
@@ -46,13 +46,19 @@ LL | let _fail = Example::<external_macro!()>;
= note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unexpected end of macro invocation
- --> $DIR/macro-fail.rs:39:25
+ --> $DIR/macro-fail.rs:37:25
|
LL | macro_rules! gimme_a_const {
| -------------------------- when calling this macro
...
LL | let _fail = Example::<gimme_a_const!()>;
| ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
+ |
+note: while trying to match meta-variable `$rusty:ident`
+ --> $DIR/macro-fail.rs:28:8
+ |
+LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
+ | ^^^^^^^^^^^^^
error[E0747]: type provided when a constant was expected
--> $DIR/macro-fail.rs:14:33
@@ -60,24 +66,6 @@ error[E0747]: type provided when a constant was expected
LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
| ^^^^^^^^^^^^^^^^^^^^^^
-error[E0747]: type provided when a constant was expected
- --> $DIR/macro-fail.rs:16:13
- |
-LL | Example::<gimme_a_const!(marker)>
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0747]: type provided when a constant was expected
- --> $DIR/macro-fail.rs:36:25
- |
-LL | let _fail = Example::<external_macro!()>;
- | ^^^^^^^^^^^^^^^^^
-
-error[E0747]: type provided when a constant was expected
- --> $DIR/macro-fail.rs:39:25
- |
-LL | let _fail = Example::<gimme_a_const!()>;
- | ^^^^^^^^^^^^^^^^
-
-error: aborting due to 8 previous errors
+error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0747`.
diff --git a/src/test/ui/const-generics/projection-as-arg-const.rs b/src/test/ui/const-generics/projection-as-arg-const.rs
new file mode 100644
index 000000000..903548c75
--- /dev/null
+++ b/src/test/ui/const-generics/projection-as-arg-const.rs
@@ -0,0 +1,20 @@
+// This is currently not possible to use projections as const generics.
+// More information about this available here:
+// https://github.com/rust-lang/rust/pull/104443#discussion_r1029375633
+
+pub trait Identity {
+ type Identity;
+}
+
+impl<T> Identity for T {
+ type Identity = Self;
+}
+
+pub fn foo<const X: <i32 as Identity>::Identity>() {
+//~^ ERROR
+ assert!(X == 12);
+}
+
+fn main() {
+ foo::<12>();
+}
diff --git a/src/test/ui/const-generics/projection-as-arg-const.stderr b/src/test/ui/const-generics/projection-as-arg-const.stderr
new file mode 100644
index 000000000..803ed9c95
--- /dev/null
+++ b/src/test/ui/const-generics/projection-as-arg-const.stderr
@@ -0,0 +1,11 @@
+error: `<i32 as Identity>::Identity` is forbidden as the type of a const generic parameter
+ --> $DIR/projection-as-arg-const.rs:13:21
+ |
+LL | pub fn foo<const X: <i32 as Identity>::Identity>() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-ptr/forbidden_slices.32bit.stderr b/src/test/ui/const-ptr/forbidden_slices.32bit.stderr
index 8978ab436..563f3ffd6 100644
--- a/src/test/ui/const-ptr/forbidden_slices.32bit.stderr
+++ b/src/test/ui/const-ptr/forbidden_slices.32bit.stderr
@@ -2,43 +2,52 @@ error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
LL | &*ptr::slice_from_raw_parts(data, len)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance)
- | inside `std::slice::from_raw_parts::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance)
+ |
+note: inside `std::slice::from_raw_parts::<'_, u32>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:18:34
+LL | &*ptr::slice_from_raw_parts(data, len)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `S0`
+ --> $DIR/forbidden_slices.rs:18:34
|
LL | pub static S0: &[u32] = unsafe { from_raw_parts(ptr::null(), 0) };
- | ------------------------------ inside `S0` at $DIR/forbidden_slices.rs:18:34
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
LL | &*ptr::slice_from_raw_parts(data, len)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance)
- | inside `std::slice::from_raw_parts::<'_, ()>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance)
+ |
+note: inside `std::slice::from_raw_parts::<'_, ()>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:19:33
+LL | &*ptr::slice_from_raw_parts(data, len)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `S1`
+ --> $DIR/forbidden_slices.rs:19:33
|
LL | pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) };
- | ------------------------------ inside `S1` at $DIR/forbidden_slices.rs:19:33
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
LL | &*ptr::slice_from_raw_parts(data, len)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | dereferencing pointer failed: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds
- | inside `std::slice::from_raw_parts::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds
+ |
+note: inside `std::slice::from_raw_parts::<'_, u32>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:22:34
+LL | &*ptr::slice_from_raw_parts(data, len)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `S2`
+ --> $DIR/forbidden_slices.rs:22:34
|
LL | pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 2) };
- | ---------------------- inside `S2` at $DIR/forbidden_slices.rs:22:34
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/forbidden_slices.rs:25:1
@@ -89,72 +98,85 @@ error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
LL | &*ptr::slice_from_raw_parts(data, len)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | dereferencing pointer failed: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds
- | inside `std::slice::from_raw_parts::<'_, u64>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds
|
- ::: $DIR/forbidden_slices.rs:43:5
+note: inside `std::slice::from_raw_parts::<'_, u64>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
+ |
+LL | &*ptr::slice_from_raw_parts(data, len)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `S8`
+ --> $DIR/forbidden_slices.rs:43:5
|
LL | from_raw_parts(ptr, 1)
- | ---------------------- inside `S8` at $DIR/forbidden_slices.rs:43:5
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
- | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
|
- ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
-LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
- | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `from_ptr_range::<'_, u32>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:46:34
+LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R0`
+ --> $DIR/forbidden_slices.rs:46:34
|
LL | pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) };
- | ---------------------------------------- inside `R0` at $DIR/forbidden_slices.rs:46:34
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
- | inside `ptr::const_ptr::<impl *const ()>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const ()>::sub_ptr`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
-LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
- | ------------------------------ inside `from_ptr_range::<'_, ()>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+LL | assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `from_ptr_range::<'_, ()>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:47:33
+LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R1`
+ --> $DIR/forbidden_slices.rs:47:33
|
LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) };
- | ---------------------------------------- inside `R1` at $DIR/forbidden_slices.rs:47:33
- |
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds
+ |
+note: inside `ptr::const_ptr::<impl *const u32>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds
- | inside `ptr::const_ptr::<impl *const u32>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
-...
-LL | unsafe { self.offset(count as isize) }
- | --------------------------- inside `ptr::const_ptr::<impl *const u32>::add` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u32>::add`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:50:25
+LL | unsafe { self.offset(count as isize) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R2`
+ --> $DIR/forbidden_slices.rs:50:25
|
LL | from_ptr_range(ptr..ptr.add(2))
- | ---------- inside `R2` at $DIR/forbidden_slices.rs:50:25
+ | ^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/forbidden_slices.rs:52:1
@@ -205,56 +227,67 @@ error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds
+ |
+note: inside `ptr::const_ptr::<impl *const u64>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds
- | inside `ptr::const_ptr::<impl *const u64>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
-...
-LL | unsafe { self.offset(count as isize) }
- | --------------------------- inside `ptr::const_ptr::<impl *const u64>::add` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u64>::add`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:74:25
+LL | unsafe { self.offset(count as isize) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R8`
+ --> $DIR/forbidden_slices.rs:74:25
|
LL | from_ptr_range(ptr..ptr.add(1))
- | ---------- inside `R8` at $DIR/forbidden_slices.rs:74:25
+ | ^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | `ptr_offset_from_unsigned` called on pointers into different allocations
- | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations
|
- ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
-LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
- | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `from_ptr_range::<'_, u32>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:79:34
+LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R9`
+ --> $DIR/forbidden_slices.rs:79:34
|
LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) };
- | ----------------------------------------------- inside `R9` at $DIR/forbidden_slices.rs:79:34
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | `ptr_offset_from_unsigned` called on pointers into different allocations
- | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations
|
- ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
-LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
- | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `from_ptr_range::<'_, u32>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:80:35
+LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R10`
+ --> $DIR/forbidden_slices.rs:80:35
|
LL | pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) };
- | ------------------------ inside `R10` at $DIR/forbidden_slices.rs:80:35
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 18 previous errors
diff --git a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr
index db42b7c98..43529d57f 100644
--- a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr
+++ b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr
@@ -2,43 +2,52 @@ error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
LL | &*ptr::slice_from_raw_parts(data, len)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance)
- | inside `std::slice::from_raw_parts::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance)
+ |
+note: inside `std::slice::from_raw_parts::<'_, u32>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:18:34
+LL | &*ptr::slice_from_raw_parts(data, len)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `S0`
+ --> $DIR/forbidden_slices.rs:18:34
|
LL | pub static S0: &[u32] = unsafe { from_raw_parts(ptr::null(), 0) };
- | ------------------------------ inside `S0` at $DIR/forbidden_slices.rs:18:34
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
LL | &*ptr::slice_from_raw_parts(data, len)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance)
- | inside `std::slice::from_raw_parts::<'_, ()>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance)
+ |
+note: inside `std::slice::from_raw_parts::<'_, ()>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:19:33
+LL | &*ptr::slice_from_raw_parts(data, len)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `S1`
+ --> $DIR/forbidden_slices.rs:19:33
|
LL | pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) };
- | ------------------------------ inside `S1` at $DIR/forbidden_slices.rs:19:33
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
LL | &*ptr::slice_from_raw_parts(data, len)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | dereferencing pointer failed: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds
- | inside `std::slice::from_raw_parts::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds
+ |
+note: inside `std::slice::from_raw_parts::<'_, u32>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:22:34
+LL | &*ptr::slice_from_raw_parts(data, len)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `S2`
+ --> $DIR/forbidden_slices.rs:22:34
|
LL | pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 2) };
- | ---------------------- inside `S2` at $DIR/forbidden_slices.rs:22:34
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/forbidden_slices.rs:25:1
@@ -89,72 +98,85 @@ error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
LL | &*ptr::slice_from_raw_parts(data, len)
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | dereferencing pointer failed: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds
- | inside `std::slice::from_raw_parts::<'_, u64>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds
|
- ::: $DIR/forbidden_slices.rs:43:5
+note: inside `std::slice::from_raw_parts::<'_, u64>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
+ |
+LL | &*ptr::slice_from_raw_parts(data, len)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `S8`
+ --> $DIR/forbidden_slices.rs:43:5
|
LL | from_raw_parts(ptr, 1)
- | ---------------------- inside `S8` at $DIR/forbidden_slices.rs:43:5
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
- | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
|
- ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
-LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
- | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `from_ptr_range::<'_, u32>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:46:34
+LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R0`
+ --> $DIR/forbidden_slices.rs:46:34
|
LL | pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) };
- | ---------------------------------------- inside `R0` at $DIR/forbidden_slices.rs:46:34
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
- | inside `ptr::const_ptr::<impl *const ()>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const ()>::sub_ptr`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
-LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
- | ------------------------------ inside `from_ptr_range::<'_, ()>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+LL | assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `from_ptr_range::<'_, ()>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:47:33
+LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R1`
+ --> $DIR/forbidden_slices.rs:47:33
|
LL | pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) };
- | ---------------------------------------- inside `R1` at $DIR/forbidden_slices.rs:47:33
- |
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds
+ |
+note: inside `ptr::const_ptr::<impl *const u32>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: ALLOC_ID has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds
- | inside `ptr::const_ptr::<impl *const u32>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
-...
-LL | unsafe { self.offset(count as isize) }
- | --------------------------- inside `ptr::const_ptr::<impl *const u32>::add` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u32>::add`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:50:25
+LL | unsafe { self.offset(count as isize) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R2`
+ --> $DIR/forbidden_slices.rs:50:25
|
LL | from_ptr_range(ptr..ptr.add(2))
- | ---------- inside `R2` at $DIR/forbidden_slices.rs:50:25
+ | ^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/forbidden_slices.rs:52:1
@@ -205,56 +227,67 @@ error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds
+ |
+note: inside `ptr::const_ptr::<impl *const u64>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: ALLOC_ID has size 8, so pointer to 8 bytes starting at offset 1 is out-of-bounds
- | inside `ptr::const_ptr::<impl *const u64>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
-...
-LL | unsafe { self.offset(count as isize) }
- | --------------------------- inside `ptr::const_ptr::<impl *const u64>::add` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u64>::add`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:74:25
+LL | unsafe { self.offset(count as isize) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R8`
+ --> $DIR/forbidden_slices.rs:74:25
|
LL | from_ptr_range(ptr..ptr.add(1))
- | ---------- inside `R8` at $DIR/forbidden_slices.rs:74:25
+ | ^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | `ptr_offset_from_unsigned` called on pointers into different allocations
- | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations
|
- ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
-LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
- | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `from_ptr_range::<'_, u32>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:79:34
+LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R9`
+ --> $DIR/forbidden_slices.rs:79:34
|
LL | pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) };
- | ----------------------------------------------- inside `R9` at $DIR/forbidden_slices.rs:79:34
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | `ptr_offset_from_unsigned` called on pointers into different allocations
- | inside `ptr::const_ptr::<impl *const u32>::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations
|
- ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u32>::sub_ptr`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
-LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
- | ------------------------------ inside `from_ptr_range::<'_, u32>` at $SRC_DIR/core/src/slice/raw.rs:LL:COL
+LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `from_ptr_range::<'_, u32>`
+ --> $SRC_DIR/core/src/slice/raw.rs:LL:COL
|
- ::: $DIR/forbidden_slices.rs:80:35
+LL | unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `R10`
+ --> $DIR/forbidden_slices.rs:80:35
|
LL | pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) };
- | ------------------------ inside `R10` at $DIR/forbidden_slices.rs:80:35
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 18 previous errors
diff --git a/src/test/ui/const-ptr/out_of_bounds_read.stderr b/src/test/ui/const-ptr/out_of_bounds_read.stderr
index 52b173c4d..bca29b468 100644
--- a/src/test/ui/const-ptr/out_of_bounds_read.stderr
+++ b/src/test/ui/const-ptr/out_of_bounds_read.stderr
@@ -2,53 +2,62 @@ error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds
- | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds
+ |
+note: inside `std::ptr::read::<u32>`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
- ::: $DIR/out_of_bounds_read.rs:12:33
+LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `_READ`
+ --> $DIR/out_of_bounds_read.rs:12:33
|
LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
- | ----------------------- inside `_READ` at $DIR/out_of_bounds_read.rs:12:33
+ | ^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds
- | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds
|
- ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+note: inside `std::ptr::read::<u32>`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
-LL | unsafe { read(self) }
- | ---------- inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `ptr::const_ptr::<impl *const u32>::read`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/out_of_bounds_read.rs:13:39
+LL | unsafe { read(self) }
+ | ^^^^^^^^^^
+note: inside `_CONST_READ`
+ --> $DIR/out_of_bounds_read.rs:13:39
|
LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
- | ------------------- inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:13:39
+ | ^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds
- | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc5 has size 4, so pointer to 4 bytes starting at offset 4 is out-of-bounds
+ |
+note: inside `std::ptr::read::<u32>`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
- ::: $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `ptr::mut_ptr::<impl *mut u32>::read`
+ --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
|
LL | unsafe { read(self) }
- | ---------- inside `ptr::mut_ptr::<impl *mut u32>::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
- |
- ::: $DIR/out_of_bounds_read.rs:14:37
+ | ^^^^^^^^^^
+note: inside `_MUT_READ`
+ --> $DIR/out_of_bounds_read.rs:14:37
|
LL | const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
- | --------------------------------- inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:14:37
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
diff --git a/src/test/ui/constructor-lifetime-args.stderr b/src/test/ui/constructor-lifetime-args.stderr
index b97b6faa3..bc1141b16 100644
--- a/src/test/ui/constructor-lifetime-args.stderr
+++ b/src/test/ui/constructor-lifetime-args.stderr
@@ -13,8 +13,8 @@ LL | struct S<'a, 'b>(&'a u8, &'b u8);
| ^ -- --
help: add missing lifetime argument
|
-LL | S::<'static, 'b>(&0, &0);
- | ++++
+LL | S::<'static, 'static>(&0, &0);
+ | +++++++++
error[E0107]: this struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
--> $DIR/constructor-lifetime-args.rs:19:5
@@ -45,8 +45,8 @@ LL | enum E<'a, 'b> {
| ^ -- --
help: add missing lifetime argument
|
-LL | E::V::<'static, 'b>(&0);
- | ++++
+LL | E::V::<'static, 'static>(&0);
+ | +++++++++
error[E0107]: this enum takes 2 lifetime arguments but 3 lifetime arguments were supplied
--> $DIR/constructor-lifetime-args.rs:24:8
diff --git a/src/test/ui/consts/const-err-late.rs b/src/test/ui/consts/const-err-late.rs
index a20ae7025..d2476e493 100644
--- a/src/test/ui/consts/const-err-late.rs
+++ b/src/test/ui/consts/const-err-late.rs
@@ -16,7 +16,5 @@ impl<T> S<T> {
}
fn main() {
- black_box((S::<i32>::FOO, S::<u32>::FOO));
- //~^ ERROR erroneous constant
- //~| ERROR erroneous constant
+ black_box((S::<i32>::FOO, S::<u32>::FOO)); //~ constant
}
diff --git a/src/test/ui/consts/const-err-late.stderr b/src/test/ui/consts/const-err-late.stderr
index 3a8b10317..c5c668189 100644
--- a/src/test/ui/consts/const-err-late.stderr
+++ b/src/test/ui/consts/const-err-late.stderr
@@ -4,11 +4,17 @@ error[E0080]: evaluation of `S::<i32>::FOO` failed
LL | const FOO: u8 = [5u8][1];
| ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/const-err-late.rs:19:16
|
LL | black_box((S::<i32>::FOO, S::<u32>::FOO));
- | ^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/const-err-late.rs:19:16
+ |
+LL | black_box((S::<i32>::FOO, S::<u32>::FOO));
+ | ^^^^^^^^^^^^^
error[E0080]: evaluation of `S::<u32>::FOO` failed
--> $DIR/const-err-late.rs:13:21
@@ -16,12 +22,30 @@ error[E0080]: evaluation of `S::<u32>::FOO` failed
LL | const FOO: u8 = [5u8][1];
| ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
-error[E0080]: erroneous constant used
+note: erroneous constant used
+ --> $DIR/const-err-late.rs:19:31
+ |
+LL | black_box((S::<i32>::FOO, S::<u32>::FOO));
+ | ^^^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/const-err-late.rs:19:31
+ |
+LL | black_box((S::<i32>::FOO, S::<u32>::FOO));
+ | ^^^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/const-err-late.rs:19:16
+ |
+LL | black_box((S::<i32>::FOO, S::<u32>::FOO));
+ | ^^^^^^^^^^^^^
+
+note: erroneous constant used
--> $DIR/const-err-late.rs:19:31
|
LL | black_box((S::<i32>::FOO, S::<u32>::FOO));
- | ^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-err-multi.rs b/src/test/ui/consts/const-err-multi.rs
index fb26e8aac..b265bc4c4 100644
--- a/src/test/ui/consts/const-err-multi.rs
+++ b/src/test/ui/consts/const-err-multi.rs
@@ -1,11 +1,11 @@
pub const A: i8 = -i8::MIN;
//~^ ERROR constant
pub const B: i8 = A;
-//~^ ERROR constant
+//~^ constant
pub const C: u8 = A as u8;
-//~^ ERROR constant
+//~^ constant
pub const D: i8 = 50 - A;
-//~^ ERROR constant
+//~^ constant
fn main() {
let _ = (A, B, C, D);
diff --git a/src/test/ui/consts/const-err-multi.stderr b/src/test/ui/consts/const-err-multi.stderr
index fca9e2270..28af8e5eb 100644
--- a/src/test/ui/consts/const-err-multi.stderr
+++ b/src/test/ui/consts/const-err-multi.stderr
@@ -4,24 +4,24 @@ error[E0080]: evaluation of constant value failed
LL | pub const A: i8 = -i8::MIN;
| ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-err-multi.rs:3:19
|
LL | pub const B: i8 = A;
- | ^ referenced constant has errors
+ | ^
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-err-multi.rs:5:19
|
LL | pub const C: u8 = A as u8;
- | ^ referenced constant has errors
+ | ^
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-err-multi.rs:7:24
|
LL | pub const D: i8 = 50 - A;
- | ^ referenced constant has errors
+ | ^
-error: aborting due to 4 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr b/src/test/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr
index 78143042e..ed6a6ee6e 100644
--- a/src/test/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let x: &'static usize =
| -------------- type annotation requires that borrow lasts for `'static`
LL | &std::intrinsics::size_of::<i32>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
LL | }
| - temporary value is freed at the end of this statement
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr
index c685922c4..f19917001 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr
@@ -12,15 +12,10 @@ LL | = [0; (i8::MAX + 1u8) as usize];
|
= help: the trait `~const Add<u8>` is not implemented for `i8`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
<&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&i8 as Add<&i8>>
+ <i8 as Add<&i8>>
+ <i8 as Add>
error: aborting due to 2 previous errors
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr
index b39607924..1f8e40231 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr
@@ -12,15 +12,10 @@ LL | : [u32; (i8::MAX as i8 + 1u8) as usize]
|
= help: the trait `~const Add<u8>` is not implemented for `i8`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
<&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&i8 as Add<&i8>>
+ <i8 as Add<&i8>>
+ <i8 as Add>
error[E0604]: only `u8` can be cast as `char`, not `i8`
--> $DIR/const-eval-overflow-4b.rs:22:13
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
index 3784a3861..0734f479f 100644
--- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
@@ -2,25 +2,35 @@ error[E0080]: evaluation of constant value failed
--> $DIR/const_fn_ptr_fail2.rs:9:5
|
LL | x(y)
+ | ^^^^ calling non-const function `double`
+ |
+note: inside `bar`
+ --> $DIR/const_fn_ptr_fail2.rs:9:5
+ |
+LL | x(y)
| ^^^^
- | |
- | calling non-const function `double`
- | inside `bar` at $DIR/const_fn_ptr_fail2.rs:9:5
-...
+note: inside `Y`
+ --> $DIR/const_fn_ptr_fail2.rs:14:18
+ |
LL | const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
- | --------- inside `Y` at $DIR/const_fn_ptr_fail2.rs:14:18
+ | ^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $DIR/const_fn_ptr_fail2.rs:9:5
|
LL | x(y)
+ | ^^^^ calling non-const function `double`
+ |
+note: inside `bar`
+ --> $DIR/const_fn_ptr_fail2.rs:9:5
+ |
+LL | x(y)
| ^^^^
- | |
- | calling non-const function `double`
- | inside `bar` at $DIR/const_fn_ptr_fail2.rs:9:5
-...
+note: inside `Z`
+ --> $DIR/const_fn_ptr_fail2.rs:15:18
+ |
LL | const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
- | -------------- inside `Z` at $DIR/const_fn_ptr_fail2.rs:15:18
+ | ^^^^^^^^^^^^^^
warning: skipping const checks
|
diff --git a/src/test/ui/consts/const-eval/const_panic_track_caller.stderr b/src/test/ui/consts/const-eval/const_panic_track_caller.stderr
index 5c3b412d3..846458176 100644
--- a/src/test/ui/consts/const-eval/const_panic_track_caller.stderr
+++ b/src/test/ui/consts/const-eval/const_panic_track_caller.stderr
@@ -2,13 +2,18 @@ error[E0080]: evaluation of constant value failed
--> $DIR/const_panic_track_caller.rs:15:5
|
LL | b()
+ | ^^^ the evaluated program panicked at 'hey', $DIR/const_panic_track_caller.rs:15:5
+ |
+note: inside `c`
+ --> $DIR/const_panic_track_caller.rs:15:5
+ |
+LL | b()
| ^^^
- | |
- | the evaluated program panicked at 'hey', $DIR/const_panic_track_caller.rs:15:5
- | inside `c` at $DIR/const_panic_track_caller.rs:15:5
-...
+note: inside `X`
+ --> $DIR/const_panic_track_caller.rs:21:16
+ |
LL | const X: u32 = c();
- | --- inside `X` at $DIR/const_panic_track_caller.rs:21:16
+ | ^^^
error: aborting due to previous error
diff --git a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr
index 69e3ca716..2e697b219 100644
--- a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr
+++ b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr
@@ -10,7 +10,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/dont_promote_unstable_const_fn.rs:17:28
|
LL | let _: &'static u32 = &foo();
- | ------------ ^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | }
@@ -20,7 +20,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/dont_promote_unstable_const_fn.rs:21:28
|
LL | let _: &'static u32 = &meh();
- | ------------ ^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -31,7 +31,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/dont_promote_unstable_const_fn.rs:22:26
|
LL | let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis();
- | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL |
diff --git a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr
index 129f06151..aa742d784 100644
--- a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr
+++ b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/dont_promote_unstable_const_fn_cross_crate.rs:8:28
|
LL | let _: &'static u32 = &foo();
- | ------------ ^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | let _x: &'static u32 = &foo();
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/dont_promote_unstable_const_fn_cross_crate.rs:9:29
|
LL | let _x: &'static u32 = &foo();
- | ------------ ^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | }
diff --git a/src/test/ui/consts/const-eval/erroneous-const.rs b/src/test/ui/consts/const-eval/erroneous-const.rs
index cf11531ba..e0fd057a2 100644
--- a/src/test/ui/consts/const-eval/erroneous-const.rs
+++ b/src/test/ui/consts/const-eval/erroneous-const.rs
@@ -10,7 +10,7 @@ const fn no_codegen<T>() {
if false {
// This bad constant is only used in dead code in a no-codegen function... and yet we still
// must make sure that the build fails.
- let _ = PrintName::<T>::VOID; //~ERROR could not evaluate static initializer
+ let _ = PrintName::<T>::VOID; //~ constant
}
}
diff --git a/src/test/ui/consts/const-eval/erroneous-const.stderr b/src/test/ui/consts/const-eval/erroneous-const.stderr
index 33579135d..03030392a 100644
--- a/src/test/ui/consts/const-eval/erroneous-const.stderr
+++ b/src/test/ui/consts/const-eval/erroneous-const.stderr
@@ -4,18 +4,12 @@ error[E0080]: evaluation of `PrintName::<i32>::VOID` failed
LL | const VOID: () = [()][2];
| ^^^^^^^ index out of bounds: the length is 1 but the index is 2
-error[E0080]: could not evaluate static initializer
+note: erroneous constant used
--> $DIR/erroneous-const.rs:13:17
|
LL | let _ = PrintName::<T>::VOID;
| ^^^^^^^^^^^^^^^^^^^^
- | |
- | referenced constant has errors
- | inside `no_codegen::<i32>` at $DIR/erroneous-const.rs:13:17
-...
-LL | pub static FOO: () = no_codegen::<i32>();
- | ------------------- inside `FOO` at $DIR/erroneous-const.rs:17:22
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/erroneous-const2.rs b/src/test/ui/consts/const-eval/erroneous-const2.rs
index 2fbf7be88..15c0f9107 100644
--- a/src/test/ui/consts/const-eval/erroneous-const2.rs
+++ b/src/test/ui/consts/const-eval/erroneous-const2.rs
@@ -10,7 +10,7 @@ pub static FOO: () = {
if false {
// This bad constant is only used in dead code in a static initializer... and yet we still
// must make sure that the build fails.
- let _ = PrintName::<i32>::VOID; //~ERROR could not evaluate static initializer
+ let _ = PrintName::<i32>::VOID; //~ constant
}
};
diff --git a/src/test/ui/consts/const-eval/erroneous-const2.stderr b/src/test/ui/consts/const-eval/erroneous-const2.stderr
index 630b1cf16..8626f4d78 100644
--- a/src/test/ui/consts/const-eval/erroneous-const2.stderr
+++ b/src/test/ui/consts/const-eval/erroneous-const2.stderr
@@ -4,12 +4,12 @@ error[E0080]: evaluation of `PrintName::<i32>::VOID` failed
LL | const VOID: () = [()][2];
| ^^^^^^^ index out of bounds: the length is 1 but the index is 2
-error[E0080]: could not evaluate static initializer
+note: erroneous constant used
--> $DIR/erroneous-const2.rs:13:17
|
LL | let _ = PrintName::<i32>::VOID;
- | ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/format.rs b/src/test/ui/consts/const-eval/format.rs
index 3eef0d6c3..0d8b7c12d 100644
--- a/src/test/ui/consts/const-eval/format.rs
+++ b/src/test/ui/consts/const-eval/format.rs
@@ -1,8 +1,6 @@
const fn failure() {
panic!("{:?}", 0);
//~^ ERROR cannot call non-const formatting macro in constant functions
- //~| ERROR erroneous constant used
- //~| ERROR erroneous constant used
}
const fn print() {
@@ -10,8 +8,6 @@ const fn print() {
//~^ ERROR cannot call non-const formatting macro in constant functions
//~| ERROR `Arguments::<'a>::new_v1` is not yet stable as a const fn
//~| ERROR cannot call non-const fn `_print` in constant functions
- //~| ERROR erroneous constant used
- //~| ERROR erroneous constant used
}
fn main() {}
diff --git a/src/test/ui/consts/const-eval/format.stderr b/src/test/ui/consts/const-eval/format.stderr
index 64c769648..4bf39db58 100644
--- a/src/test/ui/consts/const-eval/format.stderr
+++ b/src/test/ui/consts/const-eval/format.stderr
@@ -8,7 +8,7 @@ LL | panic!("{:?}", 0);
= note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0015]: cannot call non-const formatting macro in constant functions
- --> $DIR/format.rs:9:22
+ --> $DIR/format.rs:7:22
|
LL | println!("{:?}", 0);
| ^
@@ -17,7 +17,7 @@ LL | println!("{:?}", 0);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `Arguments::<'a>::new_v1` is not yet stable as a const fn
- --> $DIR/format.rs:9:5
+ --> $DIR/format.rs:7:5
|
LL | println!("{:?}", 0);
| ^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | println!("{:?}", 0);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0015]: cannot call non-const fn `_print` in constant functions
- --> $DIR/format.rs:9:5
+ --> $DIR/format.rs:7:5
|
LL | println!("{:?}", 0);
| ^^^^^^^^^^^^^^^^^^^
@@ -34,35 +34,62 @@ LL | println!("{:?}", 0);
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/format.rs:2:12
|
LL | panic!("{:?}", 0);
- | ^^^^^^ referenced constant has errors
+ | ^^^^^^
-error[E0080]: erroneous constant used
+note: erroneous constant used
+ --> $DIR/format.rs:2:12
+ |
+LL | panic!("{:?}", 0);
+ | ^^^^^^
+
+note: erroneous constant used
--> $DIR/format.rs:2:20
|
LL | panic!("{:?}", 0);
- | ^ referenced constant has errors
+ | ^
|
- = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/format.rs:2:20
+ |
+LL | panic!("{:?}", 0);
+ | ^
+ |
+ = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0080]: erroneous constant used
- --> $DIR/format.rs:9:14
+note: erroneous constant used
+ --> $DIR/format.rs:7:14
|
LL | println!("{:?}", 0);
- | ^^^^^^ referenced constant has errors
+ | ^^^^^^
-error[E0080]: erroneous constant used
- --> $DIR/format.rs:9:22
+note: erroneous constant used
+ --> $DIR/format.rs:7:14
|
LL | println!("{:?}", 0);
- | ^ referenced constant has errors
+ | ^^^^^^
+
+note: erroneous constant used
+ --> $DIR/format.rs:7:22
|
- = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+LL | println!("{:?}", 0);
+ | ^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/format.rs:7:22
+ |
+LL | println!("{:?}", 0);
+ | ^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to 8 previous errors
+error: aborting due to 4 previous errors
-Some errors have detailed explanations: E0015, E0080.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr
index 2628a7845..8f3b3d5f7 100644
--- a/src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr
+++ b/src/test/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr
@@ -1,14 +1,19 @@
error[E0080]: evaluation of constant value failed
--> $DIR/alloc_intrinsic_errors.rs:9:17
|
-LL | const FOO: i32 = foo();
- | ----- inside `FOO` at $DIR/alloc_intrinsic_errors.rs:6:18
-...
+LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ align has to be a power of 2, `3` is not a power of 2
+ |
+note: inside `foo`
+ --> $DIR/alloc_intrinsic_errors.rs:9:17
+ |
LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | align has to be a power of 2, `3` is not a power of 2
- | inside `foo` at $DIR/alloc_intrinsic_errors.rs:9:17
+note: inside `FOO`
+ --> $DIR/alloc_intrinsic_errors.rs:6:18
+ |
+LL | const FOO: i32 = foo();
+ | ^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/consts/const-eval/issue-104390.rs b/src/test/ui/consts/const-eval/issue-104390.rs
new file mode 100644
index 000000000..602d81824
--- /dev/null
+++ b/src/test/ui/consts/const-eval/issue-104390.rs
@@ -0,0 +1,10 @@
+fn f1() -> impl Sized { & 2E } //~ ERROR expected at least one digit in exponent
+fn f2() -> impl Sized { && 2E } //~ ERROR expected at least one digit in exponent
+fn f3() -> impl Sized { &'a 2E } //~ ERROR expected at least one digit in exponent
+//~^ ERROR borrow expressions cannot be annotated with lifetimes
+fn f4() -> impl Sized { &'static 2E } //~ ERROR expected at least one digit in exponent
+//~^ ERROR borrow expressions cannot be annotated with lifetimes
+fn f5() -> impl Sized { *& 2E } //~ ERROR expected at least one digit in exponent
+fn f6() -> impl Sized { &'_ 2E } //~ ERROR expected at least one digit in exponent
+//~^ ERROR borrow expressions cannot be annotated with lifetimes
+fn main() {}
diff --git a/src/test/ui/consts/const-eval/issue-104390.stderr b/src/test/ui/consts/const-eval/issue-104390.stderr
new file mode 100644
index 000000000..865b9996e
--- /dev/null
+++ b/src/test/ui/consts/const-eval/issue-104390.stderr
@@ -0,0 +1,65 @@
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:1:27
+ |
+LL | fn f1() -> impl Sized { & 2E }
+ | ^^
+
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:2:28
+ |
+LL | fn f2() -> impl Sized { && 2E }
+ | ^^
+
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:3:29
+ |
+LL | fn f3() -> impl Sized { &'a 2E }
+ | ^^
+
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:5:34
+ |
+LL | fn f4() -> impl Sized { &'static 2E }
+ | ^^
+
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:7:28
+ |
+LL | fn f5() -> impl Sized { *& 2E }
+ | ^^
+
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:8:29
+ |
+LL | fn f6() -> impl Sized { &'_ 2E }
+ | ^^
+
+error: borrow expressions cannot be annotated with lifetimes
+ --> $DIR/issue-104390.rs:3:25
+ |
+LL | fn f3() -> impl Sized { &'a 2E }
+ | ^--^^^
+ | |
+ | annotated with lifetime here
+ | help: remove the lifetime annotation
+
+error: borrow expressions cannot be annotated with lifetimes
+ --> $DIR/issue-104390.rs:5:25
+ |
+LL | fn f4() -> impl Sized { &'static 2E }
+ | ^-------^^^
+ | |
+ | annotated with lifetime here
+ | help: remove the lifetime annotation
+
+error: borrow expressions cannot be annotated with lifetimes
+ --> $DIR/issue-104390.rs:8:25
+ |
+LL | fn f6() -> impl Sized { &'_ 2E }
+ | ^--^^^
+ | |
+ | annotated with lifetime here
+ | help: remove the lifetime annotation
+
+error: aborting due to 9 previous errors
+
diff --git a/src/test/ui/consts/const-eval/issue-44578.rs b/src/test/ui/consts/const-eval/issue-44578.rs
index 2dbe1c2bd..e4dcc6230 100644
--- a/src/test/ui/consts/const-eval/issue-44578.rs
+++ b/src/test/ui/consts/const-eval/issue-44578.rs
@@ -23,6 +23,5 @@ impl Foo for u16 {
fn main() {
println!("{}", <Bar<u16, u8> as Foo>::AMT);
- //~^ ERROR evaluation of constant value failed
- //~| ERROR erroneous constant used
+ //~^ constant
}
diff --git a/src/test/ui/consts/const-eval/issue-44578.stderr b/src/test/ui/consts/const-eval/issue-44578.stderr
index 963381b58..0cbf54480 100644
--- a/src/test/ui/consts/const-eval/issue-44578.stderr
+++ b/src/test/ui/consts/const-eval/issue-44578.stderr
@@ -4,20 +4,36 @@ error[E0080]: evaluation of `<Bar<u16, u8> as Foo>::AMT` failed
LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-44578.rs:25:20
|
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/issue-44578.rs:25:20
|
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to 3 previous errors
+note: erroneous constant used
+ --> $DIR/issue-44578.rs:25:20
+ |
+LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/issue-44578.rs:25:20
+ |
+LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/issue-50814-2.rs b/src/test/ui/consts/const-eval/issue-50814-2.rs
index 49d1d8ff0..53eb7b149 100644
--- a/src/test/ui/consts/const-eval/issue-50814-2.rs
+++ b/src/test/ui/consts/const-eval/issue-50814-2.rs
@@ -15,7 +15,7 @@ impl<T: C> Foo<T> for A<T> {
}
fn foo<T: C>() -> &'static usize {
- &<A<T> as Foo<T>>::BAR //~ ERROR E0080
+ &<A<T> as Foo<T>>::BAR //~ constant
}
impl C for () {
diff --git a/src/test/ui/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr
index 6604f2b9f..956f7aec9 100644
--- a/src/test/ui/consts/const-eval/issue-50814-2.stderr
+++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr
@@ -4,11 +4,11 @@ error[E0080]: evaluation of `<A<()> as Foo<()>>::BAR` failed
LL | const BAR: usize = [5, 6, 7][T::BOO];
| ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42
-error[E0080]: evaluation of `foo::<()>` failed
+note: erroneous constant used
--> $DIR/issue-50814-2.rs:18:6
|
LL | &<A<T> as Foo<T>>::BAR
- | ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^
note: the above error was encountered while instantiating `fn foo::<()>`
--> $DIR/issue-50814-2.rs:30:22
@@ -16,6 +16,6 @@ note: the above error was encountered while instantiating `fn foo::<()>`
LL | println!("{:x}", foo::<()>() as *const usize as usize);
| ^^^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/issue-50814.rs b/src/test/ui/consts/const-eval/issue-50814.rs
index 5a587701f..374ed1d93 100644
--- a/src/test/ui/consts/const-eval/issue-50814.rs
+++ b/src/test/ui/consts/const-eval/issue-50814.rs
@@ -9,16 +9,16 @@ impl Unsigned for U8 {
const MAX: u8 = 0xff;
}
-struct Sum<A,B>(A,B);
+struct Sum<A, B>(A, B);
-impl<A: Unsigned, B: Unsigned> Unsigned for Sum<A,B> {
+impl<A: Unsigned, B: Unsigned> Unsigned for Sum<A, B> {
const MAX: u8 = A::MAX + B::MAX;
//~^ ERROR evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
}
fn foo<T>(_: T) -> &'static u8 {
- &Sum::<U8,U8>::MAX
- //~^ ERROR E0080
+ &Sum::<U8, U8>::MAX
+ //~^ constant
}
fn main() {
diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr
index 46dd2b89f..05b6271f4 100644
--- a/src/test/ui/consts/const-eval/issue-50814.stderr
+++ b/src/test/ui/consts/const-eval/issue-50814.stderr
@@ -4,11 +4,11 @@ error[E0080]: evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
LL | const MAX: u8 = A::MAX + B::MAX;
| ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
-error[E0080]: evaluation of `foo::<i32>` failed
+note: erroneous constant used
--> $DIR/issue-50814.rs:20:6
|
-LL | &Sum::<U8,U8>::MAX
- | ^^^^^^^^^^^^^^^^^ referenced constant has errors
+LL | &Sum::<U8, U8>::MAX
+ | ^^^^^^^^^^^^^^^^^^
note: the above error was encountered while instantiating `fn foo::<i32>`
--> $DIR/issue-50814.rs:25:5
@@ -16,6 +16,6 @@ note: the above error was encountered while instantiating `fn foo::<i32>`
LL | foo(0);
| ^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.rs b/src/test/ui/consts/const-eval/panic-assoc-never-type.rs
index d2a840932..28edf5144 100644
--- a/src/test/ui/consts/const-eval/panic-assoc-never-type.rs
+++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.rs
@@ -11,6 +11,5 @@ impl PrintName {
}
fn main() {
- let _ = PrintName::VOID;
- //~^ ERROR erroneous constant used [E0080]
+ let _ = PrintName::VOID; //~ constant
}
diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr
index 4204d302b..7c36a3a42 100644
--- a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr
+++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr
@@ -6,12 +6,18 @@ LL | const VOID: ! = panic!();
|
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/panic-assoc-never-type.rs:14:13
|
LL | let _ = PrintName::VOID;
- | ^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^
-error: aborting due to 2 previous errors
+note: erroneous constant used
+ --> $DIR/panic-assoc-never-type.rs:14:13
+ |
+LL | let _ = PrintName::VOID;
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr b/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr
index 596fa090d..2d4e7c83d 100644
--- a/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr
+++ b/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_const_fn_fail.rs:17:27
|
LL | let x: &'static u8 = &(bar() + 1);
- | ----------- ^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ----------- ^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
diff --git a/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr b/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr
index 63dc43a41..9ebae3a18 100644
--- a/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr
+++ b/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_const_fn_fail_deny_const_err.rs:18:27
|
LL | let x: &'static u8 = &(bar() + 1);
- | ----------- ^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ----------- ^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
diff --git a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr
index 8ac60da38..01fcf2ec2 100644
--- a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr
+++ b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_raw_ptr_ops.rs:2:29
|
LL | let x: &'static bool = &(42 as *const i32 == 43 as *const i32);
- | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_raw_ptr_ops.rs:4:30
|
LL | let y: &'static usize = &(&1 as *const i32 as usize + 1);
- | -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_raw_ptr_ops.rs:6:28
|
LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) });
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -35,7 +35,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_raw_ptr_ops.rs:8:29
|
LL | let a: &'static bool = &(main as fn() == main as fn());
- | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL |
diff --git a/src/test/ui/consts/const-eval/transmute-const-promotion.stderr b/src/test/ui/consts/const-eval/transmute-const-promotion.stderr
index 15b9b56ea..434a957f6 100644
--- a/src/test/ui/consts/const-eval/transmute-const-promotion.stderr
+++ b/src/test/ui/consts/const-eval/transmute-const-promotion.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/transmute-const-promotion.rs:4:37
|
LL | let x: &'static u32 = unsafe { &mem::transmute(3.0f32) };
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL |
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr
index dbd05b8f4..b24e0cc37 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr
@@ -65,6 +65,17 @@ LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
14 00 00 00 │ ....
}
-error: aborting due to 7 previous errors
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-nonnull.rs:50:1
+ |
+LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ 00 00 00 00 ╾─alloc26─╼ │ ....╾──╼
+ }
+
+error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr
index 5a1ac09bd..92b8d017c 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr
@@ -65,6 +65,17 @@ LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
14 00 00 00 │ ....
}
-error: aborting due to 7 previous errors
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-nonnull.rs:50:1
+ |
+LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ 00 00 00 00 00 00 00 00 ╾───────alloc26───────╼ │ ........╾──────╼
+ }
+
+error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.rs b/src/test/ui/consts/const-eval/ub-nonnull.rs
index d22a99cd0..490925822 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.rs
+++ b/src/test/ui/consts/const-eval/ub-nonnull.rs
@@ -1,5 +1,5 @@
// stderr-per-bitwidth
-#![feature(rustc_attrs)]
+#![feature(rustc_attrs, ptr_metadata)]
#![allow(invalid_value)] // make sure we cannot allow away the errors tested here
use std::mem;
@@ -47,4 +47,11 @@ struct RestrictedRange2(u32);
const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
//~^ ERROR it is undefined behavior to use this value
+const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
+//~^ ERROR it is undefined behavior to use this value
+ let x: &dyn Send = &42;
+ let meta = std::ptr::metadata(x);
+ mem::transmute((0_usize, meta))
+};
+
fn main() {}
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
index 6f5c028cb..e5b5c7a84 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr
@@ -60,14 +60,14 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/ub-ref-ptr.rs:34:38
|
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:38:86
+ --> $DIR/ub-ref-ptr.rs:37:86
|
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
| ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -75,14 +75,14 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:38:85
+note: erroneous constant used
+ --> $DIR/ub-ref-ptr.rs:37:85
|
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
- | ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:42:1
+ --> $DIR/ub-ref-ptr.rs:40:1
|
LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (address 0x539 is unallocated)
@@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:45:1
+ --> $DIR/ub-ref-ptr.rs:43:1
|
LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (address 0x539 is unallocated)
@@ -104,13 +104,13 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:48:41
+ --> $DIR/ub-ref-ptr.rs:46:41
|
LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:52:1
+ --> $DIR/ub-ref-ptr.rs:50:1
|
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
@@ -121,13 +121,13 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:54:38
+ --> $DIR/ub-ref-ptr.rs:52:38
|
LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:57:1
+ --> $DIR/ub-ref-ptr.rs:55:1
|
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
@@ -138,7 +138,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:59:1
+ --> $DIR/ub-ref-ptr.rs:57:1
|
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer
@@ -148,6 +148,6 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
╾─alloc41─╼ │ ╾──╼
}
-error: aborting due to 16 previous errors
+error: aborting due to 14 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
index 5ffb710d4..607366cab 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr
@@ -60,14 +60,14 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/ub-ref-ptr.rs:34:38
|
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:38:86
+ --> $DIR/ub-ref-ptr.rs:37:86
|
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
| ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
@@ -75,14 +75,14 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us
= help: this code performed an operation that depends on the underlying bytes representing a pointer
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
-error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:38:85
+note: erroneous constant used
+ --> $DIR/ub-ref-ptr.rs:37:85
|
LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
- | ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:42:1
+ --> $DIR/ub-ref-ptr.rs:40:1
|
LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (address 0x539 is unallocated)
@@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:45:1
+ --> $DIR/ub-ref-ptr.rs:43:1
|
LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (address 0x539 is unallocated)
@@ -104,13 +104,13 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:48:41
+ --> $DIR/ub-ref-ptr.rs:46:41
|
LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:52:1
+ --> $DIR/ub-ref-ptr.rs:50:1
|
LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
@@ -121,13 +121,13 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
}
error[E0080]: evaluation of constant value failed
- --> $DIR/ub-ref-ptr.rs:54:38
+ --> $DIR/ub-ref-ptr.rs:52:38
|
LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:57:1
+ --> $DIR/ub-ref-ptr.rs:55:1
|
LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
@@ -138,7 +138,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
}
error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-ref-ptr.rs:59:1
+ --> $DIR/ub-ref-ptr.rs:57:1
|
LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer
@@ -148,6 +148,6 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
╾───────alloc41───────╼ │ ╾──────╼
}
-error: aborting due to 16 previous errors
+error: aborting due to 14 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.rs b/src/test/ui/consts/const-eval/ub-ref-ptr.rs
index 92049d4c1..a1c812390 100644
--- a/src/test/ui/consts/const-eval/ub-ref-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-ref-ptr.rs
@@ -33,11 +33,9 @@ const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
//~^ ERROR evaluation of constant value failed
-//~| ERROR evaluation of constant value failed
const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
//~^ ERROR evaluation of constant value failed
-//~| ERROR evaluation of constant value failed
const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
//~^ ERROR it is undefined behavior to use this value
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
index c8b46608d..9994c2e5a 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr
@@ -139,11 +139,11 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
╾─allocN─╼ │ ╾──╼
}
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/ub-wide-ptr.rs:83:40
|
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:90:1
@@ -156,11 +156,11 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
╾allocN─╼ │ ╾──╼
}
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/ub-wide-ptr.rs:90:42
|
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:94:1
@@ -173,11 +173,11 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
╾allocN─╼ │ ╾──╼
}
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/ub-wide-ptr.rs:94:42
|
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:102:1
@@ -292,6 +292,6 @@ error[E0080]: could not evaluate static initializer
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
-error: aborting due to 32 previous errors
+error: aborting due to 29 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
index 70574d2dc..06a377d9f 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr
@@ -139,11 +139,11 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
╾───────allocN───────╼ │ ╾──────╼
}
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/ub-wide-ptr.rs:83:40
|
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:90:1
@@ -156,11 +156,11 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3
╾──────allocN───────╼ │ ╾──────╼
}
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/ub-wide-ptr.rs:90:42
|
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:94:1
@@ -173,11 +173,11 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran
╾──────allocN───────╼ │ ╾──────╼
}
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/ub-wide-ptr.rs:94:42
|
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $DIR/ub-wide-ptr.rs:102:1
@@ -292,6 +292,6 @@ error[E0080]: could not evaluate static initializer
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
-error: aborting due to 32 previous errors
+error: aborting due to 29 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
index 65f6f0235..2894ef831 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
@@ -82,18 +82,18 @@ const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
// bad data *inside* the slice
const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
//~^ ERROR it is undefined behavior to use this value
-//~| ERROR evaluation of constant value failed
+//~| constant
// good MySliceBool
const MYSLICE_GOOD: &MySliceBool = &MySlice(true, [false]);
// bad: sized field is not okay
const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
//~^ ERROR it is undefined behavior to use this value
-//~| ERROR evaluation of constant value failed
+//~| constant
// bad: unsized part is not okay
const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
//~^ ERROR it is undefined behavior to use this value
-//~| ERROR evaluation of constant value failed
+//~| constant
// # raw slice
const RAW_SLICE_VALID: *const [u8] = unsafe { mem::transmute((&42u8, 1usize)) }; // ok
diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.rs b/src/test/ui/consts/const-eval/union-const-eval-field.rs
index d88bf2a84..a94fcbbfa 100644
--- a/src/test/ui/consts/const-eval/union-const-eval-field.rs
+++ b/src/test/ui/consts/const-eval/union-const-eval-field.rs
@@ -29,7 +29,6 @@ const fn read_field3() -> Field3 {
//~^ ERROR evaluation of constant value failed
//~| uninitialized
FIELD3
- //~^ ERROR erroneous constant used [E0080]
}
fn main() {
diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.stderr
index 00964489e..9899c56c0 100644
--- a/src/test/ui/consts/const-eval/union-const-eval-field.stderr
+++ b/src/test/ui/consts/const-eval/union-const-eval-field.stderr
@@ -4,12 +4,18 @@ error[E0080]: evaluation of constant value failed
LL | const FIELD3: Field3 = unsafe { UNION.field3 };
| ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/union-const-eval-field.rs:31:5
|
LL | FIELD3
- | ^^^^^^ referenced constant has errors
+ | ^^^^^^
-error: aborting due to 2 previous errors
+note: erroneous constant used
+ --> $DIR/union-const-eval-field.rs:31:5
+ |
+LL | FIELD3
+ | ^^^^^^
+
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/union_promotion.stderr b/src/test/ui/consts/const-eval/union_promotion.stderr
index 70808c520..42f17de20 100644
--- a/src/test/ui/consts/const-eval/union_promotion.stderr
+++ b/src/test/ui/consts/const-eval/union_promotion.stderr
@@ -7,7 +7,7 @@ LL | let x: &'static bool = &unsafe {
| | type annotation requires that borrow lasts for `'static`
LL | | Foo { a: &1 }.b == Foo { a: &2 }.b
LL | | };
- | |_____^ creates a temporary which is freed while still in use
+ | |_____^ creates a temporary value which is freed while still in use
LL | }
| - temporary value is freed at the end of this statement
diff --git a/src/test/ui/consts/const-eval/unwind-abort.stderr b/src/test/ui/consts/const-eval/unwind-abort.stderr
index 99178ae8c..759ce15ab 100644
--- a/src/test/ui/consts/const-eval/unwind-abort.stderr
+++ b/src/test/ui/consts/const-eval/unwind-abort.stderr
@@ -2,14 +2,18 @@ error[E0080]: evaluation of constant value failed
--> $DIR/unwind-abort.rs:4:5
|
LL | panic!()
+ | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/unwind-abort.rs:4:5
+ |
+note: inside `foo`
+ --> $DIR/unwind-abort.rs:4:5
+ |
+LL | panic!()
| ^^^^^^^^
- | |
- | the evaluated program panicked at 'explicit panic', $DIR/unwind-abort.rs:4:5
- | inside `foo` at $SRC_DIR/std/src/panic.rs:LL:COL
-...
-LL | const _: () = foo();
- | ----- inside `_` at $DIR/unwind-abort.rs:7:15
+note: inside `_`
+ --> $DIR/unwind-abort.rs:7:15
|
+LL | const _: () = foo();
+ | ^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
index 63639729a..9710bf476 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
@@ -14,13 +14,18 @@ error[E0080]: evaluation of constant value failed
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
LL | unsafe { std::mem::transmute(()) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+ |
+note: inside `foo`
+ --> $DIR/validate_uninhabited_zsts.rs:4:14
+ |
+LL | unsafe { std::mem::transmute(()) }
| ^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | transmuting to uninhabited type
- | inside `foo` at $DIR/validate_uninhabited_zsts.rs:4:14
-...
+note: inside `FOO`
+ --> $DIR/validate_uninhabited_zsts.rs:19:33
+ |
LL | const FOO: [empty::Empty; 3] = [foo(); 3];
- | ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:19:33
+ | ^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/validate_uninhabited_zsts.rs:21:1
@@ -40,6 +45,11 @@ LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
+note: in this struct field
+ --> $DIR/validate_uninhabited_zsts.rs:16:22
+ |
+LL | pub struct Empty(Void);
+ | ^^^^
note: enums with no inhabited variants have no valid value
--> $DIR/validate_uninhabited_zsts.rs:13:5
|
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
index 63639729a..9710bf476 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
@@ -14,13 +14,18 @@ error[E0080]: evaluation of constant value failed
--> $DIR/validate_uninhabited_zsts.rs:4:14
|
LL | unsafe { std::mem::transmute(()) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+ |
+note: inside `foo`
+ --> $DIR/validate_uninhabited_zsts.rs:4:14
+ |
+LL | unsafe { std::mem::transmute(()) }
| ^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | transmuting to uninhabited type
- | inside `foo` at $DIR/validate_uninhabited_zsts.rs:4:14
-...
+note: inside `FOO`
+ --> $DIR/validate_uninhabited_zsts.rs:19:33
+ |
LL | const FOO: [empty::Empty; 3] = [foo(); 3];
- | ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:19:33
+ | ^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/validate_uninhabited_zsts.rs:21:1
@@ -40,6 +45,11 @@ LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
+note: in this struct field
+ --> $DIR/validate_uninhabited_zsts.rs:16:22
+ |
+LL | pub struct Empty(Void);
+ | ^^^^
note: enums with no inhabited variants have no valid value
--> $DIR/validate_uninhabited_zsts.rs:13:5
|
diff --git a/src/test/ui/consts/const-float-bits-reject-conv.rs b/src/test/ui/consts/const-float-bits-reject-conv.rs
index 5bf54fdbb..c77e99abb 100644
--- a/src/test/ui/consts/const-float-bits-reject-conv.rs
+++ b/src/test/ui/consts/const-float-bits-reject-conv.rs
@@ -1,4 +1,5 @@
// compile-flags: -Zmir-opt-level=0
+// error-pattern: cannot use f32::to_bits on a NaN
#![feature(const_float_bits_conv)]
#![feature(const_float_classify)]
@@ -25,22 +26,21 @@ fn f32() {
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
// ...actually, let's just check that these break. :D
const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA;
+ //~^ inside
const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555;
+ //~^ inside
+
+ // The rest of the code is dead because the constants already fail to evaluate.
const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
- //~^ ERROR evaluation of constant value failed
const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
- //~^ ERROR evaluation of constant value failed
// LLVM does not guarantee that loads and stores of NaNs preserve their exact bit pattern.
// In practice, this seems to only cause a problem on x86, since the most widely used calling
// convention mandates that floating point values are returned on the x87 FPU stack. See #73328.
- if !cfg!(target_arch = "x86") {
- const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
- //~^ ERROR evaluation of constant value failed
- const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
- //~^ ERROR evaluation of constant value failed
- }
+ // However, during CTFE we still preserve bit patterns (though that is not a guarantee).
+ const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
+ const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
}
fn f64() {
@@ -48,20 +48,18 @@ fn f64() {
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
// ...actually, let's just check that these break. :D
const MASKED_NAN1: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
+ //~^ inside
const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
+ //~^ inside
+
+ // The rest of the code is dead because the constants already fail to evaluate.
const_assert!(f64::from_bits(MASKED_NAN1).is_nan());
- //~^ ERROR evaluation of constant value failed
const_assert!(f64::from_bits(MASKED_NAN1).is_nan());
- //~^ ERROR evaluation of constant value failed
// See comment above.
- if !cfg!(target_arch = "x86") {
- const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
- //~^ ERROR evaluation of constant value failed
- const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
- //~^ ERROR evaluation of constant value failed
- }
+ const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
+ const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
}
fn main() {
diff --git a/src/test/ui/consts/const-float-bits-reject-conv.stderr b/src/test/ui/consts/const-float-bits-reject-conv.stderr
index b3575f641..195a087ff 100644
--- a/src/test/ui/consts/const-float-bits-reject-conv.stderr
+++ b/src/test/ui/consts/const-float-bits-reject-conv.stderr
@@ -2,126 +2,142 @@ error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/num/f32.rs:LL:COL
|
LL | panic!("const-eval error: cannot use f32::to_bits on a NaN")
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'const-eval error: cannot use f32::to_bits on a NaN', $SRC_DIR/core/src/num/f32.rs:LL:COL
+ |
+note: inside `core::f32::<impl f32>::to_bits::ct_f32_to_u32`
+ --> $SRC_DIR/core/src/num/f32.rs:LL:COL
+ |
+LL | panic!("const-eval error: cannot use f32::to_bits on a NaN")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | the evaluated program panicked at 'const-eval error: cannot use f32::to_bits on a NaN', $SRC_DIR/core/src/num/f32.rs:LL:COL
- | inside `core::f32::<impl f32>::to_bits::ct_f32_to_u32` at $SRC_DIR/core/src/panic.rs:LL:COL
-...
-LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) }
- | -------------------------------------------------------------------- inside `core::f32::<impl f32>::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL
+note: inside `core::f32::<impl f32>::to_bits`
+ --> $SRC_DIR/core/src/num/f32.rs:LL:COL
|
- ::: $DIR/const-float-bits-reject-conv.rs:27:30
+LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `f32::MASKED_NAN1`
+ --> $DIR/const-float-bits-reject-conv.rs:28:30
|
LL | const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA;
- | ------------------ inside `f32::MASKED_NAN1` at $DIR/const-float-bits-reject-conv.rs:27:30
- |
+ | ^^^^^^^^^^^^^^^^^^
= 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[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/num/f32.rs:LL:COL
|
LL | panic!("const-eval error: cannot use f32::to_bits on a NaN")
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'const-eval error: cannot use f32::to_bits on a NaN', $SRC_DIR/core/src/num/f32.rs:LL:COL
+ |
+note: inside `core::f32::<impl f32>::to_bits::ct_f32_to_u32`
+ --> $SRC_DIR/core/src/num/f32.rs:LL:COL
+ |
+LL | panic!("const-eval error: cannot use f32::to_bits on a NaN")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | the evaluated program panicked at 'const-eval error: cannot use f32::to_bits on a NaN', $SRC_DIR/core/src/num/f32.rs:LL:COL
- | inside `core::f32::<impl f32>::to_bits::ct_f32_to_u32` at $SRC_DIR/core/src/panic.rs:LL:COL
-...
-LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) }
- | -------------------------------------------------------------------- inside `core::f32::<impl f32>::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL
+note: inside `core::f32::<impl f32>::to_bits`
+ --> $SRC_DIR/core/src/num/f32.rs:LL:COL
|
- ::: $DIR/const-float-bits-reject-conv.rs:28:30
+LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `f32::MASKED_NAN2`
+ --> $DIR/const-float-bits-reject-conv.rs:30:30
|
LL | const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555;
- | ------------------ inside `f32::MASKED_NAN2` at $DIR/const-float-bits-reject-conv.rs:28:30
- |
+ | ^^^^^^^^^^^^^^^^^^
= 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[E0080]: evaluation of constant value failed
- --> $DIR/const-float-bits-reject-conv.rs:30:34
+note: erroneous constant used
+ --> $DIR/const-float-bits-reject-conv.rs:35:34
|
LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
- | ^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^
-error[E0080]: evaluation of constant value failed
- --> $DIR/const-float-bits-reject-conv.rs:32:34
+note: erroneous constant used
+ --> $DIR/const-float-bits-reject-conv.rs:36:34
|
LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan());
- | ^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^
-error[E0080]: evaluation of constant value failed
- --> $DIR/const-float-bits-reject-conv.rs:39:38
+note: erroneous constant used
+ --> $DIR/const-float-bits-reject-conv.rs:42:34
|
-LL | const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
- | ^^^^^^^^^^^ referenced constant has errors
+LL | const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
+ | ^^^^^^^^^^^
-error[E0080]: evaluation of constant value failed
- --> $DIR/const-float-bits-reject-conv.rs:41:38
+note: erroneous constant used
+ --> $DIR/const-float-bits-reject-conv.rs:43:34
|
-LL | const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
- | ^^^^^^^^^^^ referenced constant has errors
+LL | const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
+ | ^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/num/f64.rs:LL:COL
|
LL | panic!("const-eval error: cannot use f64::to_bits on a NaN")
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'const-eval error: cannot use f64::to_bits on a NaN', $SRC_DIR/core/src/num/f64.rs:LL:COL
+ |
+note: inside `core::f64::<impl f64>::to_bits::ct_f64_to_u64`
+ --> $SRC_DIR/core/src/num/f64.rs:LL:COL
+ |
+LL | panic!("const-eval error: cannot use f64::to_bits on a NaN")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | the evaluated program panicked at 'const-eval error: cannot use f64::to_bits on a NaN', $SRC_DIR/core/src/num/f64.rs:LL:COL
- | inside `core::f64::<impl f64>::to_bits::ct_f64_to_u64` at $SRC_DIR/core/src/panic.rs:LL:COL
-...
-LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) }
- | -------------------------------------------------------------------- inside `core::f64::<impl f64>::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL
+note: inside `core::f64::<impl f64>::to_bits`
+ --> $SRC_DIR/core/src/num/f64.rs:LL:COL
|
- ::: $DIR/const-float-bits-reject-conv.rs:50:30
+LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `f64::MASKED_NAN1`
+ --> $DIR/const-float-bits-reject-conv.rs:50:30
|
LL | const MASKED_NAN1: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
- | ------------------ inside `f64::MASKED_NAN1` at $DIR/const-float-bits-reject-conv.rs:50:30
- |
+ | ^^^^^^^^^^^^^^^^^^
= 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[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/num/f64.rs:LL:COL
|
LL | panic!("const-eval error: cannot use f64::to_bits on a NaN")
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'const-eval error: cannot use f64::to_bits on a NaN', $SRC_DIR/core/src/num/f64.rs:LL:COL
+ |
+note: inside `core::f64::<impl f64>::to_bits::ct_f64_to_u64`
+ --> $SRC_DIR/core/src/num/f64.rs:LL:COL
+ |
+LL | panic!("const-eval error: cannot use f64::to_bits on a NaN")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | the evaluated program panicked at 'const-eval error: cannot use f64::to_bits on a NaN', $SRC_DIR/core/src/num/f64.rs:LL:COL
- | inside `core::f64::<impl f64>::to_bits::ct_f64_to_u64` at $SRC_DIR/core/src/panic.rs:LL:COL
-...
-LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) }
- | -------------------------------------------------------------------- inside `core::f64::<impl f64>::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL
+note: inside `core::f64::<impl f64>::to_bits`
+ --> $SRC_DIR/core/src/num/f64.rs:LL:COL
|
- ::: $DIR/const-float-bits-reject-conv.rs:51:30
+LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `f64::MASKED_NAN2`
+ --> $DIR/const-float-bits-reject-conv.rs:52:30
|
LL | const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
- | ------------------ inside `f64::MASKED_NAN2` at $DIR/const-float-bits-reject-conv.rs:51:30
- |
+ | ^^^^^^^^^^^^^^^^^^
= 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[E0080]: evaluation of constant value failed
- --> $DIR/const-float-bits-reject-conv.rs:53:34
+note: erroneous constant used
+ --> $DIR/const-float-bits-reject-conv.rs:57:34
|
LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan());
- | ^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^
-error[E0080]: evaluation of constant value failed
- --> $DIR/const-float-bits-reject-conv.rs:55:34
+note: erroneous constant used
+ --> $DIR/const-float-bits-reject-conv.rs:58:34
|
LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan());
- | ^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^
-error[E0080]: evaluation of constant value failed
- --> $DIR/const-float-bits-reject-conv.rs:60:38
+note: erroneous constant used
+ --> $DIR/const-float-bits-reject-conv.rs:61:34
|
-LL | const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
- | ^^^^^^^^^^^ referenced constant has errors
+LL | const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1);
+ | ^^^^^^^^^^^
-error[E0080]: evaluation of constant value failed
- --> $DIR/const-float-bits-reject-conv.rs:62:38
+note: erroneous constant used
+ --> $DIR/const-float-bits-reject-conv.rs:62:34
|
-LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
- | ^^^^^^^^^^^ referenced constant has errors
+LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2);
+ | ^^^^^^^^^^^
-error: aborting due to 12 previous errors
+error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-int-conversion.stderr b/src/test/ui/consts/const-int-conversion.stderr
index 61162a792..5dd757e3f 100644
--- a/src/test/ui/consts/const-int-conversion.stderr
+++ b/src/test/ui/consts/const-int-conversion.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-conversion.rs:2:28
|
LL | let x: &'static i32 = &(5_i32.reverse_bits());
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-conversion.rs:4:28
|
LL | let y: &'static i32 = &(i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]));
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-conversion.rs:6:28
|
LL | let z: &'static i32 = &(i32::from_le_bytes([0x12, 0x34, 0x56, 0x78]));
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -35,7 +35,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-conversion.rs:8:28
|
LL | let a: &'static i32 = &(i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0])));
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -46,7 +46,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-conversion.rs:10:29
|
LL | let b: &'static [u8] = &(0x12_34_56_78_i32.to_be_bytes());
- | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -57,7 +57,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-conversion.rs:12:29
|
LL | let c: &'static [u8] = &(0x12_34_56_78_i32.to_le_bytes());
- | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -68,7 +68,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-conversion.rs:14:29
|
LL | let d: &'static [u8] = &(i32::MIN.to_be().to_ne_bytes());
- | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL |
diff --git a/src/test/ui/consts/const-int-overflowing.stderr b/src/test/ui/consts/const-int-overflowing.stderr
index 56c7f7f09..7d3689e6e 100644
--- a/src/test/ui/consts/const-int-overflowing.stderr
+++ b/src/test/ui/consts/const-int-overflowing.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-overflowing.rs:2:36
|
LL | let x: &'static (i32, bool) = &(5_i32.overflowing_add(3));
- | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-overflowing.rs:4:36
|
LL | let y: &'static (i32, bool) = &(5_i32.overflowing_sub(3));
- | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-overflowing.rs:6:36
|
LL | let z: &'static (i32, bool) = &(5_i32.overflowing_mul(3));
- | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL |
diff --git a/src/test/ui/consts/const-int-rotate.stderr b/src/test/ui/consts/const-int-rotate.stderr
index ed265804b..039da1c31 100644
--- a/src/test/ui/consts/const-int-rotate.stderr
+++ b/src/test/ui/consts/const-int-rotate.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-rotate.rs:2:28
|
LL | let x: &'static i32 = &(5_i32.rotate_left(3));
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-rotate.rs:4:28
|
LL | let y: &'static i32 = &(5_i32.rotate_right(3));
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL |
diff --git a/src/test/ui/consts/const-int-sign.stderr b/src/test/ui/consts/const-int-sign.stderr
index 5f8fd4141..fc23d9d2b 100644
--- a/src/test/ui/consts/const-int-sign.stderr
+++ b/src/test/ui/consts/const-int-sign.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-sign.rs:2:29
|
LL | let x: &'static bool = &(5_i32.is_negative());
- | ------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-sign.rs:4:29
|
LL | let y: &'static bool = &(5_i32.is_positive());
- | ------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL |
diff --git a/src/test/ui/consts/const-int-wrapping.stderr b/src/test/ui/consts/const-int-wrapping.stderr
index 5174b7265..1342fadc4 100644
--- a/src/test/ui/consts/const-int-wrapping.stderr
+++ b/src/test/ui/consts/const-int-wrapping.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-wrapping.rs:2:28
|
LL | let x: &'static i32 = &(5_i32.wrapping_add(3));
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-wrapping.rs:4:28
|
LL | let y: &'static i32 = &(5_i32.wrapping_sub(3));
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-wrapping.rs:6:28
|
LL | let z: &'static i32 = &(5_i32.wrapping_mul(3));
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -35,7 +35,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-wrapping.rs:8:28
|
LL | let a: &'static i32 = &(5_i32.wrapping_shl(3));
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -46,7 +46,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-int-wrapping.rs:10:28
|
LL | let b: &'static i32 = &(5_i32.wrapping_shr(3));
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL |
diff --git a/src/test/ui/consts/const-integer-bool-ops.rs b/src/test/ui/consts/const-integer-bool-ops.rs
index 6924956bd..4110ae3e4 100644
--- a/src/test/ui/consts/const-integer-bool-ops.rs
+++ b/src/test/ui/consts/const-integer-bool-ops.rs
@@ -6,7 +6,7 @@ const X: usize = 42 && 39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR: [i32; X] = [99; 34];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
const X1: usize = 42 || 39;
//~^ ERROR mismatched types
@@ -16,7 +16,7 @@ const X1: usize = 42 || 39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR1: [i32; X1] = [99; 47];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
const X2: usize = -42 || -39;
//~^ ERROR mismatched types
@@ -26,7 +26,7 @@ const X2: usize = -42 || -39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR2: [i32; X2] = [99; 18446744073709551607];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
const X3: usize = -42 && -39;
//~^ ERROR mismatched types
@@ -36,43 +36,43 @@ const X3: usize = -42 && -39;
//~| ERROR mismatched types
//~| expected `usize`, found `bool`
const ARR3: [i32; X3] = [99; 6];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
const Y: usize = 42.0 == 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR: [i32; Y] = [99; 1];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
const Y1: usize = 42.0 >= 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR1: [i32; Y1] = [99; 1];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
const Y2: usize = 42.0 <= 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR2: [i32; Y2] = [99; 1];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
const Y3: usize = 42.0 > 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR3: [i32; Y3] = [99; 0];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
const Y4: usize = 42.0 < 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR4: [i32; Y4] = [99; 0];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
const Y5: usize = 42.0 != 42.0;
//~^ ERROR mismatched types
//~| expected `usize`, found `bool`
const ARRR5: [i32; Y5] = [99; 0];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
fn main() {
let _ = ARR;
diff --git a/src/test/ui/consts/const-integer-bool-ops.stderr b/src/test/ui/consts/const-integer-bool-ops.stderr
index 9001fefd1..b5c3b22fd 100644
--- a/src/test/ui/consts/const-integer-bool-ops.stderr
+++ b/src/test/ui/consts/const-integer-bool-ops.stderr
@@ -16,11 +16,11 @@ error[E0308]: mismatched types
LL | const X: usize = 42 && 39;
| ^^^^^^^^ expected `usize`, found `bool`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-integer-bool-ops.rs:8:18
|
LL | const ARR: [i32; X] = [99; 34];
- | ^ referenced constant has errors
+ | ^
error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:11:19
@@ -40,11 +40,11 @@ error[E0308]: mismatched types
LL | const X1: usize = 42 || 39;
| ^^^^^^^^ expected `usize`, found `bool`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-integer-bool-ops.rs:18:19
|
LL | const ARR1: [i32; X1] = [99; 47];
- | ^^ referenced constant has errors
+ | ^^
error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:21:19
@@ -64,11 +64,11 @@ error[E0308]: mismatched types
LL | const X2: usize = -42 || -39;
| ^^^^^^^^^^ expected `usize`, found `bool`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-integer-bool-ops.rs:28:19
|
LL | const ARR2: [i32; X2] = [99; 18446744073709551607];
- | ^^ referenced constant has errors
+ | ^^
error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:31:19
@@ -88,11 +88,11 @@ error[E0308]: mismatched types
LL | const X3: usize = -42 && -39;
| ^^^^^^^^^^ expected `usize`, found `bool`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-integer-bool-ops.rs:38:19
|
LL | const ARR3: [i32; X3] = [99; 6];
- | ^^ referenced constant has errors
+ | ^^
error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:41:18
@@ -100,11 +100,11 @@ error[E0308]: mismatched types
LL | const Y: usize = 42.0 == 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-integer-bool-ops.rs:44:19
|
LL | const ARRR: [i32; Y] = [99; 1];
- | ^ referenced constant has errors
+ | ^
error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:47:19
@@ -112,11 +112,11 @@ error[E0308]: mismatched types
LL | const Y1: usize = 42.0 >= 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-integer-bool-ops.rs:50:20
|
LL | const ARRR1: [i32; Y1] = [99; 1];
- | ^^ referenced constant has errors
+ | ^^
error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:53:19
@@ -124,11 +124,11 @@ error[E0308]: mismatched types
LL | const Y2: usize = 42.0 <= 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-integer-bool-ops.rs:56:20
|
LL | const ARRR2: [i32; Y2] = [99; 1];
- | ^^ referenced constant has errors
+ | ^^
error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:59:19
@@ -136,11 +136,11 @@ error[E0308]: mismatched types
LL | const Y3: usize = 42.0 > 42.0;
| ^^^^^^^^^^^ expected `usize`, found `bool`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-integer-bool-ops.rs:62:20
|
LL | const ARRR3: [i32; Y3] = [99; 0];
- | ^^ referenced constant has errors
+ | ^^
error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:65:19
@@ -148,11 +148,11 @@ error[E0308]: mismatched types
LL | const Y4: usize = 42.0 < 42.0;
| ^^^^^^^^^^^ expected `usize`, found `bool`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-integer-bool-ops.rs:68:20
|
LL | const ARRR4: [i32; Y4] = [99; 0];
- | ^^ referenced constant has errors
+ | ^^
error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:71:19
@@ -160,13 +160,12 @@ error[E0308]: mismatched types
LL | const Y5: usize = 42.0 != 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-integer-bool-ops.rs:74:20
|
LL | const ARRR5: [i32; Y5] = [99; 0];
- | ^^ referenced constant has errors
+ | ^^
-error: aborting due to 28 previous errors
+error: aborting due to 18 previous errors
-Some errors have detailed explanations: E0080, E0308.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/consts/const-len-underflow-separate-spans.rs b/src/test/ui/consts/const-len-underflow-separate-spans.rs
index 478761aef..4544c8876 100644
--- a/src/test/ui/consts/const-len-underflow-separate-spans.rs
+++ b/src/test/ui/consts/const-len-underflow-separate-spans.rs
@@ -9,5 +9,5 @@ const LEN: usize = ONE - TWO;
fn main() {
let a: [i8; LEN] = unimplemented!();
-//~^ ERROR E0080
+//~^ constant
}
diff --git a/src/test/ui/consts/const-len-underflow-separate-spans.stderr b/src/test/ui/consts/const-len-underflow-separate-spans.stderr
index 1416e695e..269553631 100644
--- a/src/test/ui/consts/const-len-underflow-separate-spans.stderr
+++ b/src/test/ui/consts/const-len-underflow-separate-spans.stderr
@@ -4,12 +4,12 @@ error[E0080]: evaluation of constant value failed
LL | const LEN: usize = ONE - TWO;
| ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-len-underflow-separate-spans.rs:11:17
|
LL | let a: [i8; LEN] = unimplemented!();
- | ^^^ referenced constant has errors
+ | ^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr b/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr
index 0f420ae1b..109d15a8e 100644
--- a/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr
+++ b/src/test/ui/consts/const-mut-refs/issue-76510.32bit.stderr
@@ -19,13 +19,13 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
LL | const S: &'static mut str = &mut " hello ";
| ^^^^^^^^^^^^^^ cannot borrow as mutable
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-76510.rs:11:70
|
LL | let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3));
- | ^ referenced constant has errors
+ | ^
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
-Some errors have detailed explanations: E0080, E0596, E0658, E0764.
-For more information about an error, try `rustc --explain E0080`.
+Some errors have detailed explanations: E0596, E0658, E0764.
+For more information about an error, try `rustc --explain E0596`.
diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr b/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr
index 0f420ae1b..109d15a8e 100644
--- a/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr
+++ b/src/test/ui/consts/const-mut-refs/issue-76510.64bit.stderr
@@ -19,13 +19,13 @@ error[E0596]: cannot borrow data in a `&` reference as mutable
LL | const S: &'static mut str = &mut " hello ";
| ^^^^^^^^^^^^^^ cannot borrow as mutable
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-76510.rs:11:70
|
LL | let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3));
- | ^ referenced constant has errors
+ | ^
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
-Some errors have detailed explanations: E0080, E0596, E0658, E0764.
-For more information about an error, try `rustc --explain E0080`.
+Some errors have detailed explanations: E0596, E0658, E0764.
+For more information about an error, try `rustc --explain E0596`.
diff --git a/src/test/ui/consts/const-mut-refs/issue-76510.rs b/src/test/ui/consts/const-mut-refs/issue-76510.rs
index 08cf64ee3..b853e2737 100644
--- a/src/test/ui/consts/const-mut-refs/issue-76510.rs
+++ b/src/test/ui/consts/const-mut-refs/issue-76510.rs
@@ -9,7 +9,7 @@ const S: &'static mut str = &mut " hello ";
const fn trigger() -> [(); unsafe {
let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3));
- //~^ ERROR evaluation of constant value failed
+ //~^ constant
0
}] {
[(); 0]
diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr
index 3a9ce79f1..78c58b5ab 100644
--- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr
+++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr
@@ -11,7 +11,7 @@ LL | const B3: Option<&mut i32> = Some(&mut 42);
| ----------^^-
| | | |
| | | temporary value is freed at the end of this statement
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| using this value as a constant requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
@@ -21,7 +21,7 @@ LL | const B4: Option<&mut i32> = helper(&mut 42);
| ------------^^-
| | | |
| | | temporary value is freed at the end of this statement
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| using this value as a constant requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
@@ -31,7 +31,7 @@ LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
| -------------------------------^^--
| | | |
| | | temporary value is freed at the end of this statement
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| using this value as a constant requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
@@ -41,7 +41,7 @@ LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
| -------------------------------^^--
| | | |
| | | temporary value is freed at the end of this statement
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| using this value as a static requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
@@ -51,7 +51,7 @@ LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
| -------------------------------^^--
| | | |
| | | temporary value is freed at the end of this statement
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| using this value as a static requires that borrow lasts for `'static`
error: aborting due to 6 previous errors
diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr
index 234e55e3a..6e110dbdd 100644
--- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr
+++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr
@@ -2,13 +2,18 @@ error[E0080]: evaluation of constant value failed
--> $DIR/mut_ref_in_final_dynamic_check.rs:13:10
|
LL | Some(&mut *(42 as *mut i32))
+ | ^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x2a[noalloc] is a dangling pointer (it has no provenance)
+ |
+note: inside `helper`
+ --> $DIR/mut_ref_in_final_dynamic_check.rs:13:10
+ |
+LL | Some(&mut *(42 as *mut i32))
| ^^^^^^^^^^^^^^^^^^^^^^
- | |
- | dereferencing pointer failed: 0x2a[noalloc] is a dangling pointer (it has no provenance)
- | inside `helper` at $DIR/mut_ref_in_final_dynamic_check.rs:13:10
-...
+note: inside `A`
+ --> $DIR/mut_ref_in_final_dynamic_check.rs:18:29
+ |
LL | const A: Option<&mut i32> = helper();
- | -------- inside `A` at $DIR/mut_ref_in_final_dynamic_check.rs:18:29
+ | ^^^^^^^^
error: encountered dangling pointer in final constant
--> $DIR/mut_ref_in_final_dynamic_check.rs:25:1
diff --git a/src/test/ui/consts/const-ptr-nonnull.stderr b/src/test/ui/consts/const-ptr-nonnull.stderr
index 26946fb99..dbcb0c860 100644
--- a/src/test/ui/consts/const-ptr-nonnull.stderr
+++ b/src/test/ui/consts/const-ptr-nonnull.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-ptr-nonnull.rs:4:37
|
LL | let x: &'static NonNull<u32> = &(NonNull::dangling());
- | --------------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | --------------------- ^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-ptr-nonnull.rs:9:37
|
LL | let x: &'static NonNull<u32> = &(non_null.cast());
- | --------------------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | --------------------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL |
diff --git a/src/test/ui/consts/const-ptr-unique.stderr b/src/test/ui/consts/const-ptr-unique.stderr
index 3644cf4ce..83448c3e8 100644
--- a/src/test/ui/consts/const-ptr-unique.stderr
+++ b/src/test/ui/consts/const-ptr-unique.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/const-ptr-unique.rs:8:33
|
LL | let x: &'static *mut u32 = &(unique.as_ptr());
- | ----------------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ----------------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL |
diff --git a/src/test/ui/consts/const-tup-index-span.rs b/src/test/ui/consts/const-tup-index-span.rs
index 763263c6a..778a21224 100644
--- a/src/test/ui/consts/const-tup-index-span.rs
+++ b/src/test/ui/consts/const-tup-index-span.rs
@@ -4,7 +4,7 @@ const TUP: (usize,) = 5usize << 64;
//~^ ERROR mismatched types
//~| expected tuple, found `usize`
const ARR: [i32; TUP.0] = [];
-//~^ ERROR evaluation of constant value failed
+//~^ constant
fn main() {
}
diff --git a/src/test/ui/consts/const-tup-index-span.stderr b/src/test/ui/consts/const-tup-index-span.stderr
index b178e05e2..ad8468056 100644
--- a/src/test/ui/consts/const-tup-index-span.stderr
+++ b/src/test/ui/consts/const-tup-index-span.stderr
@@ -11,13 +11,12 @@ help: use a trailing comma to create a tuple with one element
LL | const TUP: (usize,) = (5usize << 64,);
| + ++
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/const-tup-index-span.rs:6:18
|
LL | const ARR: [i32; TUP.0] = [];
- | ^^^ referenced constant has errors
+ | ^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-Some errors have detailed explanations: E0080, E0308.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/consts/const_in_pattern/accept_structural.rs b/src/test/ui/consts/const_in_pattern/accept_structural.rs
index 5093fe539..1f56f581c 100644
--- a/src/test/ui/consts/const_in_pattern/accept_structural.rs
+++ b/src/test/ui/consts/const_in_pattern/accept_structural.rs
@@ -45,7 +45,7 @@ fn main() {
const TUPLE: (OND, OND) = (None, None);
match (None, None) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
- const TYPE_ASCRIPTION: OND = None: OND;
+ const TYPE_ASCRIPTION: OND = type_ascribe!(None, OND);
match None { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
const ARRAY: [OND; 2] = [None, None];
diff --git a/src/test/ui/consts/const_in_pattern/reject_non_structural.rs b/src/test/ui/consts/const_in_pattern/reject_non_structural.rs
index 7a8169bec..75fde0d92 100644
--- a/src/test/ui/consts/const_in_pattern/reject_non_structural.rs
+++ b/src/test/ui/consts/const_in_pattern/reject_non_structural.rs
@@ -53,7 +53,7 @@ fn main() {
match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
- const TYPE_ASCRIPTION: OND = Some(NoDerive): OND;
+ const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND);
match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
diff --git a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr
index f6de3699f..cbc7cac93 100644
--- a/src/test/ui/consts/const_unsafe_unreachable_ub.stderr
+++ b/src/test/ui/consts/const_unsafe_unreachable_ub.stderr
@@ -2,18 +2,23 @@ error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/hint.rs:LL:COL
|
LL | intrinsics::unreachable()
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | entering unreachable code
- | inside `unreachable_unchecked` at $SRC_DIR/core/src/hint.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ entering unreachable code
+ |
+note: inside `unreachable_unchecked`
+ --> $SRC_DIR/core/src/hint.rs:LL:COL
|
- ::: $DIR/const_unsafe_unreachable_ub.rs:6:18
+LL | intrinsics::unreachable()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `foo`
+ --> $DIR/const_unsafe_unreachable_ub.rs:6:18
|
LL | false => std::hint::unreachable_unchecked(),
- | ---------------------------------- inside `foo` at $DIR/const_unsafe_unreachable_ub.rs:6:18
-...
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `BAR`
+ --> $DIR/const_unsafe_unreachable_ub.rs:10:28
+ |
LL | const BAR: bool = unsafe { foo(false) };
- | ---------- inside `BAR` at $DIR/const_unsafe_unreachable_ub.rs:10:28
+ | ^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/consts/control-flow/interior-mutability.stderr b/src/test/ui/consts/control-flow/interior-mutability.stderr
index 4f9c7d34c..db2ffb91b 100644
--- a/src/test/ui/consts/control-flow/interior-mutability.stderr
+++ b/src/test/ui/consts/control-flow/interior-mutability.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/interior-mutability.rs:40:26
|
LL | let x: &'static _ = &X;
- | ---------- ^ creates a temporary which is freed while still in use
+ | ---------- ^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/interior-mutability.rs:41:26
|
LL | let y: &'static _ = &Y;
- | ---------- ^ creates a temporary which is freed while still in use
+ | ---------- ^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | let z: &'static _ = &Z;
@@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/interior-mutability.rs:42:26
|
LL | let z: &'static _ = &Z;
- | ---------- ^ creates a temporary which is freed while still in use
+ | ---------- ^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | }
diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs
index 159cdf257..9c239c8a1 100644
--- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs
+++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.rs
@@ -29,7 +29,7 @@ const UNALIGNED_PTR: () = unsafe {
};
const UNALIGNED_READ: () = {
- INNER; //[with_flag]~ERROR evaluation of constant value failed
+ INNER; //[with_flag]~ constant
// There is an error here but its span is in the standard library so we cannot match it...
// so we have this in a *nested* const, such that the *outer* const fails to use it.
const INNER: () = unsafe {
diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
index 3e1195822..2603a7358 100644
--- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
+++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr
@@ -32,27 +32,30 @@ error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | accessing memory with alignment 1, but alignment 4 is required
- | inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment 1, but alignment 4 is required
|
- ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+note: inside `std::ptr::read::<u32>`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
-LL | unsafe { read(self) }
- | ---------- inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `ptr::const_ptr::<impl *const u32>::read`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/detect-extra-ub.rs:38:9
+LL | unsafe { read(self) }
+ | ^^^^^^^^^^
+note: inside `INNER`
+ --> $DIR/detect-extra-ub.rs:38:9
|
LL | ptr.read();
- | ---------- inside `INNER` at $DIR/detect-extra-ub.rs:38:9
+ | ^^^^^^^^^^
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/detect-extra-ub.rs:32:5
|
LL | INNER;
- | ^^^^^ referenced constant has errors
+ | ^^^^^
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/fn_trait_refs.rs b/src/test/ui/consts/fn_trait_refs.rs
new file mode 100644
index 000000000..b50749297
--- /dev/null
+++ b/src/test/ui/consts/fn_trait_refs.rs
@@ -0,0 +1,77 @@
+// check-pass
+
+#![feature(const_fn_trait_ref_impls)]
+#![feature(fn_traits)]
+#![feature(unboxed_closures)]
+#![feature(const_trait_impl)]
+#![feature(const_mut_refs)]
+#![feature(const_cmp)]
+#![feature(const_refs_to_cell)]
+
+use std::marker::Destruct;
+
+const fn tester_fn<T>(f: T) -> T::Output
+where
+ T: ~const Fn<()> + ~const Destruct,
+{
+ f()
+}
+
+const fn tester_fn_mut<T>(mut f: T) -> T::Output
+where
+ T: ~const FnMut<()> + ~const Destruct,
+{
+ f()
+}
+
+const fn tester_fn_once<T>(f: T) -> T::Output
+where
+ T: ~const FnOnce<()>,
+{
+ f()
+}
+
+const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output)
+where
+ T: ~const Fn<()> + ~const Destruct,
+{
+ (
+ // impl<A: Tuple, F: ~const Fn + ?Sized> const Fn<A> for &F
+ tester_fn(&f),
+ // impl<A: Tuple, F: ~const Fn + ?Sized> const FnMut<A> for &F
+ tester_fn_mut(&f),
+ // impl<A: Tuple, F: ~const Fn + ?Sized> const FnOnce<A> for &F
+ tester_fn_once(&f),
+ )
+}
+
+const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
+where
+ T: ~const FnMut<()> + ~const Destruct,
+{
+ (
+ // impl<A: Tuple, F: ~const FnMut + ?Sized> const FnMut<A> for &mut F
+ tester_fn_mut(&mut f),
+ // impl<A: Tuple, F: ~const FnMut + ?Sized> const FnOnce<A> for &mut F
+ tester_fn_once(&mut f),
+ )
+}
+const fn test(i: i32) -> i32 {
+ i + 1
+}
+
+fn main() {
+ const fn one() -> i32 {
+ 1
+ };
+ const fn two() -> i32 {
+ 2
+ };
+ const _: () = {
+ let test_one = test_fn(one);
+ assert!(test_one == (1, 1, 1));
+
+ let test_two = test_fn_mut(two);
+ assert!(test_two == (2, 2));
+ };
+}
diff --git a/src/test/ui/consts/invalid-const-in-body.rs b/src/test/ui/consts/invalid-const-in-body.rs
new file mode 100644
index 000000000..f0fa3bb7b
--- /dev/null
+++ b/src/test/ui/consts/invalid-const-in-body.rs
@@ -0,0 +1,6 @@
+fn f() -> impl Sized {
+ 2.0E
+ //~^ ERROR expected at least one digit in exponent
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/invalid-const-in-body.stderr b/src/test/ui/consts/invalid-const-in-body.stderr
new file mode 100644
index 000000000..3be658359
--- /dev/null
+++ b/src/test/ui/consts/invalid-const-in-body.stderr
@@ -0,0 +1,8 @@
+error: expected at least one digit in exponent
+ --> $DIR/invalid-const-in-body.rs:2:5
+ |
+LL | 2.0E
+ | ^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/consts/invalid-inline-const-in-match-arm.rs b/src/test/ui/consts/invalid-inline-const-in-match-arm.rs
new file mode 100644
index 000000000..4d2d8fb13
--- /dev/null
+++ b/src/test/ui/consts/invalid-inline-const-in-match-arm.rs
@@ -0,0 +1,9 @@
+#![allow(incomplete_features)]
+#![feature(inline_const_pat)]
+
+fn main() {
+ match () {
+ const { (|| {})() } => {}
+ //~^ ERROR cannot call non-const closure in constants
+ }
+}
diff --git a/src/test/ui/consts/invalid-inline-const-in-match-arm.stderr b/src/test/ui/consts/invalid-inline-const-in-match-arm.stderr
new file mode 100644
index 000000000..ab594c921
--- /dev/null
+++ b/src/test/ui/consts/invalid-inline-const-in-match-arm.stderr
@@ -0,0 +1,12 @@
+error[E0015]: cannot call non-const closure in constants
+ --> $DIR/invalid-inline-const-in-match-arm.rs:6:17
+ |
+LL | const { (|| {})() } => {}
+ | ^^^^^^^^^
+ |
+ = note: closures need an RFC before allowed to be called in constants
+ = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/consts/invalid-union.32bit.stderr b/src/test/ui/consts/invalid-union.32bit.stderr
index bad07989e..4758ea4ae 100644
--- a/src/test/ui/consts/invalid-union.32bit.stderr
+++ b/src/test/ui/consts/invalid-union.32bit.stderr
@@ -9,12 +9,24 @@ LL | fn main() {
╾─alloc7──╼ │ ╾──╼
}
-error[E0080]: erroneous constant used
- --> $DIR/invalid-union.rs:42:25
+note: erroneous constant used
+ --> $DIR/invalid-union.rs:43:25
|
LL | let _: &'static _ = &C;
- | ^^ referenced constant has errors
+ | ^^
-error: aborting due to 2 previous errors
+note: erroneous constant used
+ --> $DIR/invalid-union.rs:43:25
+ |
+LL | let _: &'static _ = &C;
+ | ^^
+
+note: erroneous constant used
+ --> $DIR/invalid-union.rs:43:25
+ |
+LL | let _: &'static _ = &C;
+ | ^^
+
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/invalid-union.64bit.stderr b/src/test/ui/consts/invalid-union.64bit.stderr
index a209f0038..22b85d20c 100644
--- a/src/test/ui/consts/invalid-union.64bit.stderr
+++ b/src/test/ui/consts/invalid-union.64bit.stderr
@@ -9,12 +9,24 @@ LL | fn main() {
╾───────alloc7────────╼ │ ╾──────╼
}
-error[E0080]: erroneous constant used
- --> $DIR/invalid-union.rs:42:25
+note: erroneous constant used
+ --> $DIR/invalid-union.rs:43:25
|
LL | let _: &'static _ = &C;
- | ^^ referenced constant has errors
+ | ^^
-error: aborting due to 2 previous errors
+note: erroneous constant used
+ --> $DIR/invalid-union.rs:43:25
+ |
+LL | let _: &'static _ = &C;
+ | ^^
+
+note: erroneous constant used
+ --> $DIR/invalid-union.rs:43:25
+ |
+LL | let _: &'static _ = &C;
+ | ^^
+
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/invalid-union.rs b/src/test/ui/consts/invalid-union.rs
index 435d26d6e..28706b4a9 100644
--- a/src/test/ui/consts/invalid-union.rs
+++ b/src/test/ui/consts/invalid-union.rs
@@ -39,5 +39,6 @@ const C: S = {
};
fn main() { //~ ERROR it is undefined behavior to use this value
- let _: &'static _ = &C; //~ ERROR erroneous constant used
+ // FIXME the span here is wrong, sould be pointing at the line below, not above.
+ let _: &'static _ = &C;
}
diff --git a/src/test/ui/consts/issue-102117.rs b/src/test/ui/consts/issue-102117.rs
index b77342c41..3ed90aed2 100644
--- a/src/test/ui/consts/issue-102117.rs
+++ b/src/test/ui/consts/issue-102117.rs
@@ -14,11 +14,11 @@ pub struct VTable {
impl VTable {
pub fn new<T>() -> &'static Self {
const {
- //~^ ERROR the parameter type `T` may not live long enough
- //~| ERROR the parameter type `T` may not live long enough
&VTable {
layout: Layout::new::<T>(),
type_id: TypeId::of::<T>(),
+ //~^ ERROR the parameter type `T` may not live long enough
+ //~| ERROR the parameter type `T` may not live long enough
drop_in_place: unsafe {
transmute::<unsafe fn(*mut T), unsafe fn(*mut ())>(drop_in_place::<T>)
},
diff --git a/src/test/ui/consts/issue-102117.stderr b/src/test/ui/consts/issue-102117.stderr
index eb4b329bd..f42bcf90f 100644
--- a/src/test/ui/consts/issue-102117.stderr
+++ b/src/test/ui/consts/issue-102117.stderr
@@ -1,14 +1,8 @@
error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/issue-102117.rs:16:9
+ --> $DIR/issue-102117.rs:19:26
|
-LL | / const {
-LL | |
-LL | |
-LL | | &VTable {
-... |
-LL | | }
-LL | | }
- | |_________^ ...so that the type `T` will meet its required lifetime bounds
+LL | type_id: TypeId::of::<T>(),
+ | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
@@ -16,16 +10,10 @@ LL | pub fn new<T: 'static>() -> &'static Self {
| +++++++++
error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/issue-102117.rs:16:9
+ --> $DIR/issue-102117.rs:19:26
|
-LL | / const {
-LL | |
-LL | |
-LL | | &VTable {
-... |
-LL | | }
-LL | | }
- | |_________^ ...so that the type `T` will meet its required lifetime bounds
+LL | type_id: TypeId::of::<T>(),
+ | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
diff --git a/src/test/ui/consts/issue-103790.rs b/src/test/ui/consts/issue-103790.rs
new file mode 100644
index 000000000..ea3cac605
--- /dev/null
+++ b/src/test/ui/consts/issue-103790.rs
@@ -0,0 +1,10 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct S<const S: (), const S: S = { S }>;
+//~^ ERROR the name `S` is already used for a generic parameter in this item's generic parameters
+//~| ERROR missing generics for struct `S`
+//~| ERROR cycle detected when computing type of `S::S`
+//~| ERROR cycle detected when computing type of `S`
+
+fn main() {}
diff --git a/src/test/ui/consts/issue-103790.stderr b/src/test/ui/consts/issue-103790.stderr
new file mode 100644
index 000000000..41b0816dc
--- /dev/null
+++ b/src/test/ui/consts/issue-103790.stderr
@@ -0,0 +1,65 @@
+error[E0403]: the name `S` is already used for a generic parameter in this item's generic parameters
+ --> $DIR/issue-103790.rs:4:29
+ |
+LL | struct S<const S: (), const S: S = { S }>;
+ | - ^ already used
+ | |
+ | first use of `S`
+
+error[E0107]: missing generics for struct `S`
+ --> $DIR/issue-103790.rs:4:32
+ |
+LL | struct S<const S: (), const S: S = { S }>;
+ | ^ expected at least 1 generic argument
+ |
+note: struct defined here, with at least 1 generic parameter: `S`
+ --> $DIR/issue-103790.rs:4:8
+ |
+LL | struct S<const S: (), const S: S = { S }>;
+ | ^ -----------
+help: add missing generic argument
+ |
+LL | struct S<const S: (), const S: S<S> = { S }>;
+ | ~~~~
+
+error[E0391]: cycle detected when computing type of `S::S`
+ --> $DIR/issue-103790.rs:4:32
+ |
+LL | struct S<const S: (), const S: S = { S }>;
+ | ^
+ |
+ = note: ...which immediately requires computing type of `S::S` again
+note: cycle used when computing type of `S`
+ --> $DIR/issue-103790.rs:4:1
+ |
+LL | struct S<const S: (), const S: S = { S }>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0391]: cycle detected when computing type of `S`
+ --> $DIR/issue-103790.rs:4:1
+ |
+LL | struct S<const S: (), const S: S = { S }>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: ...which requires computing type of `S::S`...
+ --> $DIR/issue-103790.rs:4:32
+ |
+LL | struct S<const S: (), const S: S = { S }>;
+ | ^
+ = note: ...which again requires computing type of `S`, completing the cycle
+note: cycle used when collecting item types in top-level module
+ --> $DIR/issue-103790.rs:1:1
+ |
+LL | / #![feature(generic_const_exprs)]
+LL | | #![allow(incomplete_features)]
+LL | |
+LL | | struct S<const S: (), const S: S = { S }>;
+... |
+LL | |
+LL | | fn main() {}
+ | |____________^
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0107, E0391, E0403.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/consts/issue-104609.rs b/src/test/ui/consts/issue-104609.rs
new file mode 100644
index 000000000..01fd1c48c
--- /dev/null
+++ b/src/test/ui/consts/issue-104609.rs
@@ -0,0 +1,10 @@
+fn foo() {
+ oops;
+ //~^ ERROR: cannot find value `oops` in this scope
+}
+
+unsafe fn bar() {
+ std::mem::transmute::<_, *mut _>(1_u8);
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/issue-104609.stderr b/src/test/ui/consts/issue-104609.stderr
new file mode 100644
index 000000000..00360c44d
--- /dev/null
+++ b/src/test/ui/consts/issue-104609.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `oops` in this scope
+ --> $DIR/issue-104609.rs:2:5
+ |
+LL | oops;
+ | ^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/consts/issue-104768.rs b/src/test/ui/consts/issue-104768.rs
new file mode 100644
index 000000000..3192daafa
--- /dev/null
+++ b/src/test/ui/consts/issue-104768.rs
@@ -0,0 +1,4 @@
+const A: &_ = 0_u32;
+//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for constants
+
+fn main() {}
diff --git a/src/test/ui/consts/issue-104768.stderr b/src/test/ui/consts/issue-104768.stderr
new file mode 100644
index 000000000..55b2b6f04
--- /dev/null
+++ b/src/test/ui/consts/issue-104768.stderr
@@ -0,0 +1,12 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
+ --> $DIR/issue-104768.rs:1:10
+ |
+LL | const A: &_ = 0_u32;
+ | ^^
+ | |
+ | not allowed in type signatures
+ | help: replace with the correct type: `u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/consts/issue-36163.stderr b/src/test/ui/consts/issue-36163.stderr
index 9ac6c984c..7137c0538 100644
--- a/src/test/ui/consts/issue-36163.stderr
+++ b/src/test/ui/consts/issue-36163.stderr
@@ -5,10 +5,10 @@ LL | B = A,
| ^
|
note: ...which requires const-evaluating + checking `A`...
- --> $DIR/issue-36163.rs:1:1
+ --> $DIR/issue-36163.rs:1:18
|
LL | const A: isize = Foo::B as isize;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^
= note: ...which again requires const-evaluating + checking `Foo::B::{constant#0}`, completing the cycle
note: cycle used when simplifying constant for the type system `Foo::B::{constant#0}`
--> $DIR/issue-36163.rs:4:9
diff --git a/src/test/ui/consts/issue-54224.stderr b/src/test/ui/consts/issue-54224.stderr
index 8dcb4daca..55fe55759 100644
--- a/src/test/ui/consts/issue-54224.stderr
+++ b/src/test/ui/consts/issue-54224.stderr
@@ -5,7 +5,7 @@ LL | const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]);
| ------^^^^^^^^^-
| | | |
| | | temporary value is freed at the end of this statement
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| using this value as a constant requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
@@ -15,7 +15,7 @@ LL | pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]);
| ---------------^^^^^^^^^-
| | | |
| | | temporary value is freed at the end of this statement
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| using this value as a constant requires that borrow lasts for `'static`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-54954.rs b/src/test/ui/consts/issue-54954.rs
index d4e1df227..520bf508f 100644
--- a/src/test/ui/issues/issue-54954.rs
+++ b/src/test/ui/consts/issue-54954.rs
@@ -9,8 +9,8 @@ trait Tt {
}
fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
- //~^ ERROR evaluation of constant value failed
- //~| ERROR evaluation of constant value failed
+ //~^ constant
+ //~| constant
z
}
diff --git a/src/test/ui/issues/issue-54954.stderr b/src/test/ui/consts/issue-54954.stderr
index 668985c2b..850558287 100644
--- a/src/test/ui/issues/issue-54954.stderr
+++ b/src/test/ui/consts/issue-54954.stderr
@@ -16,19 +16,19 @@ LL | | core::mem::size_of::<T>()
LL | | }
| |_____- `Tt::const_val` defined here
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-54954.rs:11:15
|
LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
- | ^^^^^^^ referenced constant has errors
+ | ^^^^^^^
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-54954.rs:11:34
|
LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
- | ^^^^^^^ referenced constant has errors
+ | ^^^^^^^
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0080, E0379, E0790.
-For more information about an error, try `rustc --explain E0080`.
+Some errors have detailed explanations: E0379, E0790.
+For more information about an error, try `rustc --explain E0379`.
diff --git a/src/test/ui/consts/issue-56164.rs b/src/test/ui/consts/issue-56164.rs
index df3e3bf90..22c257d0b 100644
--- a/src/test/ui/consts/issue-56164.rs
+++ b/src/test/ui/consts/issue-56164.rs
@@ -1,6 +1,5 @@
const fn foo() { (||{})() }
//~^ ERROR cannot call non-const closure
-//~| ERROR erroneous constant used
const fn bad(input: fn()) {
input()
diff --git a/src/test/ui/consts/issue-56164.stderr b/src/test/ui/consts/issue-56164.stderr
index c5b2c57fb..2579b3e78 100644
--- a/src/test/ui/consts/issue-56164.stderr
+++ b/src/test/ui/consts/issue-56164.stderr
@@ -8,18 +8,23 @@ LL | const fn foo() { (||{})() }
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: function pointer calls are not allowed in constant functions
- --> $DIR/issue-56164.rs:6:5
+ --> $DIR/issue-56164.rs:5:5
|
LL | input()
| ^^^^^^^
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/issue-56164.rs:1:18
|
LL | const fn foo() { (||{})() }
- | ^^^^^^ referenced constant has errors
+ | ^^^^^^
-error: aborting due to 3 previous errors
+note: erroneous constant used
+ --> $DIR/issue-56164.rs:1:18
+ |
+LL | const fn foo() { (||{})() }
+ | ^^^^^^
+
+error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0015, E0080.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/consts/issue-66693.rs b/src/test/ui/consts/issue-66693.rs
index 1ff250be1..df45d01ec 100644
--- a/src/test/ui/consts/issue-66693.rs
+++ b/src/test/ui/consts/issue-66693.rs
@@ -10,7 +10,6 @@ static _FOO: () = panic!(true);
const fn _foo() {
panic!(&1);
//~^ ERROR: argument to `panic!()` in a const context must have type `&str`
- //~| ERROR: erroneous constant used
}
// ensure that conforming panics don't cause an error
diff --git a/src/test/ui/consts/issue-66693.stderr b/src/test/ui/consts/issue-66693.stderr
index 911374f50..e9a3fced6 100644
--- a/src/test/ui/consts/issue-66693.stderr
+++ b/src/test/ui/consts/issue-66693.stderr
@@ -22,12 +22,17 @@ LL | panic!(&1);
|
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/issue-66693.rs:11:12
|
LL | panic!(&1);
- | ^^ referenced constant has errors
+ | ^^
-error: aborting due to 4 previous errors
+note: erroneous constant used
+ --> $DIR/issue-66693.rs:11:12
+ |
+LL | panic!(&1);
+ | ^^
+
+error: aborting due to 3 previous errors
-For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/issue-miri-1910.stderr b/src/test/ui/consts/issue-miri-1910.stderr
index 3872e3d4f..1f82e1777 100644
--- a/src/test/ui/consts/issue-miri-1910.stderr
+++ b/src/test/ui/consts/issue-miri-1910.stderr
@@ -2,23 +2,25 @@ error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | unable to copy parts of a pointer from memory at ALLOC
- | inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to copy parts of a pointer from memory at ALLOC
|
- ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+note: inside `std::ptr::read::<u8>`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
-LL | unsafe { read(self) }
- | ---------- inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `ptr::const_ptr::<impl *const u8>::read`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/issue-miri-1910.rs:8:5
+LL | unsafe { read(self) }
+ | ^^^^^^^^^^
+note: inside `C`
+ --> $DIR/issue-miri-1910.rs:8:5
|
LL | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
- | ------------------------------------------------------------------- inside `C` at $DIR/issue-miri-1910.rs:8:5
- |
- = help: this code performed an operation that depends on the underlying bytes representing a pointer
- = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/consts/min_const_fn/promotion.stderr b/src/test/ui/consts/min_const_fn/promotion.stderr
index 550423c2d..0b8dc0ce0 100644
--- a/src/test/ui/consts/min_const_fn/promotion.stderr
+++ b/src/test/ui/consts/min_const_fn/promotion.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:11:27
|
LL | let x: &'static () = &foo1();
- | ----------- ^^^^^^ creates a temporary which is freed while still in use
+ | ----------- ^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:12:28
|
LL | let y: &'static i32 = &foo2(42);
- | ------------ ^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:13:28
|
LL | let z: &'static i32 = &foo3();
- | ------------ ^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -35,7 +35,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:14:34
|
LL | let a: &'static Cell<i32> = &foo4();
- | ------------------ ^^^^^^ creates a temporary which is freed while still in use
+ | ------------------ ^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -46,7 +46,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:15:42
|
LL | let a: &'static Option<Cell<i32>> = &foo5();
- | -------------------------- ^^^^^^ creates a temporary which is freed while still in use
+ | -------------------------- ^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | let a: &'static Option<Cell<i32>> = &foo6();
@@ -57,7 +57,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:16:42
|
LL | let a: &'static Option<Cell<i32>> = &foo6();
- | -------------------------- ^^^^^^ creates a temporary which is freed while still in use
+ | -------------------------- ^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | }
diff --git a/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr b/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr
index 840d698eb..cf3fd88d0 100644
--- a/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr
+++ b/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr
@@ -2,13 +2,18 @@ error[E0080]: could not evaluate static initializer
--> $DIR/abi-mismatch.rs:9:5
|
LL | my_fn();
+ | ^^^^^^^ calling a function with calling convention C using calling convention Rust
+ |
+note: inside `call_rust_fn`
+ --> $DIR/abi-mismatch.rs:9:5
+ |
+LL | my_fn();
| ^^^^^^^
- | |
- | calling a function with calling convention C using calling convention Rust
- | inside `call_rust_fn` at $DIR/abi-mismatch.rs:9:5
-...
+note: inside `VAL`
+ --> $DIR/abi-mismatch.rs:15:18
+ |
LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
- | --------------------------------------------------------------------- inside `VAL` at $DIR/abi-mismatch.rs:15:18
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: skipping const checks
|
diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.rs b/src/test/ui/consts/miri_unleashed/assoc_const.rs
index 76ed667a5..7bb0c1b77 100644
--- a/src/test/ui/consts/miri_unleashed/assoc_const.rs
+++ b/src/test/ui/consts/miri_unleashed/assoc_const.rs
@@ -26,5 +26,5 @@ fn main() {
// this is fine, but would have been forbidden by the static checks on `F`
let x = <() as Bar<u32, ()>>::F;
// this test only causes errors due to the line below, so post-monomorphization
- let y = <String as Bar<Vec<u32>, String>>::F; //~ ERROR erroneous constant
+ let y = <String as Bar<Vec<u32>, String>>::F; //~ constant
}
diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.stderr b/src/test/ui/consts/miri_unleashed/assoc_const.stderr
index 519bd0748..b26f121db 100644
--- a/src/test/ui/consts/miri_unleashed/assoc_const.stderr
+++ b/src/test/ui/consts/miri_unleashed/assoc_const.stderr
@@ -2,22 +2,41 @@ error[E0080]: evaluation of `<std::string::String as Bar<std::vec::Vec<u32>, std
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `<Vec<u32> as Drop>::drop`
+ |
+note: inside `std::ptr::drop_in_place::<Vec<u32>> - shim(Some(Vec<u32>))`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ |
+LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | calling non-const function `<Vec<u32> as Drop>::drop`
- | inside `std::ptr::drop_in_place::<Vec<u32>> - shim(Some(Vec<u32>))` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
- | inside `std::ptr::drop_in_place::<(Vec<u32>, u32)> - shim(Some((Vec<u32>, u32)))` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+note: inside `std::ptr::drop_in_place::<(Vec<u32>, u32)> - shim(Some((Vec<u32>, u32)))`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
- ::: $DIR/assoc_const.rs:12:31
+LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `<String as Bar<Vec<u32>, String>>::F`
+ --> $DIR/assoc_const.rs:12:31
|
LL | const F: u32 = (U::X, 42).1;
- | - inside `<String as Bar<Vec<u32>, String>>::F` at $DIR/assoc_const.rs:12:31
+ | ^
+
+note: erroneous constant used
+ --> $DIR/assoc_const.rs:29:13
+ |
+LL | let y = <String as Bar<Vec<u32>, String>>::F;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/assoc_const.rs:29:13
+ |
+LL | let y = <String as Bar<Vec<u32>, String>>::F;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/assoc_const.rs:29:13
|
LL | let y = <String as Bar<Vec<u32>, String>>::F;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: skipping const checks
|
@@ -27,6 +46,6 @@ help: skipping check that does not even have a feature gate
LL | const F: u32 = (U::X, 42).1;
| ^^^^^^^^^^
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/miri_unleashed/assoc_const_2.rs b/src/test/ui/consts/miri_unleashed/assoc_const_2.rs
index 8377141ea..aad5b3460 100644
--- a/src/test/ui/consts/miri_unleashed/assoc_const_2.rs
+++ b/src/test/ui/consts/miri_unleashed/assoc_const_2.rs
@@ -24,5 +24,5 @@ impl Bar<String> for String {}
fn main() {
let x = <() as Bar<()>>::F;
// this test only causes errors due to the line below, so post-monomorphization
- let y = <String as Bar<String>>::F; //~ ERROR erroneous constant
+ let y = <String as Bar<String>>::F; //~ constant
}
diff --git a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr
index 2bf753c2b..fc4b18056 100644
--- a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr
+++ b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr
@@ -4,12 +4,24 @@ error[E0080]: evaluation of `<std::string::String as Bar<std::string::String>>::
LL | const F: u32 = 100 / U::X;
| ^^^^^^^^^^ attempt to divide `100_u32` by zero
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/assoc_const_2.rs:27:13
|
LL | let y = <String as Bar<String>>::F;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 2 previous errors
+note: erroneous constant used
+ --> $DIR/assoc_const_2.rs:27:13
+ |
+LL | let y = <String as Bar<String>>::F;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/assoc_const_2.rs:27:13
+ |
+LL | let y = <String as Bar<String>>::F;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/miri_unleashed/drop.stderr b/src/test/ui/consts/miri_unleashed/drop.stderr
index a3a502723..e2e2f16d5 100644
--- a/src/test/ui/consts/miri_unleashed/drop.stderr
+++ b/src/test/ui/consts/miri_unleashed/drop.stderr
@@ -2,15 +2,18 @@ error[E0080]: could not evaluate static initializer
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | calling non-const function `<Vec<i32> as Drop>::drop`
- | inside `std::ptr::drop_in_place::<Vec<i32>> - shim(Some(Vec<i32>))` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `<Vec<i32> as Drop>::drop`
+ |
+note: inside `std::ptr::drop_in_place::<Vec<i32>> - shim(Some(Vec<i32>))`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
- ::: $DIR/drop.rs:17:1
+LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `TEST_BAD`
+ --> $DIR/drop.rs:17:1
|
LL | };
- | - inside `TEST_BAD` at $DIR/drop.rs:17:1
+ | ^
warning: skipping const checks
|
diff --git a/src/test/ui/consts/miri_unleashed/tls.stderr b/src/test/ui/consts/miri_unleashed/tls.stderr
index 436c51123..7aaeadd04 100644
--- a/src/test/ui/consts/miri_unleashed/tls.stderr
+++ b/src/test/ui/consts/miri_unleashed/tls.stderr
@@ -2,13 +2,13 @@ error[E0080]: could not evaluate static initializer
--> $DIR/tls.rs:11:25
|
LL | unsafe { let _val = A; }
- | ^ cannot access thread local static (DefId(0:6 ~ tls[78b0]::A))
+ | ^ cannot access thread local static (DefId(0:4 ~ tls[78b0]::A))
error[E0080]: could not evaluate static initializer
--> $DIR/tls.rs:18:26
|
LL | unsafe { let _val = &A; }
- | ^ cannot access thread local static (DefId(0:6 ~ tls[78b0]::A))
+ | ^ cannot access thread local static (DefId(0:4 ~ tls[78b0]::A))
warning: skipping const checks
|
diff --git a/src/test/ui/consts/missing_span_in_backtrace.rs b/src/test/ui/consts/missing_span_in_backtrace.rs
new file mode 100644
index 000000000..c4930b73a
--- /dev/null
+++ b/src/test/ui/consts/missing_span_in_backtrace.rs
@@ -0,0 +1,27 @@
+// compile-flags: -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ui-testing=no
+// normalize-stderr-test "alloc[0-9]+" -> "ALLOC_ID"
+
+#![feature(const_swap)]
+#![feature(const_mut_refs)]
+use std::{
+ mem::{self, MaybeUninit},
+ ptr,
+};
+
+const X: () = {
+ let mut ptr1 = &1;
+ let mut ptr2 = &2;
+
+ // Swap them, bytewise.
+ unsafe {
+ ptr::swap_nonoverlapping(
+ &mut ptr1 as *mut _ as *mut MaybeUninit<u8>,
+ &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
+ mem::size_of::<&i32>(),
+ );
+ }
+};
+
+fn main() {
+ X
+}
diff --git a/src/test/ui/consts/missing_span_in_backtrace.stderr b/src/test/ui/consts/missing_span_in_backtrace.stderr
new file mode 100644
index 000000000..e6d3d5199
--- /dev/null
+++ b/src/test/ui/consts/missing_span_in_backtrace.stderr
@@ -0,0 +1,28 @@
+error[E0080]: evaluation of constant value failed
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ |
+ = note: unable to copy parts of a pointer from memory at ALLOC_ID
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+note: inside `std::ptr::read::<MaybeUninit<MaybeUninit<u8>>>`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+note: inside `mem::swap_simple::<MaybeUninit<MaybeUninit<u8>>>`
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+note: inside `ptr::swap_nonoverlapping_simple_untyped::<MaybeUninit<u8>>`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+note: inside `swap_nonoverlapping::<MaybeUninit<u8>>`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+note: inside `X`
+ --> $DIR/missing_span_in_backtrace.rs:17:9
+ |
+17 | / ptr::swap_nonoverlapping(
+18 | | &mut ptr1 as *mut _ as *mut MaybeUninit<u8>,
+19 | | &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
+20 | | mem::size_of::<&i32>(),
+21 | | );
+ | |_________^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/offset_from_ub.stderr b/src/test/ui/consts/offset_from_ub.stderr
index 62a087d94..9578d90ea 100644
--- a/src/test/ui/consts/offset_from_ub.stderr
+++ b/src/test/ui/consts/offset_from_ub.stderr
@@ -8,15 +8,18 @@ error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | `ptr_offset_from` called on pointers into different allocations
- | inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on pointers into different allocations
+ |
+note: inside `ptr::const_ptr::<impl *const u8>::offset_from`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/offset_from_ub.rs:24:14
+LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `NOT_PTR`
+ --> $DIR/offset_from_ub.rs:24:14
|
LL | unsafe { (42 as *const u8).offset_from(&5u8) as usize }
- | ----------------------------------- inside `NOT_PTR` at $DIR/offset_from_ub.rs:24:14
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $DIR/offset_from_ub.rs:31:14
@@ -88,29 +91,35 @@ error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
- | inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
|
- ::: $DIR/offset_from_ub.rs:115:14
+note: inside `ptr::const_ptr::<impl *const u8>::offset_from`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `OFFSET_VERY_FAR1`
+ --> $DIR/offset_from_ub.rs:115:14
|
LL | unsafe { ptr2.offset_from(ptr1) }
- | ---------------------- inside `OFFSET_VERY_FAR1` at $DIR/offset_from_ub.rs:115:14
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
- | inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: null pointer is a dangling pointer (it has no provenance)
|
- ::: $DIR/offset_from_ub.rs:121:14
+note: inside `ptr::const_ptr::<impl *const u8>::offset_from`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `OFFSET_VERY_FAR2`
+ --> $DIR/offset_from_ub.rs:121:14
|
LL | unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) }
- | ----------------------------------------- inside `OFFSET_VERY_FAR2` at $DIR/offset_from_ub.rs:121:14
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 15 previous errors
diff --git a/src/test/ui/consts/offset_ub.stderr b/src/test/ui/consts/offset_ub.stderr
index 5a792bba5..7938f70a2 100644
--- a/src/test/ui/consts/offset_ub.stderr
+++ b/src/test/ui/consts/offset_ub.stderr
@@ -2,169 +2,205 @@ error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | overflowing in-bounds pointer arithmetic
- | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing in-bounds pointer arithmetic
+ |
+note: inside `ptr::const_ptr::<impl *const u8>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/offset_ub.rs:7:46
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `BEFORE_START`
+ --> $DIR/offset_ub.rs:7:46
|
LL | pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) };
- | ------------------------------ inside `BEFORE_START` at $DIR/offset_ub.rs:7:46
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: allocN has size 1, so pointer to 2 bytes starting at offset 0 is out-of-bounds
- | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: allocN has size 1, so pointer to 2 bytes starting at offset 0 is out-of-bounds
|
- ::: $DIR/offset_ub.rs:8:43
+note: inside `ptr::const_ptr::<impl *const u8>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `AFTER_END`
+ --> $DIR/offset_ub.rs:8:43
|
LL | pub const AFTER_END: *const u8 = unsafe { (&0u8 as *const u8).offset(2) };
- | ----------------------------- inside `AFTER_END` at $DIR/offset_ub.rs:8:43
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: allocN has size 100, so pointer to 101 bytes starting at offset 0 is out-of-bounds
- | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: allocN has size 100, so pointer to 101 bytes starting at offset 0 is out-of-bounds
|
- ::: $DIR/offset_ub.rs:9:45
+note: inside `ptr::const_ptr::<impl *const u8>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `AFTER_ARRAY`
+ --> $DIR/offset_ub.rs:9:45
|
LL | pub const AFTER_ARRAY: *const u8 = unsafe { [0u8; 100].as_ptr().offset(101) };
- | ------------------------------- inside `AFTER_ARRAY` at $DIR/offset_ub.rs:9:45
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | overflowing in-bounds pointer arithmetic
- | inside `ptr::const_ptr::<impl *const u16>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing in-bounds pointer arithmetic
+ |
+note: inside `ptr::const_ptr::<impl *const u16>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/offset_ub.rs:11:43
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `OVERFLOW`
+ --> $DIR/offset_ub.rs:11:43
|
LL | pub const OVERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MAX) };
- | ------------------------------------- inside `OVERFLOW` at $DIR/offset_ub.rs:11:43
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | overflowing in-bounds pointer arithmetic
- | inside `ptr::const_ptr::<impl *const u16>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing in-bounds pointer arithmetic
|
- ::: $DIR/offset_ub.rs:12:44
+note: inside `ptr::const_ptr::<impl *const u16>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `UNDERFLOW`
+ --> $DIR/offset_ub.rs:12:44
|
LL | pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) };
- | ------------------------------------- inside `UNDERFLOW` at $DIR/offset_ub.rs:12:44
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | overflowing in-bounds pointer arithmetic
- | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing in-bounds pointer arithmetic
|
- ::: $DIR/offset_ub.rs:13:56
+note: inside `ptr::const_ptr::<impl *const u8>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `OVERFLOW_ADDRESS_SPACE`
+ --> $DIR/offset_ub.rs:13:56
|
LL | pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) };
- | ----------------------------------- inside `OVERFLOW_ADDRESS_SPACE` at $DIR/offset_ub.rs:13:56
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | overflowing in-bounds pointer arithmetic
- | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing in-bounds pointer arithmetic
+ |
+note: inside `ptr::const_ptr::<impl *const u8>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/offset_ub.rs:14:57
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `UNDERFLOW_ADDRESS_SPACE`
+ --> $DIR/offset_ub.rs:14:57
|
LL | pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) };
- | --------------------------- inside `UNDERFLOW_ADDRESS_SPACE` at $DIR/offset_ub.rs:14:57
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: allocN has size 1, so pointer to 2 bytes starting at offset -4 is out-of-bounds
- | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: allocN has size 1, so pointer to 2 bytes starting at offset -4 is out-of-bounds
|
- ::: $DIR/offset_ub.rs:15:49
+note: inside `ptr::const_ptr::<impl *const u8>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `NEGATIVE_OFFSET`
+ --> $DIR/offset_ub.rs:15:49
|
LL | pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) };
- | ------------------------------------------------ inside `NEGATIVE_OFFSET` at $DIR/offset_ub.rs:15:49
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: allocN has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds
- | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: allocN has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds
|
- ::: $DIR/offset_ub.rs:17:50
+note: inside `ptr::const_ptr::<impl *const u8>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `ZERO_SIZED_ALLOC`
+ --> $DIR/offset_ub.rs:17:50
|
LL | pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) };
- | --------------------------- inside `ZERO_SIZED_ALLOC` at $DIR/offset_ub.rs:17:50
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) as *mut T }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: 0x1[noalloc] is a dangling pointer (it has no provenance)
- | inside `ptr::mut_ptr::<impl *mut u8>::offset` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: 0x1[noalloc] is a dangling pointer (it has no provenance)
+ |
+note: inside `ptr::mut_ptr::<impl *mut u8>::offset`
+ --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
|
- ::: $DIR/offset_ub.rs:18:42
+LL | unsafe { intrinsics::offset(self, count) as *mut T }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `DANGLING`
+ --> $DIR/offset_ub.rs:18:42
|
LL | pub const DANGLING: *const u8 = unsafe { ptr::NonNull::<u8>::dangling().as_ptr().offset(4) };
- | ------------------------------------------------- inside `DANGLING` at $DIR/offset_ub.rs:18:42
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: null pointer is a dangling pointer (it has no provenance)
- | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: null pointer is a dangling pointer (it has no provenance)
|
- ::: $DIR/offset_ub.rs:21:50
+note: inside `ptr::const_ptr::<impl *const u8>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `NULL_OFFSET_ZERO`
+ --> $DIR/offset_ub.rs:21:50
|
LL | pub const NULL_OFFSET_ZERO: *const u8 = unsafe { ptr::null::<u8>().offset(0) };
- | --------------------------- inside `NULL_OFFSET_ZERO` at $DIR/offset_ub.rs:21:50
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: 0x7f..f[noalloc] is a dangling pointer (it has no provenance)
- | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: 0x7f..f[noalloc] is a dangling pointer (it has no provenance)
|
- ::: $DIR/offset_ub.rs:24:47
+note: inside `ptr::const_ptr::<impl *const u8>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `UNDERFLOW_ABS`
+ --> $DIR/offset_ub.rs:24:47
|
LL | pub const UNDERFLOW_ABS: *const u8 = unsafe { (usize::MAX as *const u8).offset(isize::MIN) };
- | -------------------------------------------- inside `UNDERFLOW_ABS` at $DIR/offset_ub.rs:24:47
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 12 previous errors
diff --git a/src/test/ui/consts/promote-not.stderr b/src/test/ui/consts/promote-not.stderr
index 0d0b0f9c6..b93358e8d 100644
--- a/src/test/ui/consts/promote-not.stderr
+++ b/src/test/ui/consts/promote-not.stderr
@@ -5,14 +5,14 @@ LL | static mut TEST1: Option<&mut [i32]> = Some(&mut [1, 2, 3]);
| ----------^^^^^^^^^-
| | | |
| | | temporary value is freed at the end of this statement
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| using this value as a static requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:11:18
|
LL | let x = &mut [1,2,3];
- | ^^^^^^^ creates a temporary which is freed while still in use
+ | ^^^^^^^ creates a temporary value which is freed while still in use
LL | x
| - using this value as a static requires that borrow lasts for `'static`
LL | };
@@ -22,7 +22,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:20:32
|
LL | let _x: &'static () = &foo();
- | ----------- ^^^^^ creates a temporary which is freed while still in use
+ | ----------- ^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | }
@@ -32,7 +32,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:28:29
|
LL | let _x: &'static i32 = &unsafe { U { x: 0 }.x };
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | }
@@ -42,7 +42,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:33:29
|
LL | let _x: &'static i32 = &unsafe { U { x: 0 }.x };
- | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | };
@@ -52,7 +52,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:39:29
|
LL | let _val: &'static _ = &(Cell::new(1), 2).1;
- | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | };
@@ -62,7 +62,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:46:29
|
LL | let _val: &'static _ = &(Cell::new(1), 2).0;
- | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -73,7 +73,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:47:29
|
LL | let _val: &'static _ = &(Cell::new(1), 2).1;
- | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -84,7 +84,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:50:29
|
LL | let _val: &'static _ = &(1/0);
- | ---------- ^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -95,7 +95,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:51:29
|
LL | let _val: &'static _ = &(1/(1-1));
- | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -106,7 +106,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:52:29
|
LL | let _val: &'static _ = &(1%0);
- | ---------- ^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -117,7 +117,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:53:29
|
LL | let _val: &'static _ = &(1%(1-1));
- | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -128,7 +128,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:54:29
|
LL | let _val: &'static _ = &([1,2,3][4]+1);
- | ---------- ^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -139,7 +139,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:57:29
|
LL | let _val: &'static _ = &TEST_DROP;
- | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -150,7 +150,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:59:29
|
LL | let _val: &'static _ = &&TEST_DROP;
- | ---------- ^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -161,7 +161,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:59:30
|
LL | let _val: &'static _ = &&TEST_DROP;
- | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -172,7 +172,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:62:29
|
LL | let _val: &'static _ = &(&TEST_DROP,);
- | ---------- ^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -183,7 +183,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:62:31
|
LL | let _val: &'static _ = &(&TEST_DROP,);
- | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -194,7 +194,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:65:29
|
LL | let _val: &'static _ = &[&TEST_DROP; 1];
- | ---------- ^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -207,7 +207,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let _val: &'static _ = &[&TEST_DROP; 1];
| ---------- ^^^^^^^^^ - temporary value is freed at the end of this statement
| | |
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| type annotation requires that borrow lasts for `'static`
error: aborting due to 20 previous errors
diff --git a/src/test/ui/consts/promote_const_let.stderr b/src/test/ui/consts/promote_const_let.stderr
index c47d297c9..975a235a6 100644
--- a/src/test/ui/consts/promote_const_let.stderr
+++ b/src/test/ui/consts/promote_const_let.stderr
@@ -19,7 +19,7 @@ LL | let x: &'static u32 = &{
LL | | let y = 42;
LL | | y
LL | | };
- | |_____^ creates a temporary which is freed while still in use
+ | |_____^ creates a temporary value which is freed while still in use
LL | }
| - temporary value is freed at the end of this statement
diff --git a/src/test/ui/consts/promoted-const-drop.stderr b/src/test/ui/consts/promoted-const-drop.stderr
index 184ba0ea3..480283417 100644
--- a/src/test/ui/consts/promoted-const-drop.stderr
+++ b/src/test/ui/consts/promoted-const-drop.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted-const-drop.rs:13:26
|
LL | let _: &'static A = &A();
- | ---------- ^^^ creates a temporary which is freed while still in use
+ | ---------- ^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | let _: &'static [A] = &[C];
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted-const-drop.rs:14:28
|
LL | let _: &'static [A] = &[C];
- | ------------ ^^^ creates a temporary which is freed while still in use
+ | ------------ ^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | }
diff --git a/src/test/ui/consts/ptr_comparisons.stderr b/src/test/ui/consts/ptr_comparisons.stderr
index b71964b92..274753ef1 100644
--- a/src/test/ui/consts/ptr_comparisons.stderr
+++ b/src/test/ui/consts/ptr_comparisons.stderr
@@ -2,15 +2,18 @@ error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
LL | unsafe { intrinsics::offset(self, count) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | |
- | out-of-bounds pointer arithmetic: alloc3 has size $WORD, so pointer to $TWO_WORDS bytes starting at offset 0 is out-of-bounds
- | inside `ptr::const_ptr::<impl *const usize>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: alloc3 has size $WORD, so pointer to $TWO_WORDS bytes starting at offset 0 is out-of-bounds
+ |
+note: inside `ptr::const_ptr::<impl *const usize>::offset`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/ptr_comparisons.rs:50:34
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `_`
+ --> $DIR/ptr_comparisons.rs:50:34
|
LL | const _: *const usize = unsafe { (FOO as *const usize).offset(2) };
- | ------------------------------- inside `_` at $DIR/ptr_comparisons.rs:50:34
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $DIR/ptr_comparisons.rs:53:33
diff --git a/src/test/ui/consts/qualif-union.stderr b/src/test/ui/consts/qualif-union.stderr
index 8ec68ada0..d847cf88f 100644
--- a/src/test/ui/consts/qualif-union.stderr
+++ b/src/test/ui/consts/qualif-union.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/qualif-union.rs:28:26
|
LL | let _: &'static _ = &C1;
- | ---------- ^^ creates a temporary which is freed while still in use
+ | ---------- ^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -13,7 +13,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/qualif-union.rs:29:26
|
LL | let _: &'static _ = &C2;
- | ---------- ^^ creates a temporary which is freed while still in use
+ | ---------- ^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -24,7 +24,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/qualif-union.rs:30:26
|
LL | let _: &'static _ = &C3;
- | ---------- ^^ creates a temporary which is freed while still in use
+ | ---------- ^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
@@ -35,7 +35,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/qualif-union.rs:31:26
|
LL | let _: &'static _ = &C4;
- | ---------- ^^ creates a temporary which is freed while still in use
+ | ---------- ^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | let _: &'static _ = &C5;
@@ -46,7 +46,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/qualif-union.rs:32:26
|
LL | let _: &'static _ = &C5;
- | ---------- ^^ creates a temporary which is freed while still in use
+ | ---------- ^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | }
diff --git a/src/test/ui/consts/recursive.stderr b/src/test/ui/consts/recursive.stderr
index 14fa3da7a..60ce64d2a 100644
--- a/src/test/ui/consts/recursive.stderr
+++ b/src/test/ui/consts/recursive.stderr
@@ -13,14 +13,23 @@ error[E0080]: evaluation of constant value failed
--> $DIR/recursive.rs:4:5
|
LL | f(x);
+ | ^^^^ reached the configured maximum number of stack frames
+ |
+note: inside `f::<i32>`
+ --> $DIR/recursive.rs:4:5
+ |
+LL | f(x);
| ^^^^
- | |
- | reached the configured maximum number of stack frames
- | inside `f::<i32>` at $DIR/recursive.rs:4:5
- | [... 126 additional calls inside `f::<i32>` at $DIR/recursive.rs:4:5 ...]
-...
+note: [... 126 additional calls inside `f::<i32>` ...]
+ --> $DIR/recursive.rs:4:5
+ |
+LL | f(x);
+ | ^^^^
+note: inside `X`
+ --> $DIR/recursive.rs:8:15
+ |
LL | const X: () = f(1);
- | ---- inside `X` at $DIR/recursive.rs:8:15
+ | ^^^^
error: aborting due to previous error; 1 warning emitted
diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.rs b/src/test/ui/consts/uninhabited-const-issue-61744.rs
index a07c39882..ca6449cce 100644
--- a/src/test/ui/consts/uninhabited-const-issue-61744.rs
+++ b/src/test/ui/consts/uninhabited-const-issue-61744.rs
@@ -15,5 +15,5 @@ trait Const {
impl<T> Const for T {}
pub fn main() -> () {
- dbg!(i32::CONSTANT); //~ ERROR erroneous constant used
+ dbg!(i32::CONSTANT); //~ constant
}
diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr
index 9c7cc8861..3a94e1931 100644
--- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr
+++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr
@@ -2,150 +2,667 @@ error[E0080]: evaluation of `<i32 as Const>::CONSTANT` failed
--> $DIR/uninhabited-const-issue-61744.rs:4:5
|
LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^ reached the configured maximum number of stack frames
+ |
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
| ^^^^^^^^^^^^^^^^^^
- | |
- | reached the configured maximum number of stack frames
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside `fake_type::<i32>` at $DIR/uninhabited-const-issue-61744.rs:4:5
-...
-LL | fake_type()
- | -----------
- | |
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
- | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
-...
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<!>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `hint_unreachable`
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+note: inside `fake_type::<i32>`
+ --> $DIR/uninhabited-const-issue-61744.rs:4:5
+ |
+LL | hint_unreachable()
+ | ^^^^^^^^^^^^^^^^^^
+note: inside `<i32 as Const>::CONSTANT`
+ --> $DIR/uninhabited-const-issue-61744.rs:12:36
+ |
LL | const CONSTANT: i32 = unsafe { fake_type() };
- | ----------- inside `<i32 as Const>::CONSTANT` at $DIR/uninhabited-const-issue-61744.rs:12:36
+ | ^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/uninhabited-const-issue-61744.rs:18:10
+ |
+LL | dbg!(i32::CONSTANT);
+ | ^^^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/uninhabited-const-issue-61744.rs:18:10
+ |
+LL | dbg!(i32::CONSTANT);
+ | ^^^^^^^^^^^^^
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/uninhabited-const-issue-61744.rs:18:10
|
LL | dbg!(i32::CONSTANT);
- | ^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/deref-patterns/basic.rs b/src/test/ui/deref-patterns/basic.rs
new file mode 100644
index 000000000..249716040
--- /dev/null
+++ b/src/test/ui/deref-patterns/basic.rs
@@ -0,0 +1,17 @@
+// run-pass
+// check-run-results
+#![feature(string_deref_patterns)]
+
+fn main() {
+ test(Some(String::from("42")));
+ test(Some(String::new()));
+ test(None);
+}
+
+fn test(o: Option<String>) {
+ match o {
+ Some("42") => println!("the answer"),
+ Some(_) => println!("something else?"),
+ None => println!("nil"),
+ }
+}
diff --git a/src/test/ui/deref-patterns/basic.run.stdout b/src/test/ui/deref-patterns/basic.run.stdout
new file mode 100644
index 000000000..e50df0582
--- /dev/null
+++ b/src/test/ui/deref-patterns/basic.run.stdout
@@ -0,0 +1,3 @@
+the answer
+something else?
+nil
diff --git a/src/test/ui/deref-patterns/default-infer.rs b/src/test/ui/deref-patterns/default-infer.rs
new file mode 100644
index 000000000..050b84730
--- /dev/null
+++ b/src/test/ui/deref-patterns/default-infer.rs
@@ -0,0 +1,9 @@
+// check-pass
+#![feature(string_deref_patterns)]
+
+fn main() {
+ match <_ as Default>::default() {
+ "" => (),
+ _ => unreachable!(),
+ }
+}
diff --git a/src/test/ui/deref-patterns/gate.rs b/src/test/ui/deref-patterns/gate.rs
new file mode 100644
index 000000000..ff50e30de
--- /dev/null
+++ b/src/test/ui/deref-patterns/gate.rs
@@ -0,0 +1,7 @@
+// gate-test-string_deref_patterns
+fn main() {
+ match String::new() {
+ "" | _ => {}
+ //~^ mismatched types
+ }
+}
diff --git a/src/test/ui/deref-patterns/gate.stderr b/src/test/ui/deref-patterns/gate.stderr
new file mode 100644
index 000000000..993468b5e
--- /dev/null
+++ b/src/test/ui/deref-patterns/gate.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+ --> $DIR/gate.rs:4:9
+ |
+LL | match String::new() {
+ | ------------- this expression has type `String`
+LL | "" | _ => {}
+ | ^^ expected struct `String`, found `&str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/deref-patterns/refs.rs b/src/test/ui/deref-patterns/refs.rs
new file mode 100644
index 000000000..97e260d27
--- /dev/null
+++ b/src/test/ui/deref-patterns/refs.rs
@@ -0,0 +1,18 @@
+// check-pass
+#![feature(string_deref_patterns)]
+
+fn foo(s: &String) -> i32 {
+ match *s {
+ "a" => 42,
+ _ => -1,
+ }
+}
+
+fn bar(s: Option<&&&&String>) -> i32 {
+ match s {
+ Some(&&&&"&&&&") => 1,
+ _ => -1,
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/derived-errors/issue-31997-1.stderr b/src/test/ui/derived-errors/issue-31997-1.stderr
index 6d177666e..2f4aabf84 100644
--- a/src/test/ui/derived-errors/issue-31997-1.stderr
+++ b/src/test/ui/derived-errors/issue-31997-1.stderr
@@ -2,7 +2,7 @@ error[E0433]: failed to resolve: use of undeclared type `HashMap`
--> $DIR/issue-31997-1.rs:20:19
|
LL | let mut map = HashMap::new();
- | ^^^^^^^ not found in this scope
+ | ^^^^^^^ use of undeclared type `HashMap`
|
help: consider importing this struct
|
diff --git a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs
index 15d068175..6ab1fb7b0 100644
--- a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs
+++ b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs
@@ -3,7 +3,7 @@
#[derive(Debug)]
pub struct Whatever {
pub field0: (),
- field1: (), //~ ERROR fields `field1`, `field2`, `field3` and `field4` are never read
+ field1: (), //~ ERROR fields `field1`, `field2`, `field3`, and `field4` are never read
field2: (),
field3: (),
field4: (),
diff --git a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr
index 512b870fa..7f4f78ceb 100644
--- a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr
+++ b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr
@@ -1,4 +1,4 @@
-error: fields `field1`, `field2`, `field3` and `field4` are never read
+error: fields `field1`, `field2`, `field3`, and `field4` are never read
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:6:5
|
LL | pub struct Whatever {
diff --git a/src/test/ui/deriving/deriving-all-codegen.stdout b/src/test/ui/deriving/deriving-all-codegen.stdout
index 92fce6888..a63cbd4ca 100644
--- a/src/test/ui/deriving/deriving-all-codegen.stdout
+++ b/src/test/ui/deriving/deriving-all-codegen.stdout
@@ -463,16 +463,14 @@ struct PackedNonCopy(u8);
impl ::core::clone::Clone for PackedNonCopy {
#[inline]
fn clone(&self) -> PackedNonCopy {
- let Self(ref __self_0_0) = *self;
- PackedNonCopy(::core::clone::Clone::clone(__self_0_0))
+ PackedNonCopy(::core::clone::Clone::clone(&self.0))
}
}
#[automatically_derived]
impl ::core::fmt::Debug for PackedNonCopy {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
- let Self(ref __self_0_0) = *self;
::core::fmt::Formatter::debug_tuple_field1_finish(f, "PackedNonCopy",
- &__self_0_0)
+ &&self.0)
}
}
#[automatically_derived]
@@ -485,8 +483,7 @@ impl ::core::default::Default for PackedNonCopy {
#[automatically_derived]
impl ::core::hash::Hash for PackedNonCopy {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
- let Self(ref __self_0_0) = *self;
- ::core::hash::Hash::hash(__self_0_0, state)
+ ::core::hash::Hash::hash(&self.0, state)
}
}
#[automatically_derived]
@@ -494,11 +491,7 @@ impl ::core::marker::StructuralPartialEq for PackedNonCopy { }
#[automatically_derived]
impl ::core::cmp::PartialEq for PackedNonCopy {
#[inline]
- fn eq(&self, other: &PackedNonCopy) -> bool {
- let Self(ref __self_0_0) = *self;
- let Self(ref __self_1_0) = *other;
- *__self_0_0 == *__self_1_0
- }
+ fn eq(&self, other: &PackedNonCopy) -> bool { self.0 == other.0 }
}
#[automatically_derived]
impl ::core::marker::StructuralEq for PackedNonCopy { }
@@ -516,18 +509,14 @@ impl ::core::cmp::PartialOrd for PackedNonCopy {
#[inline]
fn partial_cmp(&self, other: &PackedNonCopy)
-> ::core::option::Option<::core::cmp::Ordering> {
- let Self(ref __self_0_0) = *self;
- let Self(ref __self_1_0) = *other;
- ::core::cmp::PartialOrd::partial_cmp(__self_0_0, __self_1_0)
+ ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
}
}
#[automatically_derived]
impl ::core::cmp::Ord for PackedNonCopy {
#[inline]
fn cmp(&self, other: &PackedNonCopy) -> ::core::cmp::Ordering {
- let Self(ref __self_0_0) = *self;
- let Self(ref __self_1_0) = *other;
- ::core::cmp::Ord::cmp(__self_0_0, __self_1_0)
+ ::core::cmp::Ord::cmp(&self.0, &other.0)
}
}
diff --git a/src/test/ui/deriving/issue-105101.rs b/src/test/ui/deriving/issue-105101.rs
new file mode 100644
index 000000000..1a377feb9
--- /dev/null
+++ b/src/test/ui/deriving/issue-105101.rs
@@ -0,0 +1,9 @@
+// compile-flags: --crate-type=lib
+
+#[derive(Default)] //~ ERROR multiple declared defaults
+enum E {
+ #[default]
+ A,
+ #[default]
+ A, //~ ERROR defined multiple times
+}
diff --git a/src/test/ui/deriving/issue-105101.stderr b/src/test/ui/deriving/issue-105101.stderr
new file mode 100644
index 000000000..0f6f67043
--- /dev/null
+++ b/src/test/ui/deriving/issue-105101.stderr
@@ -0,0 +1,29 @@
+error: multiple declared defaults
+ --> $DIR/issue-105101.rs:3:10
+ |
+LL | #[derive(Default)]
+ | ^^^^^^^
+...
+LL | A,
+ | - first default
+LL | #[default]
+LL | A,
+ | - additional default
+ |
+ = note: only one variant can be default
+ = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0428]: the name `A` is defined multiple times
+ --> $DIR/issue-105101.rs:8:5
+ |
+LL | A,
+ | - previous definition of the type `A` here
+LL | #[default]
+LL | A,
+ | ^ `A` redefined here
+ |
+ = note: `A` must be defined only once in the type namespace of this enum
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0428`.
diff --git a/src/test/ui/diagnostic-width/long-E0308.rs b/src/test/ui/diagnostic-width/long-E0308.rs
new file mode 100644
index 000000000..3fd7a7110
--- /dev/null
+++ b/src/test/ui/diagnostic-width/long-E0308.rs
@@ -0,0 +1,86 @@
+// compile-flags: --diagnostic-width=60
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
+
+struct Atype<T, K>(T, K);
+struct Btype<T, K>(T, K);
+struct Ctype<T, K>(T, K);
+
+fn main() {
+ let x: Atype<
+ Btype<
+ Ctype<
+ Atype<
+ Btype<
+ Ctype<
+ Atype<
+ Btype<
+ Ctype<i32, i32>,
+ i32
+ >,
+ i32
+ >,
+ i32
+ >,
+ i32
+ >,
+ i32
+ >,
+ i32
+ >,
+ i32
+ >,
+ i32
+ > = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
+ Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
+ Ok("")
+ ))))))))))))))))))))))))))))))
+ ))))))))))))))))))))))))))))));
+ //~^^^^^ ERROR E0308
+
+ let _ = Some(Ok(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
+ Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
+ Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(
+ Some(Some(Some(Some(Some(Some(Some(Some(Some("")))))))))
+ )))))))))))))))))
+ ))))))))))))))))))
+ ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
+ Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
+ Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
+ ))))))))))))))))))))))))))))))
+ ))))))))))))))))))))))));
+ //~^^^^^ ERROR E0308
+
+ let x: Atype<
+ Btype<
+ Ctype<
+ Atype<
+ Btype<
+ Ctype<
+ Atype<
+ Btype<
+ Ctype<i32, i32>,
+ i32
+ >,
+ i32
+ >,
+ i32
+ >,
+ i32
+ >,
+ i32
+ >,
+ i32
+ >,
+ i32
+ >,
+ i32
+ > = ();
+ //~^ ERROR E0308
+
+ let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
+ Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(
+ Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
+ ))))))))))))))))))))))))))))))
+ ))))))))))))))))))))))));
+ //~^^^^^ ERROR E0308
+}
diff --git a/src/test/ui/diagnostic-width/long-E0308.stderr b/src/test/ui/diagnostic-width/long-E0308.stderr
new file mode 100644
index 000000000..487ab23a1
--- /dev/null
+++ b/src/test/ui/diagnostic-width/long-E0308.stderr
@@ -0,0 +1,80 @@
+error[E0308]: mismatched types
+ --> $DIR/long-E0308.rs:33:9
+ |
+LL | let x: Atype<
+ | _____________-
+LL | | Btype<
+LL | | Ctype<
+LL | | Atype<
+... |
+LL | | i32
+LL | | > = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok...
+ | | _____-___^
+ | ||_____|
+ | | expected due to this
+LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok...
+LL | | Ok("")
+LL | | ))))))))))))))))))))))))))))))
+LL | | ))))))))))))))))))))))))))))));
+ | |__________________________________^ expected struct `Atype`, found enum `Result`
+ |
+ = note: expected struct `Atype<Btype<..., ...>, ...>`
+ the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+ found enum `Result<Result<..., ...>, ...>`
+ the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+
+error[E0308]: mismatched types
+ --> $DIR/long-E0308.rs:46:26
+ |
+LL | ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
+ | __________________________^
+LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(...
+LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
+LL | | ))))))))))))))))))))))))))))))
+LL | | ))))))))))))))))))))))));
+ | |____________________________^ expected enum `Option`, found enum `Result`
+ |
+ = note: expected enum `Option<Result<..., ...>>`
+ the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+ found enum `Result<Result<..., ...>, ...>`
+ the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+
+error[E0308]: mismatched types
+ --> $DIR/long-E0308.rs:77:9
+ |
+LL | let x: Atype<
+ | ____________-
+LL | | Btype<
+LL | | Ctype<
+LL | | Atype<
+... |
+LL | | i32
+LL | | > = ();
+ | | - ^^ expected struct `Atype`, found `()`
+ | |_____|
+ | expected due to this
+ |
+ = note: expected struct `Atype<Btype<..., ...>, ...>`
+ the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+ found unit type `()`
+
+error[E0308]: mismatched types
+ --> $DIR/long-E0308.rs:80:17
+ |
+LL | let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
+ | ____________--___^
+ | | |
+ | | expected due to this
+LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(...
+LL | | Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
+LL | | ))))))))))))))))))))))))))))))
+LL | | ))))))))))))))))))))))));
+ | |____________________________^ expected `()`, found enum `Result`
+ |
+ = note: expected unit type `()`
+ found enum `Result<Result<..., ...>, ...>`
+ the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/did_you_mean/issue-103909.rs b/src/test/ui/did_you_mean/issue-103909.rs
new file mode 100644
index 000000000..20b67cd10
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-103909.rs
@@ -0,0 +1,9 @@
+#![allow(unused_variables)]
+use std::fs::File;
+
+fn main() {
+ if Err(err) = File::open("hello.txt") {
+ //~^ ERROR: cannot find value `err` in this scope
+ //~| ERROR: mismatched types
+ }
+}
diff --git a/src/test/ui/did_you_mean/issue-103909.stderr b/src/test/ui/did_you_mean/issue-103909.stderr
new file mode 100644
index 000000000..864101747
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-103909.stderr
@@ -0,0 +1,26 @@
+error[E0425]: cannot find value `err` in this scope
+ --> $DIR/issue-103909.rs:5:12
+ |
+LL | if Err(err) = File::open("hello.txt") {
+ | ^^^ not found in this scope
+ |
+help: you might have meant to use pattern matching
+ |
+LL | if let Err(err) = File::open("hello.txt") {
+ | +++
+
+error[E0308]: mismatched types
+ --> $DIR/issue-103909.rs:5:8
+ |
+LL | if Err(err) = File::open("hello.txt") {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
+ |
+help: consider adding `let`
+ |
+LL | if let Err(err) = File::open("hello.txt") {
+ | +++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0425.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
index d27b05fe7..7229b9ac9 100644
--- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -12,10 +12,6 @@ LL | Foo::<i32>::bar(&1i8);
<i8 as Foo<u32>>
<i8 as Foo<u64>>
<i8 as Foo<u8>>
- <u8 as Foo<bool>>
- <u8 as Foo<u16>>
- <u8 as Foo<u32>>
- <u8 as Foo<u64>>
error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
--> $DIR/issue-39802-show-5-trait-impls.rs:25:21
@@ -26,11 +22,6 @@ LL | Foo::<i32>::bar(&1u8);
| required by a bound introduced by this call
|
= help: the following other types implement trait `Foo<B>`:
- <i8 as Foo<bool>>
- <i8 as Foo<u16>>
- <i8 as Foo<u32>>
- <i8 as Foo<u64>>
- <i8 as Foo<u8>>
<u8 as Foo<bool>>
<u8 as Foo<u16>>
<u8 as Foo<u32>>
diff --git a/src/test/ui/drop/drop_order.rs b/src/test/ui/drop/drop_order.rs
index 42385216a..5ce1fd54a 100644
--- a/src/test/ui/drop/drop_order.rs
+++ b/src/test/ui/drop/drop_order.rs
@@ -43,7 +43,7 @@ impl DropOrderCollector {
}
if {
- if self.option_loud_drop(7).is_some() && self.option_loud_drop(6).is_some() {
+ if self.option_loud_drop(6).is_some() && self.option_loud_drop(7).is_some() {
self.loud_drop(8);
true
} else {
@@ -118,17 +118,85 @@ impl DropOrderCollector {
}
}
+ fn and_chain(&self) {
+ // issue-103107
+ if self.option_loud_drop(1).is_some() // 1
+ && self.option_loud_drop(2).is_some() // 2
+ && self.option_loud_drop(3).is_some() // 3
+ && self.option_loud_drop(4).is_some() // 4
+ && self.option_loud_drop(5).is_some() // 5
+ {
+ self.print(6); // 6
+ }
+
+ let _ = self.option_loud_drop(7).is_some() // 1
+ && self.option_loud_drop(8).is_some() // 2
+ && self.option_loud_drop(9).is_some(); // 3
+ self.print(10); // 4
+
+ // Test associativity
+ if self.option_loud_drop(11).is_some() // 1
+ && (self.option_loud_drop(12).is_some() // 2
+ && self.option_loud_drop(13).is_some() // 3
+ && self.option_loud_drop(14).is_some()) // 4
+ && self.option_loud_drop(15).is_some() // 5
+ {
+ self.print(16); // 6
+ }
+ }
+
+ fn or_chain(&self) {
+ // issue-103107
+ if self.option_loud_drop(1).is_none() // 1
+ || self.option_loud_drop(2).is_none() // 2
+ || self.option_loud_drop(3).is_none() // 3
+ || self.option_loud_drop(4).is_none() // 4
+ || self.option_loud_drop(5).is_some() // 5
+ {
+ self.print(6); // 6
+ }
+
+ let _ = self.option_loud_drop(7).is_none() // 1
+ || self.option_loud_drop(8).is_none() // 2
+ || self.option_loud_drop(9).is_none(); // 3
+ self.print(10); // 4
+
+ // Test associativity
+ if self.option_loud_drop(11).is_none() // 1
+ || (self.option_loud_drop(12).is_none() // 2
+ || self.option_loud_drop(13).is_none() // 3
+ || self.option_loud_drop(14).is_none()) // 4
+ || self.option_loud_drop(15).is_some() // 5
+ {
+ self.print(16); // 6
+ }
+ }
+
+ fn mixed_and_or_chain(&self) {
+ // issue-103107
+ if self.option_loud_drop(1).is_none() // 1
+ || self.option_loud_drop(2).is_none() // 2
+ || self.option_loud_drop(3).is_some() // 3
+ && self.option_loud_drop(4).is_some() // 4
+ && self.option_loud_drop(5).is_none() // 5
+ || self.option_loud_drop(6).is_none() // 6
+ || self.option_loud_drop(7).is_some() // 7
+ {
+ self.print(8); // 8
+ }
+ }
+
fn let_chain(&self) {
// take the "then" branch
- if self.option_loud_drop(2).is_some() // 2
- && self.option_loud_drop(1).is_some() // 1
+ if self.option_loud_drop(1).is_some() // 1
+ && self.option_loud_drop(2).is_some() // 2
&& let Some(_d) = self.option_loud_drop(4) { // 4
self.print(3); // 3
}
// take the "else" branch
- if self.option_loud_drop(6).is_some() // 2
- && self.option_loud_drop(5).is_some() // 1
+ if self.option_loud_drop(5).is_some() // 1
+ && self.option_loud_drop(6).is_some() // 2
&& let None = self.option_loud_drop(8) { // 4
unreachable!();
} else {
@@ -152,8 +220,8 @@ impl DropOrderCollector {
}
// let exprs last
- if self.option_loud_drop(20).is_some() // 2
- && self.option_loud_drop(19).is_some() // 1
+ if self.option_loud_drop(19).is_some() // 1
+ && self.option_loud_drop(20).is_some() // 2
&& let Some(_d) = self.option_loud_drop(23) // 5
&& let Some(_e) = self.option_loud_drop(22) { // 4
self.print(21); // 3
@@ -187,6 +255,21 @@ fn main() {
collector.if_();
collector.assert_sorted();
+ println!("-- and chain --");
+ let collector = DropOrderCollector::default();
+ collector.and_chain();
+ collector.assert_sorted();
+
+ println!("-- or chain --");
+ let collector = DropOrderCollector::default();
+ collector.or_chain();
+ collector.assert_sorted();
+
+ println!("-- mixed and/or chain --");
+ let collector = DropOrderCollector::default();
+ collector.mixed_and_or_chain();
+ collector.assert_sorted();
+
println!("-- if let --");
let collector = DropOrderCollector::default();
collector.if_let();
diff --git a/src/test/ui/drop/issue-103107.rs b/src/test/ui/drop/issue-103107.rs
new file mode 100644
index 000000000..5f4475956
--- /dev/null
+++ b/src/test/ui/drop/issue-103107.rs
@@ -0,0 +1,37 @@
+// check-pass
+// compile-flags: -Z validate-mir
+
+struct Foo<'a>(&'a mut u32);
+
+impl<'a> Drop for Foo<'a> {
+ fn drop(&mut self) {
+ *self.0 = 0;
+ }
+}
+
+fn and() {
+ let mut foo = 0;
+ // This used to compile also before the fix
+ if true && *Foo(&mut foo).0 == 0 && ({ foo = 0; true}) {}
+
+ // This used to fail before the fix
+ if *Foo(&mut foo).0 == 0 && ({ foo = 0; true}) {}
+
+ println!("{foo}");
+}
+
+fn or() {
+ let mut foo = 0;
+ // This used to compile also before the fix
+ if false || *Foo(&mut foo).0 == 1 || ({ foo = 0; true}) {}
+
+ // This used to fail before the fix
+ if *Foo(&mut foo).0 == 1 || ({ foo = 0; true}) {}
+
+ println!("{foo}");
+}
+
+fn main() {
+ and();
+ or();
+}
diff --git a/src/test/ui/drop/repeat-drop-2.stderr b/src/test/ui/drop/repeat-drop-2.stderr
index 7357551c4..f030228f7 100644
--- a/src/test/ui/drop/repeat-drop-2.stderr
+++ b/src/test/ui/drop/repeat-drop-2.stderr
@@ -7,6 +7,11 @@ LL | let _bar = foo;
| --- value moved here
LL | let _baz = [foo; 0];
| ^^^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _bar = foo.clone();
+ | ++++++++
error[E0493]: destructor of `String` cannot be evaluated at compile-time
--> $DIR/repeat-drop-2.rs:7:25
diff --git a/src/test/ui/issues/issue-54943-1.rs b/src/test/ui/dropck/issue-54943-1.rs
index ec682d960..ec682d960 100644
--- a/src/test/ui/issues/issue-54943-1.rs
+++ b/src/test/ui/dropck/issue-54943-1.rs
diff --git a/src/test/ui/issues/issue-54943-2.rs b/src/test/ui/dropck/issue-54943-2.rs
index d400ae58d..d400ae58d 100644
--- a/src/test/ui/issues/issue-54943-2.rs
+++ b/src/test/ui/dropck/issue-54943-2.rs
diff --git a/src/test/ui/duplicate/duplicate-type-parameter.stderr b/src/test/ui/duplicate/duplicate-type-parameter.stderr
index 6754574f0..628f898d5 100644
--- a/src/test/ui/duplicate/duplicate-type-parameter.stderr
+++ b/src/test/ui/duplicate/duplicate-type-parameter.stderr
@@ -55,10 +55,10 @@ LL | impl<T,T> Qux<T,T> for Option<T> {}
| first use of `T`
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
- --> $DIR/duplicate-type-parameter.rs:24:6
+ --> $DIR/duplicate-type-parameter.rs:24:8
|
LL | impl<T,T> Qux<T,T> for Option<T> {}
- | ^ unconstrained type parameter
+ | ^ unconstrained type parameter
error: aborting due to 8 previous errors
diff --git a/src/test/ui/dyn-star/align.normal.stderr b/src/test/ui/dyn-star/align.normal.stderr
new file mode 100644
index 000000000..983d7bf6e
--- /dev/null
+++ b/src/test/ui/dyn-star/align.normal.stderr
@@ -0,0 +1,11 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/align.rs:4:12
+ |
+LL | #![feature(dyn_star)]
+ | ^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/dyn-star/align.over_aligned.stderr b/src/test/ui/dyn-star/align.over_aligned.stderr
new file mode 100644
index 000000000..6b6fc55d8
--- /dev/null
+++ b/src/test/ui/dyn-star/align.over_aligned.stderr
@@ -0,0 +1,20 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/align.rs:4:12
+ |
+LL | #![feature(dyn_star)]
+ | ^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: `AlignedUsize` needs to be a pointer-sized type
+ --> $DIR/align.rs:15:13
+ |
+LL | let x = AlignedUsize(12) as dyn* Debug;
+ | ^^^^^^^^^^^^^^^^ `AlignedUsize` needs to be a pointer-sized type
+ |
+ = help: the trait `PointerSized` is not implemented for `AlignedUsize`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/dyn-star/align.rs b/src/test/ui/dyn-star/align.rs
new file mode 100644
index 000000000..fb41a05a0
--- /dev/null
+++ b/src/test/ui/dyn-star/align.rs
@@ -0,0 +1,17 @@
+// revisions: normal over_aligned
+//[normal] check-pass
+
+#![feature(dyn_star)]
+//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+
+use std::fmt::Debug;
+
+#[cfg_attr(over_aligned, repr(C, align(1024)))]
+#[cfg_attr(not(over_aligned), repr(C))]
+#[derive(Debug)]
+struct AlignedUsize(usize);
+
+fn main() {
+ let x = AlignedUsize(12) as dyn* Debug;
+ //[over_aligned]~^ ERROR `AlignedUsize` needs to be a pointer-sized type
+}
diff --git a/src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs b/src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs
new file mode 100644
index 000000000..e19e36cc7
--- /dev/null
+++ b/src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs
@@ -0,0 +1,15 @@
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn dyn_debug(_: (dyn* Debug + '_)) {
+
+}
+
+fn polymorphic<T: Debug + ?Sized>(t: &T) {
+ dyn_debug(t);
+ //~^ ERROR `&T` needs to be a pointer-sized type
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr b/src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr
new file mode 100644
index 000000000..53ccbe43d
--- /dev/null
+++ b/src/test/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr
@@ -0,0 +1,15 @@
+error[E0277]: `&T` needs to be a pointer-sized type
+ --> $DIR/check-size-at-cast-polymorphic-bad.rs:11:15
+ |
+LL | dyn_debug(t);
+ | ^ `&T` needs to be a pointer-sized type
+ |
+ = help: the trait `PointerSized` is not implemented for `&T`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+ |
+LL | fn polymorphic<T: Debug + ?Sized>(t: &T) where &T: PointerSized {
+ | ++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/dyn-star/check-size-at-cast-polymorphic.rs b/src/test/ui/dyn-star/check-size-at-cast-polymorphic.rs
new file mode 100644
index 000000000..5c0a3d256
--- /dev/null
+++ b/src/test/ui/dyn-star/check-size-at-cast-polymorphic.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn dyn_debug(_: (dyn* Debug + '_)) {
+
+}
+
+fn polymorphic<T: Debug>(t: &T) {
+ dyn_debug(t);
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-star/check-size-at-cast.rs b/src/test/ui/dyn-star/check-size-at-cast.rs
new file mode 100644
index 000000000..1f22f7983
--- /dev/null
+++ b/src/test/ui/dyn-star/check-size-at-cast.rs
@@ -0,0 +1,10 @@
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn main() {
+ let i = [1, 2, 3, 4] as dyn* Debug;
+ //~^ ERROR `[i32; 4]` needs to be a pointer-sized type
+ dbg!(i);
+}
diff --git a/src/test/ui/dyn-star/check-size-at-cast.stderr b/src/test/ui/dyn-star/check-size-at-cast.stderr
new file mode 100644
index 000000000..af2a1ccf7
--- /dev/null
+++ b/src/test/ui/dyn-star/check-size-at-cast.stderr
@@ -0,0 +1,11 @@
+error[E0277]: `[i32; 4]` needs to be a pointer-sized type
+ --> $DIR/check-size-at-cast.rs:7:13
+ |
+LL | let i = [1, 2, 3, 4] as dyn* Debug;
+ | ^^^^^^^^^^^^ `[i32; 4]` needs to be a pointer-sized type
+ |
+ = help: the trait `PointerSized` is not implemented for `[i32; 4]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/dyn-star/dispatch-on-pin-mut.rs b/src/test/ui/dyn-star/dispatch-on-pin-mut.rs
new file mode 100644
index 000000000..5774c8b2a
--- /dev/null
+++ b/src/test/ui/dyn-star/dispatch-on-pin-mut.rs
@@ -0,0 +1,52 @@
+// run-pass
+// edition:2021
+// check-run-results
+
+#![feature(dyn_star)]
+//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+
+use std::future::Future;
+
+async fn foo(f: dyn* Future<Output = i32>) {
+ println!("value: {}", f.await);
+}
+
+async fn async_main() {
+ foo(Box::pin(async { 1 })).await
+}
+
+// ------------------------------------------------------------------------- //
+// Implementation Details Below...
+
+use std::pin::Pin;
+use std::task::*;
+
+pub fn noop_waker() -> Waker {
+ let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE);
+
+ // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld
+ unsafe { Waker::from_raw(raw) }
+}
+
+const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
+
+unsafe fn noop_clone(_p: *const ()) -> RawWaker {
+ RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE)
+}
+
+unsafe fn noop(_p: *const ()) {}
+
+fn main() {
+ let mut fut = async_main();
+
+ // Poll loop, just to test the future...
+ let waker = noop_waker();
+ let ctx = &mut Context::from_waker(&waker);
+
+ loop {
+ match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } {
+ Poll::Pending => {}
+ Poll::Ready(()) => break,
+ }
+ }
+}
diff --git a/src/test/ui/dyn-star/dispatch-on-pin-mut.run.stdout b/src/test/ui/dyn-star/dispatch-on-pin-mut.run.stdout
new file mode 100644
index 000000000..96c5ca698
--- /dev/null
+++ b/src/test/ui/dyn-star/dispatch-on-pin-mut.run.stdout
@@ -0,0 +1 @@
+value: 1
diff --git a/src/test/ui/dyn-star/dispatch-on-pin-mut.stderr b/src/test/ui/dyn-star/dispatch-on-pin-mut.stderr
new file mode 100644
index 000000000..fdf74aa7e
--- /dev/null
+++ b/src/test/ui/dyn-star/dispatch-on-pin-mut.stderr
@@ -0,0 +1,11 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/dispatch-on-pin-mut.rs:5:12
+ |
+LL | #![feature(dyn_star)]
+ | ^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs b/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs
new file mode 100644
index 000000000..c12b16f16
--- /dev/null
+++ b/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs
@@ -0,0 +1,27 @@
+// run-pass
+// check-run-results
+
+#![feature(dyn_star)]
+//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait AddOne {
+ fn add1(&mut self) -> usize;
+}
+
+impl AddOne for usize {
+ fn add1(&mut self) -> usize {
+ *self += 1;
+ *self
+ }
+}
+
+fn add_one(i: &mut (dyn* AddOne + '_)) -> usize {
+ i.add1()
+}
+
+fn main() {
+ let mut x = 42usize as dyn* AddOne;
+
+ println!("{}", add_one(&mut x));
+ println!("{}", add_one(&mut x));
+}
diff --git a/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.run.stdout b/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.run.stdout
new file mode 100644
index 000000000..b4db3ed70
--- /dev/null
+++ b/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.run.stdout
@@ -0,0 +1,2 @@
+43
+44
diff --git a/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.stderr b/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.stderr
new file mode 100644
index 000000000..933c13383
--- /dev/null
+++ b/src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.stderr
@@ -0,0 +1,11 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/dont-unsize-coerce-dyn-star.rs:4:12
+ |
+LL | #![feature(dyn_star)]
+ | ^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/dyn-star/dyn-async-trait.rs b/src/test/ui/dyn-star/dyn-async-trait.rs
new file mode 100644
index 000000000..9b27133b4
--- /dev/null
+++ b/src/test/ui/dyn-star/dyn-async-trait.rs
@@ -0,0 +1,36 @@
+// check-pass
+// edition: 2021
+
+// This test case is meant to demonstrate how close we can get to async
+// functions in dyn traits with the current level of dyn* support.
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::future::Future;
+
+trait DynAsyncCounter {
+ fn increment<'a>(&'a mut self) -> dyn* Future<Output = usize> + 'a;
+}
+
+struct MyCounter {
+ count: usize,
+}
+
+impl DynAsyncCounter for MyCounter {
+ fn increment<'a>(&'a mut self) -> dyn* Future<Output = usize> + 'a {
+ Box::pin(async {
+ self.count += 1;
+ self.count
+ })
+ }
+}
+
+async fn do_counter(counter: &mut dyn DynAsyncCounter) -> usize {
+ counter.increment().await
+}
+
+fn main() {
+ let mut counter = MyCounter { count: 0 };
+ let _ = do_counter(&mut counter);
+}
diff --git a/src/test/ui/dyn-star/issue-102430.rs b/src/test/ui/dyn-star/issue-102430.rs
new file mode 100644
index 000000000..244ecda66
--- /dev/null
+++ b/src/test/ui/dyn-star/issue-102430.rs
@@ -0,0 +1,32 @@
+// check-pass
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+trait AddOne {
+ fn add1(&mut self) -> usize;
+}
+
+impl AddOne for usize {
+ fn add1(&mut self) -> usize {
+ *self += 1;
+ *self
+ }
+}
+
+impl AddOne for &mut usize {
+ fn add1(&mut self) -> usize {
+ (*self).add1()
+ }
+}
+
+fn add_one(mut i: dyn* AddOne + '_) -> usize {
+ i.add1()
+}
+
+fn main() {
+ let mut x = 42usize;
+ let y = &mut x as (dyn* AddOne + '_);
+
+ println!("{}", add_one(y));
+}
diff --git a/src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.rs b/src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.rs
new file mode 100644
index 000000000..a4eb669e3
--- /dev/null
+++ b/src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.rs
@@ -0,0 +1,13 @@
+#![feature(dyn_star, trait_upcasting)]
+//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait A: B {}
+trait B {}
+impl A for usize {}
+impl B for usize {}
+
+fn main() {
+ let x: Box<dyn* A> = Box::new(1usize as dyn* A);
+ let y: Box<dyn* B> = x;
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr b/src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr
new file mode 100644
index 000000000..2fc751b3b
--- /dev/null
+++ b/src/test/ui/dyn-star/no-unsize-coerce-dyn-trait.stderr
@@ -0,0 +1,23 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/no-unsize-coerce-dyn-trait.rs:1:12
+ |
+LL | #![feature(dyn_star, trait_upcasting)]
+ | ^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+ --> $DIR/no-unsize-coerce-dyn-trait.rs:11:26
+ |
+LL | let y: Box<dyn* B> = x;
+ | ----------- ^ expected trait `B`, found trait `A`
+ | |
+ | expected due to this
+ |
+ = note: expected struct `Box<dyn* B>`
+ found struct `Box<dyn* A>`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/dyn-star/return.rs b/src/test/ui/dyn-star/return.rs
new file mode 100644
index 000000000..fa3d8d7d5
--- /dev/null
+++ b/src/test/ui/dyn-star/return.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+#![feature(dyn_star)]
+//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+
+fn _foo() -> dyn* Unpin {
+ 4usize
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-star/return.stderr b/src/test/ui/dyn-star/return.stderr
new file mode 100644
index 000000000..e000351a6
--- /dev/null
+++ b/src/test/ui/dyn-star/return.stderr
@@ -0,0 +1,11 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/return.rs:3:12
+ |
+LL | #![feature(dyn_star)]
+ | ^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs b/src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs
new file mode 100644
index 000000000..1e8cafe15
--- /dev/null
+++ b/src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs
@@ -0,0 +1,9 @@
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+fn main() {
+ let i = 42 as &dyn* Debug;
+ //~^ ERROR non-primitive cast: `i32` as `&dyn* Debug`
+}
diff --git a/src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr b/src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr
new file mode 100644
index 000000000..f6444a60a
--- /dev/null
+++ b/src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr
@@ -0,0 +1,9 @@
+error[E0605]: non-primitive cast: `i32` as `&dyn* Debug`
+ --> $DIR/unsize-into-ref-dyn-star.rs:7:13
+ |
+LL | let i = 42 as &dyn* Debug;
+ | ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/src/test/ui/dyn-star/upcast.rs b/src/test/ui/dyn-star/upcast.rs
index cee76ada7..c667ac143 100644
--- a/src/test/ui/dyn-star/upcast.rs
+++ b/src/test/ui/dyn-star/upcast.rs
@@ -1,7 +1,6 @@
-// run-pass
+// known-bug: #104800
#![feature(dyn_star, trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo: Bar {
fn hello(&self);
diff --git a/src/test/ui/dyn-star/upcast.stderr b/src/test/ui/dyn-star/upcast.stderr
new file mode 100644
index 000000000..6a95f7754
--- /dev/null
+++ b/src/test/ui/dyn-star/upcast.stderr
@@ -0,0 +1,20 @@
+warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/upcast.rs:3:12
+ |
+LL | #![feature(dyn_star, trait_upcasting)]
+ | ^^^^^^^^
+ |
+ = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: `dyn* Foo` needs to be a pointer-sized type
+ --> $DIR/upcast.rs:30:23
+ |
+LL | let w: dyn* Bar = w;
+ | ^ `dyn* Foo` needs to be a pointer-sized type
+ |
+ = help: the trait `PointerSized` is not implemented for `dyn* Foo`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/editions/edition-keywords-2015-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2015-2015-parsing.stderr
index 3435fdfd7..39944622d 100644
--- a/src/test/ui/editions/edition-keywords-2015-2015-parsing.stderr
+++ b/src/test/ui/editions/edition-keywords-2015-2015-parsing.stderr
@@ -3,12 +3,24 @@ error: no rules expected the token `r#async`
|
LL | r#async = consumes_async!(r#async);
| ^^^^^^^ no rules expected this token in macro call
+ |
+note: while trying to match `async`
+ --> $DIR/auxiliary/edition-kw-macro-2015.rs:17:6
+ |
+LL | (async) => (1)
+ | ^^^^^
error: no rules expected the token `async`
--> $DIR/edition-keywords-2015-2015-parsing.rs:17:35
|
LL | r#async = consumes_async_raw!(async);
| ^^^^^ no rules expected this token in macro call
+ |
+note: while trying to match `r#async`
+ --> $DIR/auxiliary/edition-kw-macro-2015.rs:22:6
+ |
+LL | (r#async) => (1)
+ | ^^^^^^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/editions/edition-keywords-2015-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2015-2018-parsing.stderr
index 6e86d746f..fa83908e6 100644
--- a/src/test/ui/editions/edition-keywords-2015-2018-parsing.stderr
+++ b/src/test/ui/editions/edition-keywords-2015-2018-parsing.stderr
@@ -3,12 +3,24 @@ error: no rules expected the token `r#async`
|
LL | r#async = consumes_async!(r#async);
| ^^^^^^^ no rules expected this token in macro call
+ |
+note: while trying to match `async`
+ --> $DIR/auxiliary/edition-kw-macro-2018.rs:17:6
+ |
+LL | (async) => (1)
+ | ^^^^^
error: no rules expected the token `async`
--> $DIR/edition-keywords-2015-2018-parsing.rs:17:35
|
LL | r#async = consumes_async_raw!(async);
| ^^^^^ no rules expected this token in macro call
+ |
+note: while trying to match `r#async`
+ --> $DIR/auxiliary/edition-kw-macro-2018.rs:22:6
+ |
+LL | (r#async) => (1)
+ | ^^^^^^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
index e1eea725b..1a4a94e97 100644
--- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
+++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
@@ -25,12 +25,24 @@ error: no rules expected the token `r#async`
|
LL | r#async = consumes_async!(r#async);
| ^^^^^^^ no rules expected this token in macro call
+ |
+note: while trying to match `async`
+ --> $DIR/auxiliary/edition-kw-macro-2015.rs:17:6
+ |
+LL | (async) => (1)
+ | ^^^^^
error: no rules expected the token `async`
--> $DIR/edition-keywords-2018-2015-parsing.rs:21:35
|
LL | r#async = consumes_async_raw!(async);
| ^^^^^ no rules expected this token in macro call
+ |
+note: while trying to match `r#async`
+ --> $DIR/auxiliary/edition-kw-macro-2015.rs:22:6
+ |
+LL | (r#async) => (1)
+ | ^^^^^^^
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
--> $DIR/auxiliary/edition-kw-macro-2015.rs:27:23
diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
index 0af4da09c..19eb7ac98 100644
--- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
+++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
@@ -25,12 +25,24 @@ error: no rules expected the token `r#async`
|
LL | r#async = consumes_async!(r#async);
| ^^^^^^^ no rules expected this token in macro call
+ |
+note: while trying to match `async`
+ --> $DIR/auxiliary/edition-kw-macro-2018.rs:17:6
+ |
+LL | (async) => (1)
+ | ^^^^^
error: no rules expected the token `async`
--> $DIR/edition-keywords-2018-2018-parsing.rs:21:35
|
LL | r#async = consumes_async_raw!(async);
| ^^^^^ no rules expected this token in macro call
+ |
+note: while trying to match `r#async`
+ --> $DIR/auxiliary/edition-kw-macro-2018.rs:22:6
+ |
+LL | (r#async) => (1)
+ | ^^^^^^^
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
--> $DIR/auxiliary/edition-kw-macro-2018.rs:27:23
diff --git a/src/test/ui/empty/empty-comment.stderr b/src/test/ui/empty/empty-comment.stderr
index f583dbbdc..7cc8d8fe9 100644
--- a/src/test/ui/empty/empty-comment.stderr
+++ b/src/test/ui/empty/empty-comment.stderr
@@ -6,6 +6,12 @@ LL | macro_rules! one_arg_macro {
...
LL | one_arg_macro!(/**/);
| ^^^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments
+ |
+note: while trying to match meta-variable `$fmt:expr`
+ --> $DIR/empty-comment.rs:6:6
+ |
+LL | ($fmt:expr) => (print!(concat!($fmt, "\n")));
+ | ^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/empty/empty-struct-braces-expr.rs b/src/test/ui/empty/empty-struct-braces-expr.rs
index f4144277f..2aab3e777 100644
--- a/src/test/ui/empty/empty-struct-braces-expr.rs
+++ b/src/test/ui/empty/empty-struct-braces-expr.rs
@@ -17,7 +17,7 @@ fn main() {
//~^ ERROR expected function, tuple struct or tuple variant, found struct `Empty1`
let e3 = E::Empty3; //~ ERROR expected value, found struct variant `E::Empty3`
let e3 = E::Empty3();
- //~^ ERROR expected function, tuple struct or tuple variant, found struct variant `E::Empty3`
+ //~^ ERROR expected value, found struct variant `E::Empty3`
let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1`
let xe1 = XEmpty1();
diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr
index 5b0ca613f..e1a7a02a5 100644
--- a/src/test/ui/empty/empty-struct-braces-expr.stderr
+++ b/src/test/ui/empty/empty-struct-braces-expr.stderr
@@ -21,24 +21,6 @@ help: a unit struct with a similar name exists
LL | let e1 = XEmpty2;
| ~~~~~~~
-error[E0423]: expected value, found struct variant `E::Empty3`
- --> $DIR/empty-struct-braces-expr.rs:18:14
- |
-LL | Empty3 {}
- | --------- `E::Empty3` defined here
-...
-LL | let e3 = E::Empty3;
- | ^^^^^^^^^ help: use struct literal syntax instead: `E::Empty3 {}`
-
-error[E0423]: expected function, tuple struct or tuple variant, found struct variant `E::Empty3`
- --> $DIR/empty-struct-braces-expr.rs:19:14
- |
-LL | Empty3 {}
- | --------- `E::Empty3` defined here
-...
-LL | let e3 = E::Empty3();
- | ^^^^^^^^^^^ help: use struct literal syntax instead: `E::Empty3 {}`
-
error[E0423]: expected value, found struct `XEmpty1`
--> $DIR/empty-struct-braces-expr.rs:22:15
|
@@ -84,6 +66,18 @@ help: a unit struct with a similar name exists
LL | let e1 = XEmpty2();
| ~~~~~~~
+error[E0533]: expected value, found struct variant `E::Empty3`
+ --> $DIR/empty-struct-braces-expr.rs:18:14
+ |
+LL | let e3 = E::Empty3;
+ | ^^^^^^^^^ not a value
+
+error[E0533]: expected value, found struct variant `E::Empty3`
+ --> $DIR/empty-struct-braces-expr.rs:19:14
+ |
+LL | let e3 = E::Empty3();
+ | ^^^^^^^^^ not a value
+
error[E0423]: expected function, tuple struct or tuple variant, found struct `XEmpty1`
--> $DIR/empty-struct-braces-expr.rs:23:15
|
@@ -132,5 +126,5 @@ LL | XE::Empty1 {};
error: aborting due to 9 previous errors
-Some errors have detailed explanations: E0423, E0599.
+Some errors have detailed explanations: E0423, E0533, E0599.
For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/empty/empty-struct-braces-pat-1.stderr b/src/test/ui/empty/empty-struct-braces-pat-1.stderr
index 0215a9e59..14e09fc27 100644
--- a/src/test/ui/empty/empty-struct-braces-pat-1.stderr
+++ b/src/test/ui/empty/empty-struct-braces-pat-1.stderr
@@ -1,34 +1,15 @@
-error[E0532]: expected unit struct, unit variant or constant, found struct variant `E::Empty3`
+error[E0533]: expected unit struct, unit variant or constant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-1.rs:24:9
|
-LL | Empty3 {}
- | --------- `E::Empty3` defined here
-...
LL | E::Empty3 => ()
- | ^^^^^^^^^ help: use struct pattern syntax instead: `E::Empty3 {}`
+ | ^^^^^^^^^ not a unit struct, unit variant or constant
-error[E0532]: expected unit struct, unit variant or constant, found struct variant `XE::XEmpty3`
+error[E0533]: expected unit struct, unit variant or constant, found struct variant `XE::XEmpty3`
--> $DIR/empty-struct-braces-pat-1.rs:31:9
|
LL | XE::XEmpty3 => ()
- | ^^^^^^^^^^^
- |
- ::: $DIR/auxiliary/empty-struct.rs:6:5
- |
-LL | XEmpty3 {},
- | ------- `XE::XEmpty3` defined here
-LL | XEmpty4,
- | ------- similarly named unit variant `XEmpty4` defined here
- |
-help: use struct pattern syntax instead
- |
-LL | XE::XEmpty3 { /* fields */ } => ()
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: a unit variant with a similar name exists
- |
-LL | XE::XEmpty4 => ()
- | ~~~~~~~
+ | ^^^^^^^^^^^ not a unit struct, unit variant or constant
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0532`.
+For more information about this error, try `rustc --explain E0533`.
diff --git a/src/test/ui/empty/empty-struct-braces-pat-3.stderr b/src/test/ui/empty/empty-struct-braces-pat-3.stderr
index 615e7fb4a..00c8b12e6 100644
--- a/src/test/ui/empty/empty-struct-braces-pat-3.stderr
+++ b/src/test/ui/empty/empty-struct-braces-pat-3.stderr
@@ -1,67 +1,27 @@
-error[E0532]: expected tuple struct or tuple variant, found struct variant `E::Empty3`
+error[E0164]: expected tuple struct or tuple variant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-3.rs:17:9
|
-LL | Empty3 {}
- | --------- `E::Empty3` defined here
-...
LL | E::Empty3() => ()
- | ^^^^^^^^^^^ help: use struct pattern syntax instead: `E::Empty3 {}`
+ | ^^^^^^^^^^^ not a tuple struct or tuple variant
-error[E0532]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3`
+error[E0164]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3`
--> $DIR/empty-struct-braces-pat-3.rs:21:9
|
LL | XE::XEmpty3() => ()
- | ^^^^^^^^^^^^^
- |
- ::: $DIR/auxiliary/empty-struct.rs:6:5
- |
-LL | XEmpty3 {},
- | ------- `XE::XEmpty3` defined here
-LL | XEmpty4,
-LL | XEmpty5(),
- | ------- similarly named tuple variant `XEmpty5` defined here
- |
-help: use struct pattern syntax instead
- |
-LL | XE::XEmpty3 { /* fields */ } => ()
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: a tuple variant with a similar name exists
- |
-LL | XE::XEmpty5() => ()
- | ~~~~~~~
+ | ^^^^^^^^^^^^^ not a tuple struct or tuple variant
-error[E0532]: expected tuple struct or tuple variant, found struct variant `E::Empty3`
+error[E0164]: expected tuple struct or tuple variant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-3.rs:25:9
|
-LL | Empty3 {}
- | --------- `E::Empty3` defined here
-...
LL | E::Empty3(..) => ()
- | ^^^^^^^^^^^^^ help: use struct pattern syntax instead: `E::Empty3 {}`
+ | ^^^^^^^^^^^^^ not a tuple struct or tuple variant
-error[E0532]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3`
+error[E0164]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3`
--> $DIR/empty-struct-braces-pat-3.rs:29:9
|
LL | XE::XEmpty3(..) => ()
- | ^^^^^^^^^^^^^^^
- |
- ::: $DIR/auxiliary/empty-struct.rs:6:5
- |
-LL | XEmpty3 {},
- | ------- `XE::XEmpty3` defined here
-LL | XEmpty4,
-LL | XEmpty5(),
- | ------- similarly named tuple variant `XEmpty5` defined here
- |
-help: use struct pattern syntax instead
- |
-LL | XE::XEmpty3 { /* fields */ } => ()
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: a tuple variant with a similar name exists
- |
-LL | XE::XEmpty5(..) => ()
- | ~~~~~~~
+ | ^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to 4 previous errors
-For more information about this error, try `rustc --explain E0532`.
+For more information about this error, try `rustc --explain E0164`.
diff --git a/src/test/ui/enum-discriminant/get_discr.rs b/src/test/ui/enum-discriminant/get_discr.rs
new file mode 100644
index 000000000..71eea4e0f
--- /dev/null
+++ b/src/test/ui/enum-discriminant/get_discr.rs
@@ -0,0 +1,114 @@
+// run-pass
+
+// Now that there are several variations on the code generated in
+// `codegen_get_discr`, let's make sure the various cases yield the correct
+// result.
+
+// To get the discriminant of an E<X1> value, there are no shortcuts - we must
+// do the full algorithm.
+#[repr(u8)]
+pub enum X1 {
+ _1 = 1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
+ _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
+ _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
+ _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
+ _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
+ _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
+ _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
+ _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
+ _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144,
+ _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160,
+ _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176,
+ _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192,
+ _193, _194, _195, _196, _197, _198, _199, _200, _201, _202, _203, _204, _205, _206, _207, _208,
+ _209, _210, _211, _212, _213, _214, _215, _216, _217, _218, _219, _220, _221, _222, _223, _224,
+ _225, _226, _227, _228, _229, _230, _231, _232, _233, _234, _235, _236, _237, _238, _239, _240,
+ _241, _242, _243, _244, _245, _246, _247, _248, _249, _250, _251, _252, _253, _254,
+}
+
+#[repr(i8)]
+pub enum X2 {
+ _1 = -1, _2 = 0, _3 = 1,
+}
+
+#[repr(i8)]
+pub enum X3 {
+ _1 = -128, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
+ _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
+ _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
+ _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
+ _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
+ _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
+ _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
+ _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
+ _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144,
+ _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160,
+ _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176,
+ _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192,
+ _193, _194, _195, _196, _197, _198, _199, _200, _201, _202, _203, _204, _205, _206, _207, _208,
+ _209, _210, _211, _212, _213, _214, _215, _216, _217, _218, _219, _220, _221, _222, _223, _224,
+ _225, _226, _227, _228, _229, _230, _231, _232, _233, _234, _235, _236, _237, _238, _239, _240,
+ _241, _242, _243, _244, _245, _246, _247, _248, _249, _250, _251, _252, _253, _254,
+}
+
+#[repr(i8)]
+pub enum X4 {
+ _1 = -126, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,
+ _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32,
+ _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48,
+ _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64,
+ _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,
+ _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
+ _97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
+ _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
+ _129, _130, _131, _132, _133, _134, _135, _136, _137, _138, _139, _140, _141, _142, _143, _144,
+ _145, _146, _147, _148, _149, _150, _151, _152, _153, _154, _155, _156, _157, _158, _159, _160,
+ _161, _162, _163, _164, _165, _166, _167, _168, _169, _170, _171, _172, _173, _174, _175, _176,
+ _177, _178, _179, _180, _181, _182, _183, _184, _185, _186, _187, _188, _189, _190, _191, _192,
+ _193, _194, _195, _196, _197, _198, _199, _200, _201, _202, _203, _204, _205, _206, _207, _208,
+ _209, _210, _211, _212, _213, _214, _215, _216, _217, _218, _219, _220, _221, _222, _223, _224,
+ _225, _226, _227, _228, _229, _230, _231, _232, _233, _234, _235, _236, _237, _238, _239, _240,
+ _241, _242, _243, _244, _245, _246, _247, _248, _249, _250, _251, _252, _253, _254,
+}
+
+pub enum E<X> {
+ A(X),
+ B,
+ C,
+}
+
+pub fn match_e<X>(e: E<X>) -> u8 {
+ use E::*;
+ match e {
+ A(_) => 0,
+ B => 1,
+ C => 2,
+ }
+}
+
+fn main() {
+ assert_eq!(match_e(E::A(X1::_1)), 0);
+ assert_eq!(match_e(E::A(X1::_2)), 0);
+ assert_eq!(match_e(E::A(X1::_254)), 0);
+ assert_eq!(match_e(E::<X1>::B), 1);
+ assert_eq!(match_e(E::<X1>::C), 2);
+ assert_eq!(match_e(E::A(X2::_1)), 0);
+ assert_eq!(match_e(E::A(X2::_2)), 0);
+ assert_eq!(match_e(E::A(X2::_3)), 0);
+ assert_eq!(match_e(E::<X2>::B), 1);
+ assert_eq!(match_e(E::<X2>::C), 2);
+ assert_eq!(match_e(E::A(X3::_1)), 0);
+ assert_eq!(match_e(E::A(X3::_2)), 0);
+ assert_eq!(match_e(E::A(X3::_254)), 0);
+ assert_eq!(match_e(E::<X3>::B), 1);
+ assert_eq!(match_e(E::<X3>::C), 2);
+ assert_eq!(match_e(E::A(X4::_1)), 0);
+ assert_eq!(match_e(E::A(X4::_2)), 0);
+ assert_eq!(match_e(E::A(X4::_254)), 0);
+ assert_eq!(match_e(E::<X4>::B), 1);
+ assert_eq!(match_e(E::<X4>::C), 2);
+ assert_eq!(match_e(E::A(false)), 0);
+ assert_eq!(match_e(E::A(true)), 0);
+ assert_eq!(match_e(E::<bool>::B), 1);
+ assert_eq!(match_e(E::<bool>::C), 2);
+}
diff --git a/src/test/ui/enum-discriminant/issue-104519.rs b/src/test/ui/enum-discriminant/issue-104519.rs
new file mode 100644
index 000000000..c4630f76b
--- /dev/null
+++ b/src/test/ui/enum-discriminant/issue-104519.rs
@@ -0,0 +1,36 @@
+// run-pass
+#![allow(dead_code)]
+
+enum OpenResult {
+ Ok(()),
+ Err(()),
+ TransportErr(TransportErr),
+}
+
+#[repr(i32)]
+enum TransportErr {
+ UnknownMethod = -2,
+}
+
+#[inline(never)]
+fn some_match(result: OpenResult) -> u8 {
+ match result {
+ OpenResult::Ok(()) => 0,
+ _ => 1,
+ }
+}
+
+fn main() {
+ let result = OpenResult::Ok(());
+ assert_eq!(some_match(result), 0);
+
+ let result = OpenResult::Ok(());
+ match result {
+ OpenResult::Ok(()) => (),
+ _ => unreachable!("message a"),
+ }
+ match result {
+ OpenResult::Ok(()) => (),
+ _ => unreachable!("message b"),
+ }
+}
diff --git a/src/test/ui/issues/issue-46519.rs b/src/test/ui/enum-discriminant/issue-46519.rs
index 0567923b7..0567923b7 100644
--- a/src/test/ui/issues/issue-46519.rs
+++ b/src/test/ui/enum-discriminant/issue-46519.rs
diff --git a/src/test/ui/enum/issue-67945-2.rs b/src/test/ui/enum/issue-67945-2.rs
index e5044468d..2eb123b73 100644
--- a/src/test/ui/enum/issue-67945-2.rs
+++ b/src/test/ui/enum/issue-67945-2.rs
@@ -1,7 +1,7 @@
#![feature(type_ascription)]
enum Bug<S> { //~ ERROR parameter `S` is never used
- Var = 0: S,
+ Var = type_ascribe!(0, S),
//~^ ERROR generic parameters may not be used
}
diff --git a/src/test/ui/enum/issue-67945-2.stderr b/src/test/ui/enum/issue-67945-2.stderr
index 4f5e236a3..63d3521af 100644
--- a/src/test/ui/enum/issue-67945-2.stderr
+++ b/src/test/ui/enum/issue-67945-2.stderr
@@ -1,8 +1,8 @@
error: generic parameters may not be used in const operations
- --> $DIR/issue-67945-2.rs:4:14
+ --> $DIR/issue-67945-2.rs:4:28
|
-LL | Var = 0: S,
- | ^ cannot perform const operation using `S`
+LL | Var = type_ascribe!(0, S),
+ | ^ cannot perform const operation using `S`
|
= note: type parameters may not be used in const expressions
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
diff --git a/src/test/ui/error-codes/E0045.stderr b/src/test/ui/error-codes/E0045.stderr
index d163128bc..fcc613b11 100644
--- a/src/test/ui/error-codes/E0045.stderr
+++ b/src/test/ui/error-codes/E0045.stderr
@@ -1,8 +1,8 @@
-error[E0045]: C-variadic function must have C or cdecl calling convention
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
--> $DIR/E0045.rs:1:17
|
LL | extern "Rust" { fn foo(x: u8, ...); }
- | ^^^^^^^^^^^^^^^^^^^ C-variadics require C or cdecl calling convention
+ | ^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0059.stderr b/src/test/ui/error-codes/E0059.stderr
index a1b8aeaed..f331d0142 100644
--- a/src/test/ui/error-codes/E0059.stderr
+++ b/src/test/ui/error-codes/E0059.stderr
@@ -1,8 +1,14 @@
-error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit
- --> $DIR/E0059.rs:3:41
+error[E0059]: type parameter to bare `Fn` trait must be a tuple
+ --> $DIR/E0059.rs:3:11
|
LL | fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) }
- | ^^^^
+ | ^^^^^^^ the trait `Tuple` is not implemented for `i32`
+ |
+note: required by a bound in `Fn`
+ --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+ |
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | ^^^^^ required by this bound in `Fn`
error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0081.stderr b/src/test/ui/error-codes/E0081.stderr
index 64562fefc..d4b21f689 100644
--- a/src/test/ui/error-codes/E0081.stderr
+++ b/src/test/ui/error-codes/E0081.stderr
@@ -32,7 +32,7 @@ LL | First = -1,
| -- `-1` assigned here
LL |
LL | Second = -2,
- | ----------- discriminant for `Last` incremented from this startpoint (`Second` + 1 variant later => `Last` = -1)
+ | ------ discriminant for `Last` incremented from this startpoint (`Second` + 1 variant later => `Last` = -1)
LL |
LL | Last,
| ---- `-1` assigned here
@@ -53,7 +53,7 @@ LL | V4 = 0,
| - `0` assigned here
LL |
LL | V5 = -2,
- | ------- discriminant for `V7` incremented from this startpoint (`V5` + 2 variants later => `V7` = 0)
+ | -- discriminant for `V7` incremented from this startpoint (`V5` + 2 variants later => `V7` = 0)
...
LL | V7,
| -- `0` assigned here
@@ -68,7 +68,7 @@ LL | V5 = -2,
| -- `-2` assigned here
...
LL | V8 = -3,
- | ------- discriminant for `V9` incremented from this startpoint (`V8` + 1 variant later => `V9` = -2)
+ | -- discriminant for `V9` incremented from this startpoint (`V8` + 1 variant later => `V9` = -2)
LL |
LL | V9,
| -- `-2` assigned here
diff --git a/src/test/ui/error-codes/E0164.stderr b/src/test/ui/error-codes/E0164.stderr
index 0db89dfec..5a80d6ec3 100644
--- a/src/test/ui/error-codes/E0164.stderr
+++ b/src/test/ui/error-codes/E0164.stderr
@@ -2,7 +2,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated constant
--> $DIR/E0164.rs:9:9
|
LL | Foo::B(i) => i,
- | ^^^^^^^^^ not a tuple variant or struct
+ | ^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0268.stderr b/src/test/ui/error-codes/E0268.stderr
index c926f9e48..6422e8a94 100644
--- a/src/test/ui/error-codes/E0268.stderr
+++ b/src/test/ui/error-codes/E0268.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/E0268.rs:2:5
|
LL | break;
- | ^^^^^ cannot `break` outside of a loop
+ | ^^^^^ cannot `break` outside of a loop or labeled block
error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0275.rs b/src/test/ui/error-codes/E0275.rs
index 28a9676f0..95d7f85f1 100644
--- a/src/test/ui/error-codes/E0275.rs
+++ b/src/test/ui/error-codes/E0275.rs
@@ -1,3 +1,4 @@
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
trait Foo {}
struct Bar<T>(T);
diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr
index 87cfaa489..451a683ac 100644
--- a/src/test/ui/error-codes/E0275.stderr
+++ b/src/test/ui/error-codes/E0275.stderr
@@ -1,15 +1,16 @@
-error[E0275]: overflow evaluating the requirement `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
- --> $DIR/E0275.rs:5:33
+error[E0275]: overflow evaluating the requirement `Bar<Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>>: Foo`
+ --> $DIR/E0275.rs:6:33
|
LL | impl<T> Foo for T where Bar<T>: Foo {}
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`)
-note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
- --> $DIR/E0275.rs:5:9
+note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
+ --> $DIR/E0275.rs:6:9
|
LL | impl<T> Foo for T where Bar<T>: Foo {}
| ^^^ ^
+ = note: the full type name has been written to '$TEST_BUILD_DIR/error-codes/E0275/E0275.long-type-hash.txt'
= note: 127 redundant requirements hidden
= note: required for `Bar<T>` to implement `Foo`
diff --git a/src/test/ui/error-codes/E0282.rs b/src/test/ui/error-codes/E0282.rs
index 9bd16abb7..f1f93b3ae 100644
--- a/src/test/ui/error-codes/E0282.rs
+++ b/src/test/ui/error-codes/E0282.rs
@@ -1,3 +1,4 @@
fn main() {
- let x = "hello".chars().rev().collect(); //~ ERROR E0282
+ let x = "hello".chars().rev().collect();
+ //~^ ERROR E0282
}
diff --git a/src/test/ui/error-codes/E0401.rs b/src/test/ui/error-codes/E0401.rs
index c30e5f471..8f8d6b87e 100644
--- a/src/test/ui/error-codes/E0401.rs
+++ b/src/test/ui/error-codes/E0401.rs
@@ -8,7 +8,9 @@ fn foo<T>(x: T) {
W: Fn()>
(y: T) { //~ ERROR E0401
}
- bfnr(x); //~ ERROR type annotations needed
+ bfnr(x);
+ //~^ ERROR type annotations needed
+ //~| ERROR type annotations needed
}
diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr
index b0e2ef5b6..9687eca61 100644
--- a/src/test/ui/error-codes/E0401.stderr
+++ b/src/test/ui/error-codes/E0401.stderr
@@ -21,7 +21,7 @@ LL | (y: T) {
| ^ use of generic parameter from outer function
error[E0401]: can't use generic parameters from outer function
- --> $DIR/E0401.rs:22:25
+ --> $DIR/E0401.rs:24:25
|
LL | impl<T> Iterator for A<T> {
| ---- `Self` type implicitly declared here, by this `impl`
@@ -43,7 +43,28 @@ help: consider specifying the generic arguments
LL | bfnr::<U, V, W>(x);
| +++++++++++
-error: aborting due to 4 previous errors
+error[E0283]: type annotations needed
+ --> $DIR/E0401.rs:11:5
+ |
+LL | bfnr(x);
+ | ^^^^ cannot infer type of the type parameter `W` declared on the function `bfnr`
+ |
+ = note: multiple `impl`s satisfying `_: Fn<()>` found in the following crates: `alloc`, `core`:
+ - impl<A, F> Fn<A> for &F
+ where A: Tuple, F: Fn<A>, F: ?Sized;
+ - impl<Args, F, A> Fn<Args> for Box<F, A>
+ where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
+note: required by a bound in `bfnr`
+ --> $DIR/E0401.rs:4:30
+ |
+LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) {
+ | ^^^^ required by this bound in `bfnr`
+help: consider specifying the type arguments in the function call
+ |
+LL | bfnr::<U, V, W>(x);
+ | +++++++++++
+
+error: aborting due to 5 previous errors
-Some errors have detailed explanations: E0282, E0401.
+Some errors have detailed explanations: E0282, E0283, E0401.
For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/error-codes/E0767.rs b/src/test/ui/error-codes/E0767.rs
index 6c6cb746e..14215d36a 100644
--- a/src/test/ui/error-codes/E0767.rs
+++ b/src/test/ui/error-codes/E0767.rs
@@ -1,6 +1,7 @@
-fn main () {
+fn main() {
'a: loop {
|| {
+ //~^ ERROR mismatched types
loop { break 'a; } //~ ERROR E0767
}
}
diff --git a/src/test/ui/error-codes/E0767.stderr b/src/test/ui/error-codes/E0767.stderr
index 242982330..ee8524730 100644
--- a/src/test/ui/error-codes/E0767.stderr
+++ b/src/test/ui/error-codes/E0767.stderr
@@ -1,14 +1,27 @@
error[E0767]: use of unreachable label `'a`
- --> $DIR/E0767.rs:4:26
+ --> $DIR/E0767.rs:5:26
|
LL | 'a: loop {
| -- unreachable label defined here
-LL | || {
+...
LL | loop { break 'a; }
| ^^ unreachable label `'a`
|
= note: labels are unreachable through functions, closures, async blocks and modules
-error: aborting due to previous error
+error[E0308]: mismatched types
+ --> $DIR/E0767.rs:3:9
+ |
+LL | / || {
+LL | |
+LL | | loop { break 'a; }
+LL | | }
+ | |_________^ expected `()`, found closure
+ |
+ = note: expected unit type `()`
+ found closure `[closure@$DIR/E0767.rs:3:9: 3:11]`
+
+error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0767`.
+Some errors have detailed explanations: E0308, E0767.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/error-codes/E0778.rs b/src/test/ui/error-codes/E0778.rs
index 60e5c2598..74653886d 100644
--- a/src/test/ui/error-codes/E0778.rs
+++ b/src/test/ui/error-codes/E0778.rs
@@ -1,8 +1,4 @@
-#![feature(isa_attribute)]
-
#[instruction_set()] //~ ERROR
-fn no_isa_defined() {
-}
+fn no_isa_defined() {}
-fn main() {
-}
+fn main() {}
diff --git a/src/test/ui/error-codes/E0778.stderr b/src/test/ui/error-codes/E0778.stderr
index 6ecae7924..42647e5c6 100644
--- a/src/test/ui/error-codes/E0778.stderr
+++ b/src/test/ui/error-codes/E0778.stderr
@@ -1,5 +1,5 @@
error[E0778]: `#[instruction_set]` requires an argument
- --> $DIR/E0778.rs:3:1
+ --> $DIR/E0778.rs:1:1
|
LL | #[instruction_set()]
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/error-codes/E0779.rs b/src/test/ui/error-codes/E0779.rs
index 1b4dbce20..c32dae12c 100644
--- a/src/test/ui/error-codes/E0779.rs
+++ b/src/test/ui/error-codes/E0779.rs
@@ -1,6 +1,2 @@
-#![feature(isa_attribute)]
-
#[instruction_set(arm::magic)] //~ ERROR
-fn main() {
-
-}
+fn main() {}
diff --git a/src/test/ui/error-codes/E0779.stderr b/src/test/ui/error-codes/E0779.stderr
index da787260d..7c6a119a0 100644
--- a/src/test/ui/error-codes/E0779.stderr
+++ b/src/test/ui/error-codes/E0779.stderr
@@ -1,5 +1,5 @@
error[E0779]: invalid instruction set specified
- --> $DIR/E0779.rs:3:1
+ --> $DIR/E0779.rs:1:1
|
LL | #[instruction_set(arm::magic)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/error-codes/e0119/conflict-with-std.stderr b/src/test/ui/error-codes/e0119/conflict-with-std.stderr
index 3ff96a6a4..ef888a1c2 100644
--- a/src/test/ui/error-codes/e0119/conflict-with-std.stderr
+++ b/src/test/ui/error-codes/e0119/conflict-with-std.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::convert::AsRef<Q>` for type `std::boxed::Box<Q>`
+error[E0119]: conflicting implementations of trait `AsRef<Q>` for type `Box<Q>`
--> $DIR/conflict-with-std.rs:5:1
|
LL | impl AsRef<Q> for Box<Q> {
@@ -8,7 +8,7 @@ LL | impl AsRef<Q> for Box<Q> {
- impl<T, A> AsRef<T> for Box<T, A>
where A: Allocator, T: ?Sized;
-error[E0119]: conflicting implementations of trait `std::convert::From<S>` for type `S`
+error[E0119]: conflicting implementations of trait `From<S>` for type `S`
--> $DIR/conflict-with-std.rs:12:1
|
LL | impl From<S> for S {
@@ -17,7 +17,7 @@ LL | impl From<S> for S {
= note: conflicting implementation in crate `core`:
- impl<T> From<T> for T;
-error[E0119]: conflicting implementations of trait `std::convert::TryFrom<X>` for type `X`
+error[E0119]: conflicting implementations of trait `TryFrom<X>` for type `X`
--> $DIR/conflict-with-std.rs:19:1
|
LL | impl TryFrom<X> for X {
diff --git a/src/test/ui/error-codes/e0119/issue-23563.stderr b/src/test/ui/error-codes/e0119/issue-23563.stderr
index f149cef58..1b2d64282 100644
--- a/src/test/ui/error-codes/e0119/issue-23563.stderr
+++ b/src/test/ui/error-codes/e0119/issue-23563.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `a::LolFrom<&[_]>` for type `LocalType<_>`
+error[E0119]: conflicting implementations of trait `LolFrom<&[_]>` for type `LocalType<_>`
--> $DIR/issue-23563.rs:13:1
|
LL | impl<'a, T> LolFrom<&'a [T]> for LocalType<T> {
diff --git a/src/test/ui/error-codes/e0119/issue-27403.stderr b/src/test/ui/error-codes/e0119/issue-27403.stderr
index c11a50487..9b3345c23 100644
--- a/src/test/ui/error-codes/e0119/issue-27403.stderr
+++ b/src/test/ui/error-codes/e0119/issue-27403.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::convert::Into<_>` for type `GenX<_>`
+error[E0119]: conflicting implementations of trait `Into<_>` for type `GenX<_>`
--> $DIR/issue-27403.rs:5:1
|
LL | impl<S> Into<S> for GenX<S> {
diff --git a/src/test/ui/error-codes/e0119/so-37347311.stderr b/src/test/ui/error-codes/e0119/so-37347311.stderr
index f1c2b0d29..99367e808 100644
--- a/src/test/ui/error-codes/e0119/so-37347311.stderr
+++ b/src/test/ui/error-codes/e0119/so-37347311.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::convert::From<MyError<_>>` for type `MyError<_>`
+error[E0119]: conflicting implementations of trait `From<MyError<_>>` for type `MyError<_>`
--> $DIR/so-37347311.rs:11:1
|
LL | impl<S: Storage> From<S::Error> for MyError<S> {
diff --git a/src/test/ui/errors/issue-104621-extern-bad-file.rs b/src/test/ui/errors/issue-104621-extern-bad-file.rs
new file mode 100644
index 000000000..3f13d6052
--- /dev/null
+++ b/src/test/ui/errors/issue-104621-extern-bad-file.rs
@@ -0,0 +1,8 @@
+// compile-flags: --extern foo={{src-base}}/errors/issue-104621-extern-bad-file.rs
+// only-linux
+
+extern crate foo;
+//~^ ERROR extern location for foo is of an unknown type
+//~| ERROR file name should be lib*.rlib or lib*.so
+//~| ERROR can't find crate for `foo` [E0463]
+fn main() {}
diff --git a/src/test/ui/errors/issue-104621-extern-bad-file.stderr b/src/test/ui/errors/issue-104621-extern-bad-file.stderr
new file mode 100644
index 000000000..b8500ad0e
--- /dev/null
+++ b/src/test/ui/errors/issue-104621-extern-bad-file.stderr
@@ -0,0 +1,21 @@
+error: extern location for foo is of an unknown type: $DIR/issue-104621-extern-bad-file.rs
+ --> $DIR/issue-104621-extern-bad-file.rs:4:1
+ |
+LL | extern crate foo;
+ | ^^^^^^^^^^^^^^^^^
+
+error: file name should be lib*.rlib or lib*.so
+ --> $DIR/issue-104621-extern-bad-file.rs:4:1
+ |
+LL | extern crate foo;
+ | ^^^^^^^^^^^^^^^^^
+
+error[E0463]: can't find crate for `foo`
+ --> $DIR/issue-104621-extern-bad-file.rs:4:1
+ |
+LL | extern crate foo;
+ | ^^^^^^^^^^^^^^^^^ can't find crate
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0463`.
diff --git a/src/test/ui/errors/issue-104621-extern-not-file.rs b/src/test/ui/errors/issue-104621-extern-not-file.rs
new file mode 100644
index 000000000..899e45a30
--- /dev/null
+++ b/src/test/ui/errors/issue-104621-extern-not-file.rs
@@ -0,0 +1,4 @@
+// compile-flags: --extern foo=.
+
+extern crate foo; //~ ERROR extern location for foo is not a file: .
+fn main() {}
diff --git a/src/test/ui/errors/issue-104621-extern-not-file.stderr b/src/test/ui/errors/issue-104621-extern-not-file.stderr
new file mode 100644
index 000000000..5aaf97413
--- /dev/null
+++ b/src/test/ui/errors/issue-104621-extern-not-file.stderr
@@ -0,0 +1,8 @@
+error: extern location for foo is not a file: .
+ --> $DIR/issue-104621-extern-not-file.rs:3:1
+ |
+LL | extern crate foo;
+ | ^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/fail-simple.stderr b/src/test/ui/fail-simple.stderr
index 26ed918e9..af8f54291 100644
--- a/src/test/ui/fail-simple.stderr
+++ b/src/test/ui/fail-simple.stderr
@@ -3,6 +3,8 @@ error: no rules expected the token `@`
|
LL | panic!(@);
| ^ no rules expected this token in macro call
+ |
+ = note: while trying to match end of macro
error: aborting due to previous error
diff --git a/src/test/ui/feature-gates/feature-gate-abi-efiapi.rs b/src/test/ui/feature-gates/feature-gate-abi-efiapi.rs
new file mode 100644
index 000000000..0c0d736ac
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-abi-efiapi.rs
@@ -0,0 +1,33 @@
+// needs-llvm-components: x86
+// compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
+
+// Functions
+extern "efiapi" fn f1() {} //~ ERROR efiapi ABI is experimental
+
+// Methods in trait defintion
+trait Tr {
+ extern "efiapi" fn f2(); //~ ERROR efiapi ABI is experimental
+ extern "efiapi" fn f3() {} //~ ERROR efiapi ABI is experimental
+}
+
+struct S;
+
+// Methods in trait impl
+impl Tr for S {
+ extern "efiapi" fn f2() {} //~ ERROR efiapi ABI is experimental
+}
+
+// Methods in inherent impl
+impl S {
+ extern "efiapi" fn f4() {} //~ ERROR efiapi ABI is experimental
+}
+
+// Function pointer types
+type A = extern "efiapi" fn(); //~ ERROR efiapi ABI is experimental
+
+// Foreign modules
+extern "efiapi" {} //~ ERROR efiapi ABI is experimental
diff --git a/src/test/ui/feature-gates/feature-gate-abi-efiapi.stderr b/src/test/ui/feature-gates/feature-gate-abi-efiapi.stderr
new file mode 100644
index 000000000..5b01dcc6d
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-abi-efiapi.stderr
@@ -0,0 +1,66 @@
+error[E0658]: efiapi ABI is experimental and subject to change
+ --> $DIR/feature-gate-abi-efiapi.rs:9:8
+ |
+LL | extern "efiapi" fn f1() {}
+ | ^^^^^^^^
+ |
+ = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
+ = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
+
+error[E0658]: efiapi ABI is experimental and subject to change
+ --> $DIR/feature-gate-abi-efiapi.rs:13:12
+ |
+LL | extern "efiapi" fn f2();
+ | ^^^^^^^^
+ |
+ = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
+ = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
+
+error[E0658]: efiapi ABI is experimental and subject to change
+ --> $DIR/feature-gate-abi-efiapi.rs:14:12
+ |
+LL | extern "efiapi" fn f3() {}
+ | ^^^^^^^^
+ |
+ = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
+ = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
+
+error[E0658]: efiapi ABI is experimental and subject to change
+ --> $DIR/feature-gate-abi-efiapi.rs:21:12
+ |
+LL | extern "efiapi" fn f2() {}
+ | ^^^^^^^^
+ |
+ = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
+ = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
+
+error[E0658]: efiapi ABI is experimental and subject to change
+ --> $DIR/feature-gate-abi-efiapi.rs:26:12
+ |
+LL | extern "efiapi" fn f4() {}
+ | ^^^^^^^^
+ |
+ = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
+ = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
+
+error[E0658]: efiapi ABI is experimental and subject to change
+ --> $DIR/feature-gate-abi-efiapi.rs:30:17
+ |
+LL | type A = extern "efiapi" fn();
+ | ^^^^^^^^
+ |
+ = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
+ = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
+
+error[E0658]: efiapi ABI is experimental and subject to change
+ --> $DIR/feature-gate-abi-efiapi.rs:33:8
+ |
+LL | extern "efiapi" {}
+ | ^^^^^^^^
+ |
+ = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
+ = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-abi.rs b/src/test/ui/feature-gates/feature-gate-abi.rs
index 855263595..712655f97 100644
--- a/src/test/ui/feature-gates/feature-gate-abi.rs
+++ b/src/test/ui/feature-gates/feature-gate-abi.rs
@@ -1,6 +1,5 @@
// gate-test-intrinsics
// gate-test-platform_intrinsics
-// gate-test-abi_efiapi
// compile-flags: --crate-type=rlib
#![feature(no_core, lang_items)]
@@ -9,13 +8,15 @@
#[lang="sized"]
trait Sized { }
+#[lang="tuple_trait"]
+trait Tuple { }
+
// Functions
extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change
//~^ ERROR intrinsic must be in
extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental
//~^ ERROR intrinsic must be in
extern "rust-call" fn f4(_: ()) {} //~ ERROR rust-call ABI is subject to change
-extern "efiapi" fn f10() {} //~ ERROR efiapi ABI is experimental and subject to change
// Methods in trait definition
trait Tr {
@@ -24,10 +25,8 @@ trait Tr {
extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental
//~^ ERROR intrinsic must be in
extern "rust-call" fn m4(_: ()); //~ ERROR rust-call ABI is subject to change
- extern "efiapi" fn m10(); //~ ERROR efiapi ABI is experimental and subject to change
extern "rust-call" fn dm4(_: ()) {} //~ ERROR rust-call ABI is subject to change
- extern "efiapi" fn dm10() {} //~ ERROR efiapi ABI is experimental and subject to change
}
struct S;
@@ -39,7 +38,6 @@ impl Tr for S {
extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental
//~^ ERROR intrinsic must be in
extern "rust-call" fn m4(_: ()) {} //~ ERROR rust-call ABI is subject to change
- extern "efiapi" fn m10() {} //~ ERROR efiapi ABI is experimental and subject to change
}
// Methods in inherent impl
@@ -49,17 +47,14 @@ impl S {
extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental
//~^ ERROR intrinsic must be in
extern "rust-call" fn im4(_: ()) {} //~ ERROR rust-call ABI is subject to change
- extern "efiapi" fn im10() {} //~ ERROR efiapi ABI is experimental and subject to change
}
// Function pointer types
type A1 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to change
type A2 = extern "platform-intrinsic" fn(); //~ ERROR platform intrinsics are experimental
type A4 = extern "rust-call" fn(_: ()); //~ ERROR rust-call ABI is subject to change
-type A10 = extern "efiapi" fn(); //~ ERROR efiapi ABI is experimental and subject to change
// Foreign modules
extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
extern "platform-intrinsic" {} //~ ERROR platform intrinsics are experimental
extern "rust-call" {} //~ ERROR rust-call ABI is subject to change
-extern "efiapi" {} //~ ERROR efiapi ABI is experimental and subject to change
diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr
index bcca39c8f..e9791b951 100644
--- a/src/test/ui/feature-gates/feature-gate-abi.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi.stderr
@@ -1,5 +1,5 @@
error[E0658]: intrinsics are subject to change
- --> $DIR/feature-gate-abi.rs:13:8
+ --> $DIR/feature-gate-abi.rs:15:8
|
LL | extern "rust-intrinsic" fn f1() {}
| ^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | extern "rust-intrinsic" fn f1() {}
= help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy
- --> $DIR/feature-gate-abi.rs:15:8
+ --> $DIR/feature-gate-abi.rs:17:8
|
LL | extern "platform-intrinsic" fn f2() {}
| ^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL | extern "platform-intrinsic" fn f2() {}
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change
- --> $DIR/feature-gate-abi.rs:17:8
+ --> $DIR/feature-gate-abi.rs:19:8
|
LL | extern "rust-call" fn f4(_: ()) {}
| ^^^^^^^^^^^
@@ -24,17 +24,8 @@ LL | extern "rust-call" fn f4(_: ()) {}
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-error[E0658]: efiapi ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:18:8
- |
-LL | extern "efiapi" fn f10() {}
- | ^^^^^^^^
- |
- = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
- = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
-
error[E0658]: intrinsics are subject to change
- --> $DIR/feature-gate-abi.rs:22:12
+ --> $DIR/feature-gate-abi.rs:23:12
|
LL | extern "rust-intrinsic" fn m1();
| ^^^^^^^^^^^^^^^^
@@ -42,7 +33,7 @@ LL | extern "rust-intrinsic" fn m1();
= help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy
- --> $DIR/feature-gate-abi.rs:24:12
+ --> $DIR/feature-gate-abi.rs:25:12
|
LL | extern "platform-intrinsic" fn m2();
| ^^^^^^^^^^^^^^^^^^^^
@@ -51,7 +42,7 @@ LL | extern "platform-intrinsic" fn m2();
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change
- --> $DIR/feature-gate-abi.rs:26:12
+ --> $DIR/feature-gate-abi.rs:27:12
|
LL | extern "rust-call" fn m4(_: ());
| ^^^^^^^^^^^
@@ -59,15 +50,6 @@ LL | extern "rust-call" fn m4(_: ());
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-error[E0658]: efiapi ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:27:12
- |
-LL | extern "efiapi" fn m10();
- | ^^^^^^^^
- |
- = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
- = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
-
error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:29:12
|
@@ -77,17 +59,8 @@ LL | extern "rust-call" fn dm4(_: ()) {}
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-error[E0658]: efiapi ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:30:12
- |
-LL | extern "efiapi" fn dm10() {}
- | ^^^^^^^^
- |
- = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
- = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
-
error[E0658]: intrinsics are subject to change
- --> $DIR/feature-gate-abi.rs:37:12
+ --> $DIR/feature-gate-abi.rs:36:12
|
LL | extern "rust-intrinsic" fn m1() {}
| ^^^^^^^^^^^^^^^^
@@ -95,7 +68,7 @@ LL | extern "rust-intrinsic" fn m1() {}
= help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy
- --> $DIR/feature-gate-abi.rs:39:12
+ --> $DIR/feature-gate-abi.rs:38:12
|
LL | extern "platform-intrinsic" fn m2() {}
| ^^^^^^^^^^^^^^^^^^^^
@@ -104,7 +77,7 @@ LL | extern "platform-intrinsic" fn m2() {}
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change
- --> $DIR/feature-gate-abi.rs:41:12
+ --> $DIR/feature-gate-abi.rs:40:12
|
LL | extern "rust-call" fn m4(_: ()) {}
| ^^^^^^^^^^^
@@ -112,17 +85,8 @@ LL | extern "rust-call" fn m4(_: ()) {}
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-error[E0658]: efiapi ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:42:12
- |
-LL | extern "efiapi" fn m10() {}
- | ^^^^^^^^
- |
- = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
- = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
-
error[E0658]: intrinsics are subject to change
- --> $DIR/feature-gate-abi.rs:47:12
+ --> $DIR/feature-gate-abi.rs:45:12
|
LL | extern "rust-intrinsic" fn im1() {}
| ^^^^^^^^^^^^^^^^
@@ -130,7 +94,7 @@ LL | extern "rust-intrinsic" fn im1() {}
= help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy
- --> $DIR/feature-gate-abi.rs:49:12
+ --> $DIR/feature-gate-abi.rs:47:12
|
LL | extern "platform-intrinsic" fn im2() {}
| ^^^^^^^^^^^^^^^^^^^^
@@ -139,7 +103,7 @@ LL | extern "platform-intrinsic" fn im2() {}
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change
- --> $DIR/feature-gate-abi.rs:51:12
+ --> $DIR/feature-gate-abi.rs:49:12
|
LL | extern "rust-call" fn im4(_: ()) {}
| ^^^^^^^^^^^
@@ -147,17 +111,8 @@ LL | extern "rust-call" fn im4(_: ()) {}
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-error[E0658]: efiapi ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:52:12
- |
-LL | extern "efiapi" fn im10() {}
- | ^^^^^^^^
- |
- = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
- = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
-
error[E0658]: intrinsics are subject to change
- --> $DIR/feature-gate-abi.rs:56:18
+ --> $DIR/feature-gate-abi.rs:53:18
|
LL | type A1 = extern "rust-intrinsic" fn();
| ^^^^^^^^^^^^^^^^
@@ -165,7 +120,7 @@ LL | type A1 = extern "rust-intrinsic" fn();
= help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy
- --> $DIR/feature-gate-abi.rs:57:18
+ --> $DIR/feature-gate-abi.rs:54:18
|
LL | type A2 = extern "platform-intrinsic" fn();
| ^^^^^^^^^^^^^^^^^^^^
@@ -174,7 +129,7 @@ LL | type A2 = extern "platform-intrinsic" fn();
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change
- --> $DIR/feature-gate-abi.rs:58:18
+ --> $DIR/feature-gate-abi.rs:55:18
|
LL | type A4 = extern "rust-call" fn(_: ());
| ^^^^^^^^^^^
@@ -182,17 +137,8 @@ LL | type A4 = extern "rust-call" fn(_: ());
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-error[E0658]: efiapi ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:59:19
- |
-LL | type A10 = extern "efiapi" fn();
- | ^^^^^^^^
- |
- = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
- = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
-
error[E0658]: intrinsics are subject to change
- --> $DIR/feature-gate-abi.rs:62:8
+ --> $DIR/feature-gate-abi.rs:58:8
|
LL | extern "rust-intrinsic" {}
| ^^^^^^^^^^^^^^^^
@@ -200,7 +146,7 @@ LL | extern "rust-intrinsic" {}
= help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy
- --> $DIR/feature-gate-abi.rs:63:8
+ --> $DIR/feature-gate-abi.rs:59:8
|
LL | extern "platform-intrinsic" {}
| ^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +155,7 @@ LL | extern "platform-intrinsic" {}
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change
- --> $DIR/feature-gate-abi.rs:64:8
+ --> $DIR/feature-gate-abi.rs:60:8
|
LL | extern "rust-call" {}
| ^^^^^^^^^^^
@@ -217,63 +163,54 @@ LL | extern "rust-call" {}
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
-error[E0658]: efiapi ABI is experimental and subject to change
- --> $DIR/feature-gate-abi.rs:65:8
- |
-LL | extern "efiapi" {}
- | ^^^^^^^^
- |
- = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
- = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
-
error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:22:32
+ --> $DIR/feature-gate-abi.rs:23:32
|
LL | extern "rust-intrinsic" fn m1();
| ^^
error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:24:36
+ --> $DIR/feature-gate-abi.rs:25:36
|
LL | extern "platform-intrinsic" fn m2();
| ^^
error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:13:33
+ --> $DIR/feature-gate-abi.rs:15:33
|
LL | extern "rust-intrinsic" fn f1() {}
| ^^
error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:15:37
+ --> $DIR/feature-gate-abi.rs:17:37
|
LL | extern "platform-intrinsic" fn f2() {}
| ^^
error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:37:37
+ --> $DIR/feature-gate-abi.rs:36:37
|
LL | extern "rust-intrinsic" fn m1() {}
| ^^
error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:39:41
+ --> $DIR/feature-gate-abi.rs:38:41
|
LL | extern "platform-intrinsic" fn m2() {}
| ^^
error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:47:38
+ --> $DIR/feature-gate-abi.rs:45:38
|
LL | extern "rust-intrinsic" fn im1() {}
| ^^
error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
- --> $DIR/feature-gate-abi.rs:49:42
+ --> $DIR/feature-gate-abi.rs:47:42
|
LL | extern "platform-intrinsic" fn im2() {}
| ^^
-error: aborting due to 34 previous errors
+error: aborting due to 27 previous errors
For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs
index ad8909618..78d189d20 100644
--- a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs
+++ b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs
@@ -5,10 +5,12 @@
use core::alloc::Layout;
-#[alloc_error_handler] //~ ERROR the `#[alloc_error_handler]` attribute is an experimental feature
+#[alloc_error_handler] //~ ERROR use of unstable library feature 'alloc_error_handler'
fn oom(info: Layout) -> ! {
loop {}
}
#[panic_handler]
-fn panic(_: &core::panic::PanicInfo) -> ! { loop {} }
+fn panic(_: &core::panic::PanicInfo) -> ! {
+ loop {}
+}
diff --git a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr
index 03f31e53f..f414eb463 100644
--- a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr
+++ b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr
@@ -1,8 +1,8 @@
-error[E0658]: the `#[alloc_error_handler]` attribute is an experimental feature
- --> $DIR/feature-gate-alloc-error-handler.rs:8:1
+error[E0658]: use of unstable library feature 'alloc_error_handler'
+ --> $DIR/feature-gate-alloc-error-handler.rs:8:3
|
LL | #[alloc_error_handler]
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #51540 <https://github.com/rust-lang/rust/issues/51540> for more information
= help: add `#![feature(alloc_error_handler)]` to the crate attributes to enable
diff --git a/src/test/ui/feature-gates/feature-gate-custom_mir.rs b/src/test/ui/feature-gates/feature-gate-custom_mir.rs
new file mode 100644
index 000000000..0126dde2f
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-custom_mir.rs
@@ -0,0 +1,12 @@
+#![feature(core_intrinsics)]
+
+extern crate core;
+
+#[custom_mir(dialect = "built")] //~ ERROR the `#[custom_mir]` attribute is just used for the Rust test suite
+pub fn foo(_x: i32) -> i32 {
+ 0
+}
+
+fn main() {
+ assert_eq!(2, foo(2));
+}
diff --git a/src/test/ui/feature-gates/feature-gate-custom_mir.stderr b/src/test/ui/feature-gates/feature-gate-custom_mir.stderr
new file mode 100644
index 000000000..3c149d30d
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-custom_mir.stderr
@@ -0,0 +1,11 @@
+error[E0658]: the `#[custom_mir]` attribute is just used for the Rust test suite
+ --> $DIR/feature-gate-custom_mir.rs:5:1
+ |
+LL | #[custom_mir(dialect = "built")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(custom_mir)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs b/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs
new file mode 100644
index 000000000..0db8088f7
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.rs
@@ -0,0 +1,6 @@
+fn f() -> impl Fn() -> impl Sized { || () }
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
+//~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr b/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr
new file mode 100644
index 000000000..760dcb615
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr
@@ -0,0 +1,21 @@
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+ --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:1:24
+ |
+LL | fn f() -> impl Fn() -> impl Sized { || () }
+ | ^^^^^^^^^^
+ |
+ = note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information
+ = help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable
+
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
+ --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32
+ |
+LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
+ | ^^^^^^^^^^
+ |
+ = note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information
+ = help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/feature-gates/feature-gate-isa_attribute.rs b/src/test/ui/feature-gates/feature-gate-isa_attribute.rs
deleted file mode 100644
index cb02a0955..000000000
--- a/src/test/ui/feature-gates/feature-gate-isa_attribute.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#[instruction_set]
-//~^ ERROR the `#[instruction_set]` attribute is an experimental feature [E0658]
-//~| ERROR malformed `instruction_set` attribute input
-//~| ERROR must specify an instruction set [E0778]
-fn main() {
-}
diff --git a/src/test/ui/feature-gates/feature-gate-isa_attribute.stderr b/src/test/ui/feature-gates/feature-gate-isa_attribute.stderr
deleted file mode 100644
index 2a95a80ca..000000000
--- a/src/test/ui/feature-gates/feature-gate-isa_attribute.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error: malformed `instruction_set` attribute input
- --> $DIR/feature-gate-isa_attribute.rs:1:1
- |
-LL | #[instruction_set]
- | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]`
-
-error[E0658]: the `#[instruction_set]` attribute is an experimental feature
- --> $DIR/feature-gate-isa_attribute.rs:1:1
- |
-LL | #[instruction_set]
- | ^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #74727 <https://github.com/rust-lang/rust/issues/74727> for more information
- = help: add `#![feature(isa_attribute)]` to the crate attributes to enable
-
-error[E0778]: must specify an instruction set
- --> $DIR/feature-gate-isa_attribute.rs:1:1
- |
-LL | #[instruction_set]
- | ^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0658, E0778.
-For more information about an error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-linkage.rs b/src/test/ui/feature-gates/feature-gate-linkage.rs
index 15b8d442a..505f31ec6 100644
--- a/src/test/ui/feature-gates/feature-gate-linkage.rs
+++ b/src/test/ui/feature-gates/feature-gate-linkage.rs
@@ -1,5 +1,5 @@
extern "C" {
- #[linkage = "extern_weak"] static foo: isize;
+ #[linkage = "extern_weak"] static foo: *mut isize;
//~^ ERROR: the `linkage` attribute is experimental and not portable
}
diff --git a/src/test/ui/feature-gates/feature-gate-linkage.stderr b/src/test/ui/feature-gates/feature-gate-linkage.stderr
index 3e5b79bfd..a1c73e555 100644
--- a/src/test/ui/feature-gates/feature-gate-linkage.stderr
+++ b/src/test/ui/feature-gates/feature-gate-linkage.stderr
@@ -1,7 +1,7 @@
error[E0658]: the `linkage` attribute is experimental and not portable across platforms
--> $DIR/feature-gate-linkage.rs:2:5
|
-LL | #[linkage = "extern_weak"] static foo: isize;
+LL | #[linkage = "extern_weak"] static foo: *mut isize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #29603 <https://github.com/rust-lang/rust/issues/29603> for more information
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.rs b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.rs
deleted file mode 100644
index 7b09195dc..000000000
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-#[link(name = "foo", modifiers = "+verbatim")]
-//~^ ERROR: linking modifier `verbatim` is unstable
-extern "C" {}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.stderr b/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.stderr
deleted file mode 100644
index 3bfbeb8db..000000000
--- a/src/test/ui/feature-gates/feature-gate-native_link_modifiers_verbatim.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: linking modifier `verbatim` is unstable
- --> $DIR/feature-gate-native_link_modifiers_verbatim.rs:1:34
- |
-LL | #[link(name = "foo", modifiers = "+verbatim")]
- | ^^^^^^^^^^^
- |
- = note: see issue #81490 <https://github.com/rust-lang/rust/issues/81490> for more information
- = help: add `#![feature(native_link_modifiers_verbatim)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
index 5a645cf4e..787670404 100644
--- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
+++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
@@ -110,19 +110,19 @@ error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1
|
LL | #![no_link]
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^^ not an `extern crate` item
error: attribute should be applied to a free function, impl method or static
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:27:1
|
LL | #![export_name = "2200"]
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ not a free function, impl method or static
error[E0518]: attribute should be applied to function or closure
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:29:1
|
LL | #![inline]
- | ^^^^^^^^^^
+ | ^^^^^^^^^^ not a function or closure
error: `macro_export` attribute cannot be used at crate level
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1
diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
index 8db12e55d..1fa315f3d 100644
--- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
+++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
@@ -1,6 +1,6 @@
//~ NOTE not a function
//~| NOTE not a foreign function or static
-//~| NOTE not a function or static
+//~| NOTE cannot be applied to crates
//~| NOTE not an `extern` block
// This test enumerates as many compiler-builtin ungated attributes as
// possible (that is, all the mutually compatible ones), and checks
diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
index 310d1f720..300392679 100644
--- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
+++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
@@ -403,7 +403,7 @@ warning: attribute should be applied to a function definition
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
|
LL | #![cold]
- | ^^^^^^^^
+ | ^^^^^^^^ cannot be applied to crates
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
@@ -411,7 +411,7 @@ warning: attribute should be applied to an `extern` block with non-Rust ABI
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
|
LL | #![link()]
- | ^^^^^^^^^^
+ | ^^^^^^^^^^ not an `extern` block
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
@@ -419,7 +419,7 @@ warning: attribute should be applied to a foreign function or static
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
|
LL | #![link_name = "1900"]
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^ not a foreign function or static
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
@@ -427,7 +427,7 @@ warning: attribute should be applied to a function or static
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
|
LL | #![link_section = "1800"]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ not a function or static
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
diff --git a/src/test/ui/fmt/format-raw-string-error.rs b/src/test/ui/fmt/format-raw-string-error.rs
new file mode 100644
index 000000000..9f0bc01a7
--- /dev/null
+++ b/src/test/ui/fmt/format-raw-string-error.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!(r#"\'\'\'\'\'\'\'\'\'\'\'\'\'\'}"#); //~ ERROR invalid format string: unmatched `}` found
+}
diff --git a/src/test/ui/fmt/format-raw-string-error.stderr b/src/test/ui/fmt/format-raw-string-error.stderr
new file mode 100644
index 000000000..8d61950d8
--- /dev/null
+++ b/src/test/ui/fmt/format-raw-string-error.stderr
@@ -0,0 +1,10 @@
+error: invalid format string: unmatched `}` found
+ --> $DIR/format-raw-string-error.rs:2:45
+ |
+LL | println!(r#"\'\'\'\'\'\'\'\'\'\'\'\'\'\'}"#);
+ | ^ unmatched `}` in format string
+ |
+ = note: if you intended to print `}`, you can escape it using `}}`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/fmt/issue-104142.rs b/src/test/ui/fmt/issue-104142.rs
new file mode 100644
index 000000000..8d7283a71
--- /dev/null
+++ b/src/test/ui/fmt/issue-104142.rs
@@ -0,0 +1,6 @@
+fn main() {
+ println!(
+ r#"
+ \"\'}、"# //~ ERROR invalid format string: unmatched `}` found
+ );
+}
diff --git a/src/test/ui/fmt/issue-104142.stderr b/src/test/ui/fmt/issue-104142.stderr
new file mode 100644
index 000000000..d41644faa
--- /dev/null
+++ b/src/test/ui/fmt/issue-104142.stderr
@@ -0,0 +1,10 @@
+error: invalid format string: unmatched `}` found
+ --> $DIR/issue-104142.rs:4:9
+ |
+LL | \"\'}、"#
+ | ^ unmatched `}` in format string
+ |
+ = note: if you intended to print `}`, you can escape it using `}}`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/fmt/unicode-escape-spans.rs b/src/test/ui/fmt/unicode-escape-spans.rs
new file mode 100644
index 000000000..753d91ce5
--- /dev/null
+++ b/src/test/ui/fmt/unicode-escape-spans.rs
@@ -0,0 +1,19 @@
+fn main() {
+ // 1 byte in UTF-8
+ format!("\u{000041}{a}"); //~ ERROR cannot find value
+ format!("\u{0041}{a}"); //~ ERROR cannot find value
+ format!("\u{41}{a}"); //~ ERROR cannot find value
+ format!("\u{0}{a}"); //~ ERROR cannot find value
+
+ // 2 bytes
+ format!("\u{0df}{a}"); //~ ERROR cannot find value
+ format!("\u{df}{a}"); //~ ERROR cannot find value
+
+ // 3 bytes
+ format!("\u{00211d}{a}"); //~ ERROR cannot find value
+ format!("\u{211d}{a}"); //~ ERROR cannot find value
+
+ // 4 bytes
+ format!("\u{1f4a3}{a}"); //~ ERROR cannot find value
+ format!("\u{10ffff}{a}"); //~ ERROR cannot find value
+}
diff --git a/src/test/ui/fmt/unicode-escape-spans.stderr b/src/test/ui/fmt/unicode-escape-spans.stderr
new file mode 100644
index 000000000..1d8473f01
--- /dev/null
+++ b/src/test/ui/fmt/unicode-escape-spans.stderr
@@ -0,0 +1,63 @@
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:3:25
+ |
+LL | format!("\u{000041}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:4:23
+ |
+LL | format!("\u{0041}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:5:21
+ |
+LL | format!("\u{41}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:6:20
+ |
+LL | format!("\u{0}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:9:22
+ |
+LL | format!("\u{0df}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:10:21
+ |
+LL | format!("\u{df}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:13:25
+ |
+LL | format!("\u{00211d}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:14:23
+ |
+LL | format!("\u{211d}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:17:24
+ |
+LL | format!("\u{1f4a3}{a}");
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/unicode-escape-spans.rs:18:25
+ |
+LL | format!("\u{10ffff}{a}");
+ | ^ not found in this scope
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/fn/signature-error-reporting-under-verbose.rs b/src/test/ui/fn/signature-error-reporting-under-verbose.rs
new file mode 100644
index 000000000..d7a8c95e8
--- /dev/null
+++ b/src/test/ui/fn/signature-error-reporting-under-verbose.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Zverbose
+
+fn foo(_: i32, _: i32) {}
+
+fn needs_ptr(_: fn(i32, u32)) {}
+//~^ NOTE function defined here
+//~| NOTE
+
+fn main() {
+ needs_ptr(foo);
+ //~^ ERROR mismatched types
+ //~| NOTE expected `u32`, found `i32`
+ //~| NOTE expected fn pointer `fn(i32, u32)`
+ //~| NOTE arguments to this function are incorrect
+}
diff --git a/src/test/ui/fn/signature-error-reporting-under-verbose.stderr b/src/test/ui/fn/signature-error-reporting-under-verbose.stderr
new file mode 100644
index 000000000..6260fc8dc
--- /dev/null
+++ b/src/test/ui/fn/signature-error-reporting-under-verbose.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+ --> $DIR/signature-error-reporting-under-verbose.rs:10:15
+ |
+LL | needs_ptr(foo);
+ | --------- ^^^ expected `u32`, found `i32`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected fn pointer `fn(i32, u32)`
+ found fn item `fn(i32, i32) {foo}`
+note: function defined here
+ --> $DIR/signature-error-reporting-under-verbose.rs:5:4
+ |
+LL | fn needs_ptr(_: fn(i32, u32)) {}
+ | ^^^^^^^^^ ---------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/for-loop-while/break-outside-loop.stderr b/src/test/ui/for-loop-while/break-outside-loop.stderr
index 287bf9af6..9092f34df 100644
--- a/src/test/ui/for-loop-while/break-outside-loop.stderr
+++ b/src/test/ui/for-loop-while/break-outside-loop.stderr
@@ -9,11 +9,11 @@ LL | break 'lab;
|
= note: labels are unreachable through functions, closures, async blocks and modules
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/break-outside-loop.rs:10:15
|
LL | let pth = break;
- | ^^^^^ cannot `break` outside of a loop
+ | ^^^^^ cannot `break` outside of a loop or labeled block
error[E0268]: `continue` outside of a loop
--> $DIR/break-outside-loop.rs:11:17
@@ -38,11 +38,11 @@ LL | if cond() { break }
LL | if cond() { continue }
| ^^^^^^^^ cannot `continue` inside of a closure
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/break-outside-loop.rs:24:25
|
LL | let unconstrained = break;
- | ^^^^^ cannot `break` outside of a loop
+ | ^^^^^ cannot `break` outside of a loop or labeled block
error[E0267]: `break` inside of a closure
--> $DIR/break-outside-loop.rs:30:13
diff --git a/src/test/ui/function-pointer/unsized-ret.rs b/src/test/ui/function-pointer/unsized-ret.rs
index 60af5769d..79009c5cb 100644
--- a/src/test/ui/function-pointer/unsized-ret.rs
+++ b/src/test/ui/function-pointer/unsized-ret.rs
@@ -1,7 +1,8 @@
#![feature(fn_traits)]
#![feature(unboxed_closures)]
+#![feature(tuple_trait)]
-fn foo<F: Fn<T>, T>(f: Option<F>, t: T) {
+fn foo<F: Fn<T>, T:std::marker::Tuple>(f: Option<F>, t: T) {
let y = (f.unwrap()).call(t);
}
diff --git a/src/test/ui/function-pointer/unsized-ret.stderr b/src/test/ui/function-pointer/unsized-ret.stderr
index bec3e2aa3..40bf7a389 100644
--- a/src/test/ui/function-pointer/unsized-ret.stderr
+++ b/src/test/ui/function-pointer/unsized-ret.stderr
@@ -1,5 +1,5 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
- --> $DIR/unsized-ret.rs:9:27
+ --> $DIR/unsized-ret.rs:10:27
|
LL | foo::<fn() -> str, _>(None, ());
| --------------------- ^^^^ doesn't have a size known at compile-time
@@ -9,13 +9,13 @@ LL | foo::<fn() -> str, _>(None, ());
= help: within `fn() -> str`, the trait `Sized` is not implemented for `str`
= note: required because it appears within the type `fn() -> str`
note: required by a bound in `foo`
- --> $DIR/unsized-ret.rs:4:11
+ --> $DIR/unsized-ret.rs:5:11
|
-LL | fn foo<F: Fn<T>, T>(f: Option<F>, t: T) {
+LL | fn foo<F: Fn<T>, T:std::marker::Tuple>(f: Option<F>, t: T) {
| ^^^^^ required by this bound in `foo`
error[E0277]: the size for values of type `(dyn std::fmt::Display + 'a)` cannot be known at compilation time
- --> $DIR/unsized-ret.rs:12:66
+ --> $DIR/unsized-ret.rs:13:66
|
LL | foo::<for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a), _>(None, (&(),));
| ------------------------------------------------------------ ^^^^ doesn't have a size known at compile-time
@@ -25,9 +25,9 @@ LL | foo::<for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a), _>(None, (&()
= help: within `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`, the trait `for<'a> Sized` is not implemented for `(dyn std::fmt::Display + 'a)`
= note: required because it appears within the type `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`
note: required by a bound in `foo`
- --> $DIR/unsized-ret.rs:4:11
+ --> $DIR/unsized-ret.rs:5:11
|
-LL | fn foo<F: Fn<T>, T>(f: Option<F>, t: T) {
+LL | fn foo<F: Fn<T>, T:std::marker::Tuple>(f: Option<F>, t: T) {
| ^^^^^ required by this bound in `foo`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr
index 23324af61..0b1f34aeb 100644
--- a/src/test/ui/generator/auto-trait-regions.stderr
+++ b/src/test/ui/generator/auto-trait-regions.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let a = A(&mut true, &mut true, No);
| ^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | assert_foo(a);
| - borrow later used here
@@ -17,7 +17,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let a = A(&mut true, &mut true, No);
| ^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | assert_foo(a);
| - borrow later used here
diff --git a/src/test/ui/generator/clone-impl-async.rs b/src/test/ui/generator/clone-impl-async.rs
index 83c51526b..9e9b59d36 100644
--- a/src/test/ui/generator/clone-impl-async.rs
+++ b/src/test/ui/generator/clone-impl-async.rs
@@ -15,42 +15,42 @@ fn main() {
drop(non_clone);
};
check_copy(&inner_non_clone);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ //~^ ERROR : Copy` is not satisfied
check_clone(&inner_non_clone);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ //~^ ERROR : Clone` is not satisfied
let non_clone = NonClone;
let outer_non_clone = async move {
drop(non_clone);
};
check_copy(&outer_non_clone);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ //~^ ERROR : Copy` is not satisfied
check_clone(&outer_non_clone);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ //~^ ERROR : Clone` is not satisfied
let maybe_copy_clone = async move {};
check_copy(&maybe_copy_clone);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ //~^ ERROR : Copy` is not satisfied
check_clone(&maybe_copy_clone);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ //~^ ERROR : Clone` is not satisfied
let inner_non_clone_fn = the_inner_non_clone_fn();
check_copy(&inner_non_clone_fn);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ //~^ ERROR : Copy` is not satisfied
check_clone(&inner_non_clone_fn);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ //~^ ERROR : Clone` is not satisfied
let outer_non_clone_fn = the_outer_non_clone_fn(NonClone);
check_copy(&outer_non_clone_fn);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ //~^ ERROR : Copy` is not satisfied
check_clone(&outer_non_clone_fn);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ //~^ ERROR : Clone` is not satisfied
let maybe_copy_clone_fn = the_maybe_copy_clone_fn();
check_copy(&maybe_copy_clone_fn);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+ //~^ ERROR : Copy` is not satisfied
check_clone(&maybe_copy_clone_fn);
- //~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+ //~^ ERROR : Clone` is not satisfied
}
async fn the_inner_non_clone_fn() {
@@ -64,8 +64,7 @@ async fn the_outer_non_clone_fn(non_clone: NonClone) {
drop(non_clone);
}
-async fn the_maybe_copy_clone_fn() {
-}
+async fn the_maybe_copy_clone_fn() {}
fn check_copy<T: Copy>(_x: &T) {}
fn check_clone<T: Clone>(_x: &T) {}
diff --git a/src/test/ui/generator/clone-impl-async.stderr b/src/test/ui/generator/clone-impl-async.stderr
index cbb58d2af..985472887 100644
--- a/src/test/ui/generator/clone-impl-async.stderr
+++ b/src/test/ui/generator/clone-impl-async.stderr
@@ -1,83 +1,83 @@
-error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:12:27: 16:6]: Copy` is not satisfied
--> $DIR/clone-impl-async.rs:17:16
|
LL | check_copy(&inner_non_clone);
- | ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
+ | ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `[async block@$DIR/clone-impl-async.rs:12:27: 16:6]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
- --> $DIR/clone-impl-async.rs:70:18
+ --> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`
-error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:12:27: 16:6]: Clone` is not satisfied
--> $DIR/clone-impl-async.rs:19:17
|
LL | check_clone(&inner_non_clone);
- | ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
+ | ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `[async block@$DIR/clone-impl-async.rs:12:27: 16:6]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
- --> $DIR/clone-impl-async.rs:71:19
+ --> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`
-error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:23:27: 25:6]: Copy` is not satisfied
--> $DIR/clone-impl-async.rs:26:16
|
LL | check_copy(&outer_non_clone);
- | ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
+ | ---------- ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `[async block@$DIR/clone-impl-async.rs:23:27: 25:6]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
- --> $DIR/clone-impl-async.rs:70:18
+ --> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`
-error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:23:27: 25:6]: Clone` is not satisfied
--> $DIR/clone-impl-async.rs:28:17
|
LL | check_clone(&outer_non_clone);
- | ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
+ | ----------- ^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `[async block@$DIR/clone-impl-async.rs:23:27: 25:6]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
- --> $DIR/clone-impl-async.rs:71:19
+ --> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`
-error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:31:28: 31:41]: Copy` is not satisfied
--> $DIR/clone-impl-async.rs:32:16
|
LL | check_copy(&maybe_copy_clone);
- | ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
+ | ---------- ^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `[async block@$DIR/clone-impl-async.rs:31:28: 31:41]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
- --> $DIR/clone-impl-async.rs:70:18
+ --> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`
-error[E0277]: the trait bound `impl Future<Output = ()>: Clone` is not satisfied
+error[E0277]: the trait bound `[async block@$DIR/clone-impl-async.rs:31:28: 31:41]: Clone` is not satisfied
--> $DIR/clone-impl-async.rs:34:17
|
LL | check_clone(&maybe_copy_clone);
- | ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `impl Future<Output = ()>`
+ | ----------- ^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `[async block@$DIR/clone-impl-async.rs:31:28: 31:41]`
| |
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
- --> $DIR/clone-impl-async.rs:71:19
+ --> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`
@@ -91,7 +91,7 @@ LL | check_copy(&inner_non_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
- --> $DIR/clone-impl-async.rs:70:18
+ --> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`
@@ -105,7 +105,7 @@ LL | check_clone(&inner_non_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
- --> $DIR/clone-impl-async.rs:71:19
+ --> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`
@@ -119,7 +119,7 @@ LL | check_copy(&outer_non_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
- --> $DIR/clone-impl-async.rs:70:18
+ --> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`
@@ -133,7 +133,7 @@ LL | check_clone(&outer_non_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
- --> $DIR/clone-impl-async.rs:71:19
+ --> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`
@@ -147,7 +147,7 @@ LL | check_copy(&maybe_copy_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_copy`
- --> $DIR/clone-impl-async.rs:70:18
+ --> $DIR/clone-impl-async.rs:69:18
|
LL | fn check_copy<T: Copy>(_x: &T) {}
| ^^^^ required by this bound in `check_copy`
@@ -161,7 +161,7 @@ LL | check_clone(&maybe_copy_clone_fn);
| required by a bound introduced by this call
|
note: required by a bound in `check_clone`
- --> $DIR/clone-impl-async.rs:71:19
+ --> $DIR/clone-impl-async.rs:70:19
|
LL | fn check_clone<T: Clone>(_x: &T) {}
| ^^^^^ required by this bound in `check_clone`
diff --git a/src/test/ui/generator/issue-52398.stderr b/src/test/ui/generator/issue-52398.stderr
index 30a6732f7..539343275 100644
--- a/src/test/ui/generator/issue-52398.stderr
+++ b/src/test/ui/generator/issue-52398.stderr
@@ -4,7 +4,7 @@ warning: unused generator that must be used
LL | / move || {
LL | | A.test(yield);
LL | | };
- | |______^
+ | |_____^
|
= note: generators are lazy and do nothing unless resumed
= note: `#[warn(unused_must_use)]` on by default
@@ -16,7 +16,7 @@ LL | / static move || {
LL | | yield *y.borrow();
LL | | return "Done";
LL | | };
- | |______^
+ | |_____^
|
= note: generators are lazy and do nothing unless resumed
diff --git a/src/test/ui/generator/issue-57084.stderr b/src/test/ui/generator/issue-57084.stderr
index 29aca9440..8f1fc5e80 100644
--- a/src/test/ui/generator/issue-57084.stderr
+++ b/src/test/ui/generator/issue-57084.stderr
@@ -7,7 +7,7 @@ LL | | loop {
LL | | yield
LL | | }
LL | | };
- | |______^
+ | |_____^
|
= note: generators are lazy and do nothing unless resumed
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/match-bindings.stderr b/src/test/ui/generator/match-bindings.stderr
index b911b6661..3dd2d5954 100644
--- a/src/test/ui/generator/match-bindings.stderr
+++ b/src/test/ui/generator/match-bindings.stderr
@@ -8,7 +8,7 @@ LL | | match Enum::A(String::new()) {
... |
LL | | }
LL | | };
- | |______^
+ | |_____^
|
= note: generators are lazy and do nothing unless resumed
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/print/generator-print-verbose-1.stderr b/src/test/ui/generator/print/generator-print-verbose-1.stderr
index 2e0207804..ed0628bbb 100644
--- a/src/test/ui/generator/print/generator-print-verbose-1.stderr
+++ b/src/test/ui/generator/print/generator-print-verbose-1.stderr
@@ -9,7 +9,7 @@ note: generator is not `Send` as this value is used across a yield
--> $DIR/generator-print-verbose-1.rs:35:9
|
LL | let _non_send_gen = make_non_send_generator();
- | ------------- has type `Opaque(DefId(0:44 ~ generator_print_verbose_1[749a]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
+ | ------------- has type `Opaque(DefId(0:34 ~ generator_print_verbose_1[749a]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
LL | yield;
| ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
LL | };
@@ -35,17 +35,17 @@ note: required because it's used within this generator
|
LL | || {
| ^^
-note: required because it appears within the type `Opaque(DefId(0:45 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])`
+note: required because it appears within the type `Opaque(DefId(0:35 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])`
--> $DIR/generator-print-verbose-1.rs:41:30
|
LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: required because it appears within the type `Opaque(DefId(0:46 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`
+note: required because it appears within the type `Opaque(DefId(0:36 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`
--> $DIR/generator-print-verbose-1.rs:47:34
|
LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- = note: required because it captures the following types: `Opaque(DefId(0:46 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()`
+ = note: required because it captures the following types: `Opaque(DefId(0:36 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()`
note: required because it's used within this generator
--> $DIR/generator-print-verbose-1.rs:52:20
|
diff --git a/src/test/ui/generator/reborrow-mut-upvar.stderr b/src/test/ui/generator/reborrow-mut-upvar.stderr
index e83dbf833..2e1fec35e 100644
--- a/src/test/ui/generator/reborrow-mut-upvar.stderr
+++ b/src/test/ui/generator/reborrow-mut-upvar.stderr
@@ -8,7 +8,7 @@ LL | | yield;
... |
LL | | *bar = 2;
LL | | };
- | |______^
+ | |_____^
|
= note: generators are lazy and do nothing unless resumed
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr
index 5cb43067f..e262f213f 100644
--- a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr
+++ b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr
@@ -8,7 +8,7 @@ LL | | // and it should also find out that `a` is not live.
... |
LL | | let _ = &a;
LL | | };
- | |__________^
+ | |_________^
|
= note: generators are lazy and do nothing unless resumed
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/unresolved-ct-var.rs b/src/test/ui/generator/unresolved-ct-var.rs
new file mode 100644
index 000000000..0a1570fc2
--- /dev/null
+++ b/src/test/ui/generator/unresolved-ct-var.rs
@@ -0,0 +1,14 @@
+// incremental
+// edition:2021
+
+fn main() {
+ let _ = async {
+ let s = std::array::from_fn(|_| ()).await;
+ //~^ ERROR `[(); _]` is not a future
+ //~| ERROR type inside `async` block must be known in this context
+ //~| ERROR type inside `async` block must be known in this context
+ //~| ERROR type inside `async` block must be known in this context
+ //~| ERROR type inside `async` block must be known in this context
+ //~| ERROR type inside `async` block must be known in this context
+ };
+}
diff --git a/src/test/ui/generator/unresolved-ct-var.stderr b/src/test/ui/generator/unresolved-ct-var.stderr
new file mode 100644
index 000000000..fdf00dfad
--- /dev/null
+++ b/src/test/ui/generator/unresolved-ct-var.stderr
@@ -0,0 +1,78 @@
+error[E0277]: `[(); _]` is not a future
+ --> $DIR/unresolved-ct-var.rs:6:44
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ---------------------------^^^^^^
+ | | |
+ | | `[(); _]` is not a future
+ | | help: remove the `.await`
+ | this call returns `[(); _]`
+ |
+ = help: the trait `Future` is not implemented for `[(); _]`
+ = note: [(); _] must be a future or must implement `IntoFuture` to be awaited
+ = note: required for `[(); _]` to implement `IntoFuture`
+
+error[E0698]: type inside `async` block must be known in this context
+ --> $DIR/unresolved-ct-var.rs:6:17
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
+ |
+note: the type is part of the `async` block because of this `await`
+ --> $DIR/unresolved-ct-var.rs:6:44
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ^^^^^^
+
+error[E0698]: type inside `async` block must be known in this context
+ --> $DIR/unresolved-ct-var.rs:6:17
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
+ |
+note: the type is part of the `async` block because of this `await`
+ --> $DIR/unresolved-ct-var.rs:6:44
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ^^^^^^
+
+error[E0698]: type inside `async` block must be known in this context
+ --> $DIR/unresolved-ct-var.rs:6:17
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
+ |
+note: the type is part of the `async` block because of this `await`
+ --> $DIR/unresolved-ct-var.rs:6:44
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ^^^^^^
+
+error[E0698]: type inside `async` block must be known in this context
+ --> $DIR/unresolved-ct-var.rs:6:17
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
+ |
+note: the type is part of the `async` block because of this `await`
+ --> $DIR/unresolved-ct-var.rs:6:44
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ^^^^^^
+
+error[E0698]: type inside `async` block must be known in this context
+ --> $DIR/unresolved-ct-var.rs:6:17
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
+ |
+note: the type is part of the `async` block because of this `await`
+ --> $DIR/unresolved-ct-var.rs:6:44
+ |
+LL | let s = std::array::from_fn(|_| ()).await;
+ | ^^^^^^
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0277, E0698.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generator/yield-in-args-rev.stderr b/src/test/ui/generator/yield-in-args-rev.stderr
index c9e1ab722..a87248f66 100644
--- a/src/test/ui/generator/yield-in-args-rev.stderr
+++ b/src/test/ui/generator/yield-in-args-rev.stderr
@@ -5,7 +5,7 @@ LL | / || {
LL | | let b = true;
LL | | foo(yield, &b);
LL | | };
- | |______^
+ | |_____^
|
= note: generators are lazy and do nothing unless resumed
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/yield-in-box.stderr b/src/test/ui/generator/yield-in-box.stderr
index 8587e1dc6..9d03ee008 100644
--- a/src/test/ui/generator/yield-in-box.stderr
+++ b/src/test/ui/generator/yield-in-box.stderr
@@ -8,7 +8,7 @@ LL | | let _t = box (&x, yield 0, &y);
... |
LL | | }
LL | | };
- | |______^
+ | |_____^
|
= note: generators are lazy and do nothing unless resumed
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/yield-in-initializer.stderr b/src/test/ui/generator/yield-in-initializer.stderr
index 07de24662..ed14a2e32 100644
--- a/src/test/ui/generator/yield-in-initializer.stderr
+++ b/src/test/ui/generator/yield-in-initializer.stderr
@@ -8,7 +8,7 @@ LL | | // See https://github.com/rust-lang/rust/issues/52792
... |
LL | | }
LL | | };
- | |______^
+ | |_____^
|
= note: generators are lazy and do nothing unless resumed
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generator/yield-subtype.stderr b/src/test/ui/generator/yield-subtype.stderr
index fe10477bf..97862e91c 100644
--- a/src/test/ui/generator/yield-subtype.stderr
+++ b/src/test/ui/generator/yield-subtype.stderr
@@ -5,7 +5,7 @@ LL | / || {
LL | | yield a;
LL | | yield b;
LL | | };
- | |______^
+ | |_____^
|
= note: generators are lazy and do nothing unless resumed
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr b/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr
index 414999881..1c9abc4e8 100644
--- a/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr
+++ b/src/test/ui/generic-associated-types/bugs/hrtb-implied-1.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/hrtb-implied-1.rs:31:22
|
LL | let slice = &mut ();
- | ^^ creates a temporary which is freed while still in use
+ | ^^ creates a temporary value which is freed while still in use
...
LL | print_items::<WindowsMut<'_>>(windows);
| -------------------------------------- argument requires that borrow lasts for `'static`
diff --git a/src/test/ui/generic-associated-types/bugs/issue-100013.rs b/src/test/ui/generic-associated-types/bugs/issue-100013.rs
new file mode 100644
index 000000000..fc4e47a3b
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-100013.rs
@@ -0,0 +1,39 @@
+// check-fail
+// known-bug
+// edition: 2021
+
+// We really should accept this, but we need implied bounds between the regions
+// in a generator interior.
+
+pub trait FutureIterator {
+ type Future<'s, 'cx>: Send
+ where
+ 's: 'cx;
+}
+
+fn call<I: FutureIterator>() -> impl Send {
+ async { // a generator checked for autotrait impl `Send`
+ //~^ lifetime bound not satisfied
+ let x = None::<I::Future<'_, '_>>; // a type referencing GAT
+ async {}.await; // a yield point
+ }
+}
+
+fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
+ async { // a generator checked for autotrait impl `Send`
+ //~^ lifetime bound not satisfied
+ let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+ //~^ lifetime may not live long enough
+ async {}.await; // a yield point
+ }
+}
+
+fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
+ async { // a generator checked for autotrait impl `Send`
+ //~^ lifetime bound not satisfied
+ let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+ async {}.await; // a yield point
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-100013.stderr b/src/test/ui/generic-associated-types/bugs/issue-100013.stderr
new file mode 100644
index 000000000..72ae288dc
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-100013.stderr
@@ -0,0 +1,82 @@
+error: lifetime bound not satisfied
+ --> $DIR/issue-100013.rs:15:5
+ |
+LL | / async { // a generator checked for autotrait impl `Send`
+LL | |
+LL | | let x = None::<I::Future<'_, '_>>; // a type referencing GAT
+LL | | async {}.await; // a yield point
+LL | | }
+ | |_____^
+ |
+note: the lifetime defined here...
+ --> $DIR/issue-100013.rs:17:38
+ |
+LL | let x = None::<I::Future<'_, '_>>; // a type referencing GAT
+ | ^^
+note: ...must outlive the lifetime defined here
+ --> $DIR/issue-100013.rs:17:34
+ |
+LL | let x = None::<I::Future<'_, '_>>; // a type referencing GAT
+ | ^^
+ = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+
+error: lifetime bound not satisfied
+ --> $DIR/issue-100013.rs:23:5
+ |
+LL | / async { // a generator checked for autotrait impl `Send`
+LL | |
+LL | | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+LL | |
+LL | | async {}.await; // a yield point
+LL | | }
+ | |_____^
+ |
+note: the lifetime defined here...
+ --> $DIR/issue-100013.rs:22:14
+ |
+LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
+ | ^^
+note: ...must outlive the lifetime defined here
+ --> $DIR/issue-100013.rs:22:10
+ |
+LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
+ | ^^
+ = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+
+error: lifetime may not live long enough
+ --> $DIR/issue-100013.rs:25:17
+ |
+LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime bound not satisfied
+ --> $DIR/issue-100013.rs:32:5
+ |
+LL | / async { // a generator checked for autotrait impl `Send`
+LL | |
+LL | | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+LL | | async {}.await; // a yield point
+LL | | }
+ | |_____^
+ |
+note: the lifetime defined here...
+ --> $DIR/issue-100013.rs:31:18
+ |
+LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
+ | ^^
+note: ...must outlive the lifetime defined here
+ --> $DIR/issue-100013.rs:31:10
+ |
+LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
+ | ^^
+ = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.rs b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
index f6aa6b36e..d6e18010f 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-80626.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
@@ -1,7 +1,4 @@
-// check-fail
-// known-bug: #80626
-
-// This should pass, but it requires `Sized` to be coinductive.
+// check-pass
trait Allocator {
type Allocated<T>;
@@ -9,7 +6,7 @@ trait Allocator {
enum LinkedList<A: Allocator> {
Head,
- Next(A::Allocated<Self>)
+ Next(A::Allocated<Self>),
}
fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
deleted file mode 100644
index 9a0f332ed..000000000
--- a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0275]: overflow evaluating the requirement `LinkedList<A>: Sized`
- --> $DIR/issue-80626.rs:12:10
- |
-LL | Next(A::Allocated<Self>)
- | ^^^^^^^^^^^^^^^^^^
- |
-note: required by a bound in `Allocator::Allocated`
- --> $DIR/issue-80626.rs:7:20
- |
-LL | type Allocated<T>;
- | ^ required by this bound in `Allocator::Allocated`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/generic-associated-types/elided-in-expr-position.stderr b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
index 20f35c3c1..a9996123f 100644
--- a/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
+++ b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
@@ -11,7 +11,7 @@ LL | type Assoc<'a> where Self: 'a;
| ^^^^^ --
help: add missing lifetime argument
|
-LL | fn g(&self) -> Self::Assoc<'a>;
+LL | fn g(&self) -> Self::Assoc<'_>;
| ~~~~~~~~~
error[E0107]: missing generics for associated type `Trait::Assoc`
@@ -27,7 +27,7 @@ LL | type Assoc<'a> where Self: 'a;
| ^^^^^ --
help: add missing lifetime argument
|
-LL | fn g(&self) -> Self::Assoc<'a> {
+LL | fn g(&self) -> Self::Assoc<'_> {
| ~~~~~~~~~
error: aborting due to 2 previous errors
diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
index e55a21e19..165779796 100644
--- a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
+++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
@@ -36,7 +36,7 @@ LL | type Y<'a>;
| ^ --
help: add missing lifetime argument
|
-LL | fn foo<'a>(arg: Box<dyn X<Y('a, 'a) = &'a ()>>) {}
+LL | fn foo<'a>(arg: Box<dyn X<Y('_, 'a) = &'a ()>>) {}
| +++
error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
@@ -66,7 +66,7 @@ LL | type Y<'a>;
| ^ --
help: add missing lifetime argument
|
-LL | fn bar<'a>(arg: Box<dyn X<Y('a) = ()>>) {}
+LL | fn bar<'a>(arg: Box<dyn X<Y('_) = ()>>) {}
| ++
error: aborting due to 6 previous errors
diff --git a/src/test/ui/generic-associated-types/issue-81862.stderr b/src/test/ui/generic-associated-types/issue-81862.stderr
index ba7980846..9e21c567c 100644
--- a/src/test/ui/generic-associated-types/issue-81862.stderr
+++ b/src/test/ui/generic-associated-types/issue-81862.stderr
@@ -11,7 +11,7 @@ LL | type Item<'a>;
| ^^^^ --
help: add missing lifetime argument
|
-LL | fn next(&mut self) -> Option<Self::Item<'a>>;
+LL | fn next(&mut self) -> Option<Self::Item<'_>>;
| ~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/generic-associated-types/issue-87750.rs b/src/test/ui/generic-associated-types/issue-87750.rs
index 0a11a0f3a..b35657989 100644
--- a/src/test/ui/generic-associated-types/issue-87750.rs
+++ b/src/test/ui/generic-associated-types/issue-87750.rs
@@ -1,3 +1,5 @@
+// check-pass
+
trait PointerFamily {
type Pointer<T>;
}
@@ -10,11 +12,13 @@ impl PointerFamily for RcFamily {
}
#[allow(dead_code)]
-enum Node<T, P: PointerFamily> where P::Pointer<Node<T, P>>: Sized {
+enum Node<T, P: PointerFamily>
+where
+ P::Pointer<Node<T, P>>: Sized,
+{
Cons(P::Pointer<Node<T, P>>),
}
fn main() {
let _list: <RcFamily as PointerFamily>::Pointer<Node<i32, RcFamily>>;
- //~^ ERROR overflow evaluating the requirement `Node<i32, RcFamily>: Sized`
}
diff --git a/src/test/ui/generic-associated-types/issue-87750.stderr b/src/test/ui/generic-associated-types/issue-87750.stderr
deleted file mode 100644
index b358ca273..000000000
--- a/src/test/ui/generic-associated-types/issue-87750.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0275]: overflow evaluating the requirement `Node<i32, RcFamily>: Sized`
- --> $DIR/issue-87750.rs:18:16
- |
-LL | let _list: <RcFamily as PointerFamily>::Pointer<Node<i32, RcFamily>>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/generic-associated-types/issue-91139.rs b/src/test/ui/generic-associated-types/issue-91139.rs
index 5fc6071c9..e321da53d 100644
--- a/src/test/ui/generic-associated-types/issue-91139.rs
+++ b/src/test/ui/generic-associated-types/issue-91139.rs
@@ -21,6 +21,7 @@ fn foo<T>() {
//~| ERROR `T` does not live long enough
//~| ERROR `T` does not live long enough
//~| ERROR `T` may not live long enough
+ //~| ERROR `T` may not live long enough
//
// FIXME: This error is bogus, but it arises because we try to validate
// that `<() as Foo<T>>::Type<'a>` is valid, which requires proving
diff --git a/src/test/ui/generic-associated-types/issue-91139.stderr b/src/test/ui/generic-associated-types/issue-91139.stderr
index 8bbe98fa1..5485570ce 100644
--- a/src/test/ui/generic-associated-types/issue-91139.stderr
+++ b/src/test/ui/generic-associated-types/issue-91139.stderr
@@ -22,6 +22,17 @@ error: `T` does not live long enough
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/issue-91139.rs:14:58
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn foo<T: 'static>() {
+ | +++++++++
+
error: `T` does not live long enough
--> $DIR/issue-91139.rs:14:58
|
@@ -57,6 +68,6 @@ error: `T` does not live long enough
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/generic-associated-types/missing_lifetime_args.stderr b/src/test/ui/generic-associated-types/missing_lifetime_args.stderr
index 0ad1f1f8c..752587c25 100644
--- a/src/test/ui/generic-associated-types/missing_lifetime_args.stderr
+++ b/src/test/ui/generic-associated-types/missing_lifetime_args.stderr
@@ -11,7 +11,7 @@ LL | type Y<'a, 'b>;
| ^ -- --
help: add missing lifetime arguments
|
-LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'c, 'd> = (&'c u32, &'d u32)>>) {}
+LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'_, '_> = (&'c u32, &'d u32)>>) {}
| ~~~~~~~~~
error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
@@ -47,7 +47,7 @@ LL | struct Foo<'a, 'b, 'c> {
| ^^^ -- -- --
help: add missing lifetime arguments
|
-LL | fn f<'a>(_arg: Foo<'a, 'b, 'c>) {}
+LL | fn f<'a>(_arg: Foo<'a, 'a, 'a>) {}
| ++++++++
error: aborting due to 3 previous errors
diff --git a/src/test/ui/generic-associated-types/own-bound-span.rs b/src/test/ui/generic-associated-types/own-bound-span.rs
new file mode 100644
index 000000000..3699f7296
--- /dev/null
+++ b/src/test/ui/generic-associated-types/own-bound-span.rs
@@ -0,0 +1,17 @@
+struct S;
+
+trait D {
+ type P<T: Copy>;
+ //~^ NOTE required by this bound in `D::P`
+ //~| NOTE required by a bound in `D::P`
+}
+
+impl D for S {
+ type P<T: Copy> = ();
+}
+
+fn main() {
+ let _: <S as D>::P<String>;
+ //~^ ERROR the trait bound `String: Copy` is not satisfied
+ //~| NOTE the trait `Copy` is not implemented for `String`
+}
diff --git a/src/test/ui/generic-associated-types/own-bound-span.stderr b/src/test/ui/generic-associated-types/own-bound-span.stderr
new file mode 100644
index 000000000..8ab8ea623
--- /dev/null
+++ b/src/test/ui/generic-associated-types/own-bound-span.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `String: Copy` is not satisfied
+ --> $DIR/own-bound-span.rs:14:12
+ |
+LL | let _: <S as D>::P<String>;
+ | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+ |
+note: required by a bound in `D::P`
+ --> $DIR/own-bound-span.rs:4:15
+ |
+LL | type P<T: Copy>;
+ | ^^^^ required by this bound in `D::P`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
index e00a414ef..0a09ec5dc 100644
--- a/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
+++ b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
@@ -11,7 +11,7 @@ LL | type Y<'a>;
| ^ --
help: add missing lifetime argument
|
-LL | fn f2<'a>(arg : Box<dyn X<Y<'a, 1> = &'a ()>>) {}
+LL | fn f2<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {}
| +++
error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
index 58d57df63..ecf6f69c9 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
@@ -21,6 +21,7 @@ impl<T> Foo for Number<T> {
// ```
// which it is :)
type Item = [T] where [T]: Sized;
+ //~^ ERROR overflow evaluating the requirement `<Number<T> as Foo>::Item == _`
}
struct OnlySized<T> where T: Sized { f: T }
@@ -40,7 +41,6 @@ impl<T> Bar for T where T: Foo {
// can use the bound on `Foo::Item` for this, but that requires
// `wf(<T as Foo>::Item)`, which is an invalid cycle.
type Assoc = OnlySized<<T as Foo>::Item>;
- //~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: Sized`
}
fn foo<T: Print>() {
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
index 27c1a8299..aae9a56bb 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
@@ -1,14 +1,8 @@
-error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: Sized`
- --> $DIR/projection-bound-cycle-generic.rs:42:18
+error[E0275]: overflow evaluating the requirement `<Number<T> as Foo>::Item == _`
+ --> $DIR/projection-bound-cycle-generic.rs:23:5
|
-LL | type Assoc = OnlySized<<T as Foo>::Item>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: required by a bound in `OnlySized`
- --> $DIR/projection-bound-cycle-generic.rs:26:18
- |
-LL | struct OnlySized<T> where T: Sized { f: T }
- | ^ required by this bound in `OnlySized`
+LL | type Item = [T] where [T]: Sized;
+ | ^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle.rs b/src/test/ui/generic-associated-types/projection-bound-cycle.rs
index 4cad1f613..b51ae7ef2 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle.rs
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle.rs
@@ -24,6 +24,7 @@ impl Foo for Number {
// ```
// which it is :)
type Item = str where str: Sized;
+ //~^ ERROR overflow evaluating the requirement `<Number as Foo>::Item == _`
}
struct OnlySized<T> where T: Sized { f: T }
@@ -43,7 +44,6 @@ impl<T> Bar for T where T: Foo {
// can use the bound on `Foo::Item` for this, but that requires
// `wf(<T as Foo>::Item)`, which is an invalid cycle.
type Assoc = OnlySized<<T as Foo>::Item>;
- //~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: Sized`
}
fn foo<T: Print>() {
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle.stderr b/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
index a46518c80..b1b8afeec 100644
--- a/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
@@ -1,14 +1,8 @@
-error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: Sized`
- --> $DIR/projection-bound-cycle.rs:45:18
+error[E0275]: overflow evaluating the requirement `<Number as Foo>::Item == _`
+ --> $DIR/projection-bound-cycle.rs:26:5
|
-LL | type Assoc = OnlySized<<T as Foo>::Item>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: required by a bound in `OnlySized`
- --> $DIR/projection-bound-cycle.rs:29:18
- |
-LL | struct OnlySized<T> where T: Sized { f: T }
- | ^ required by this bound in `OnlySized`
+LL | type Item = str where str: Sized;
+ | ^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/generic-associated-types/self-outlives-lint.stderr b/src/test/ui/generic-associated-types/self-outlives-lint.stderr
index 58172bf06..9e9b2e18a 100644
--- a/src/test/ui/generic-associated-types/self-outlives-lint.stderr
+++ b/src/test/ui/generic-associated-types/self-outlives-lint.stderr
@@ -108,17 +108,6 @@ LL | type Bar<'b>;
= note: this bound is currently required to ensure that impls have maximum flexibility
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
-error: missing required bound on `Item`
- --> $DIR/self-outlives-lint.rs:140:5
- |
-LL | type Item<'a>;
- | ^^^^^^^^^^^^^-
- | |
- | help: add the required where clause: `where Self: 'a`
- |
- = note: this bound is currently required to ensure that impls have maximum flexibility
- = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
-
error: missing required bound on `Iterator`
--> $DIR/self-outlives-lint.rs:142:5
|
@@ -131,6 +120,17 @@ LL | type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Item`
+ --> $DIR/self-outlives-lint.rs:140:5
+ |
+LL | type Item<'a>;
+ | ^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'a`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Item`
--> $DIR/self-outlives-lint.rs:148:5
|
LL | type Item<'a>;
diff --git a/src/test/ui/generics/wrong-number-of-args.stderr b/src/test/ui/generics/wrong-number-of-args.stderr
index 388c23fc2..0475eb908 100644
--- a/src/test/ui/generics/wrong-number-of-args.stderr
+++ b/src/test/ui/generics/wrong-number-of-args.stderr
@@ -812,8 +812,8 @@ LL | trait GenericLifetimeLifetimeAT<'a, 'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ -- --
help: add missing lifetime argument
|
-LL | type B = Box<dyn GenericLifetimeLifetimeAT<'static, 'b, AssocTy=()>>;
- | ++++
+LL | type B = Box<dyn GenericLifetimeLifetimeAT<'static, 'static, AssocTy=()>>;
+ | +++++++++
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:287:26
@@ -846,8 +846,8 @@ LL | trait GenericLifetimeLifetimeTypeAT<'a, 'b, A> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- --
help: add missing lifetime argument
|
-LL | type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'b, AssocTy=()>>;
- | ++++
+LL | type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'static, AssocTy=()>>;
+ | +++++++++
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:294:26
@@ -880,8 +880,8 @@ LL | trait GenericLifetimeLifetimeTypeAT<'a, 'b, A> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- --
help: add missing lifetime argument
|
-LL | type C = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'b, (), AssocTy=()>>;
- | ++++
+LL | type C = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'static, (), AssocTy=()>>;
+ | +++++++++
error[E0107]: missing generics for struct `HashMap`
--> $DIR/wrong-number-of-args.rs:310:18
diff --git a/src/test/ui/issues/issue-36139-normalize-closure-sig.rs b/src/test/ui/higher-rank-trait-bounds/issue-36139-normalize-closure-sig.rs
index 2d49151ff..2d49151ff 100644
--- a/src/test/ui/issues/issue-36139-normalize-closure-sig.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-36139-normalize-closure-sig.rs
diff --git a/src/test/ui/issues/issue-43623.rs b/src/test/ui/higher-rank-trait-bounds/issue-43623.rs
index cedcf7c36..cedcf7c36 100644
--- a/src/test/ui/issues/issue-43623.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-43623.rs
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs
new file mode 100644
index 000000000..ab9d9a7ce
--- /dev/null
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs
@@ -0,0 +1,53 @@
+// check-fail
+// known-bug: #90950
+
+trait Yokeable<'a>: 'static {
+ type Output: 'a;
+}
+
+
+trait IsCovariant<'a> {}
+
+struct Yoke<Y: for<'a> Yokeable<'a>> {
+ data: Y,
+}
+
+
+// impl<Y: for<'a> Yokeable<'a>> Yoke<Y> {
+// fn project<Y2: for<'a> Yokeable<'a>>(
+// &self,
+// f: for<'a> fn(<Y as Yokeable<'a>>::Output, &'a (),
+// ) -> <Y2 as Yokeable<'a>>::Output) -> Yoke<Y2> {
+// unimplemented!()
+// }
+// }
+
+fn upcast<Y>(x: Yoke<Y>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> where
+ Y: for<'a> Yokeable<'a>,
+ for<'a> <Y as Yokeable<'a>>::Output: IsCovariant<'a>
+ {
+ // x.project(|data, _| {
+ // Box::new(data)
+ // })
+ unimplemented!()
+}
+
+
+impl<'a> Yokeable<'a> for Box<dyn IsCovariant<'static> + 'static> {
+ type Output = Box<dyn IsCovariant<'a> + 'a>;
+}
+
+// this impl is mostly an example and unnecessary for the pure repro
+use std::borrow::*;
+impl<'a, T: ToOwned + ?Sized> Yokeable<'a> for Cow<'static, T> {
+ type Output = Cow<'a, T>;
+}
+impl<'a, T: ToOwned + ?Sized> IsCovariant<'a> for Cow<'a, T> {}
+
+
+
+fn upcast_yoke(y: Yoke<Cow<'static, str>>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> {
+ upcast(y)
+}
+
+fn main() {}
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr
new file mode 100644
index 000000000..6206b167b
--- /dev/null
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `for<'a> <_ as Yokeable<'a>>::Output: IsCovariant<'a>` is not satisfied
+ --> $DIR/issue-90950.rs:50:12
+ |
+LL | upcast(y)
+ | ------ ^ the trait `for<'a> IsCovariant<'a>` is not implemented for `<_ as Yokeable<'a>>::Output`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `IsCovariant<'a>` is implemented for `std::borrow::Cow<'a, T>`
+note: required by a bound in `upcast`
+ --> $DIR/issue-90950.rs:27:42
+ |
+LL | fn upcast<Y>(x: Yoke<Y>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> where
+ | ------ required by a bound in this
+LL | Y: for<'a> Yokeable<'a>,
+LL | for<'a> <Y as Yokeable<'a>>::Output: IsCovariant<'a>
+ | ^^^^^^^^^^^^^^^ required by this bound in `upcast`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
new file mode 100644
index 000000000..7693b1182
--- /dev/null
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
@@ -0,0 +1,23 @@
+// check-fail
+// known-bug: #89196
+
+// Should pass, but we normalize and check bounds before we resolve the generics
+// of the function (which we know because of the return type).
+
+trait Trait<'a> {
+ type Out;
+}
+
+impl<'a, T> Trait<'a> for T {
+ type Out = T;
+}
+
+fn weird_bound<X>() -> X
+ where
+ for<'a> X: Trait<'a>,
+ for<'a> <X as Trait<'a>>::Out: Copy
+{ todo!() }
+
+fn main() {
+ let _: () = weird_bound();
+}
diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
new file mode 100644
index 000000000..51c964600
--- /dev/null
+++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `for<'a> <_ as Trait<'a>>::Out: Copy` is not satisfied
+ --> $DIR/norm-before-method-resolution.rs:22:17
+ |
+LL | let _: () = weird_bound();
+ | ^^^^^^^^^^^ the trait `for<'a> Copy` is not implemented for `<_ as Trait<'a>>::Out`
+ |
+note: required by a bound in `weird_bound`
+ --> $DIR/norm-before-method-resolution.rs:18:40
+ |
+LL | fn weird_bound<X>() -> X
+ | ----------- required by a bound in this
+...
+LL | for<'a> <X as Trait<'a>>::Out: Copy
+ | ^^^^ required by this bound in `weird_bound`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr
index 0f2ff96b5..c48c84035 100644
--- a/src/test/ui/hygiene/no_implicit_prelude.stderr
+++ b/src/test/ui/hygiene/no_implicit_prelude.stderr
@@ -5,7 +5,7 @@ LL | fn f() { ::bar::m!(); }
| ----------- in this macro invocation
...
LL | Vec::new();
- | ^^^ not found in this scope
+ | ^^^ use of undeclared type `Vec`
|
= note: this error originates in the macro `::bar::m` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider importing this struct
diff --git a/src/test/ui/hygiene/panic-location.run.stderr b/src/test/ui/hygiene/panic-location.run.stderr
index 216b31586..0b23b1cc2 100644
--- a/src/test/ui/hygiene/panic-location.run.stderr
+++ b/src/test/ui/hygiene/panic-location.run.stderr
@@ -1,2 +1,2 @@
-thread 'main' panicked at 'capacity overflow', $SRC_DIR/alloc/src/collections/vec_deque/mod.rs:LL:COL
+thread 'main' panicked at 'capacity overflow', library/alloc/src/raw_vec.rs:518:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/src/test/ui/impl-trait/auto-trait.rs b/src/test/ui/impl-trait/auto-trait.rs
index afa95645a..35994e4a5 100644
--- a/src/test/ui/impl-trait/auto-trait.rs
+++ b/src/test/ui/impl-trait/auto-trait.rs
@@ -20,7 +20,6 @@ impl<T: Send> AnotherTrait for T {}
// in the future.)
impl AnotherTrait for D<OpaqueType> {
//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
- //~| ERROR cannot implement trait on type alias impl trait
}
fn main() {}
diff --git a/src/test/ui/impl-trait/auto-trait.stderr b/src/test/ui/impl-trait/auto-trait.stderr
index 5e10272b0..81009413c 100644
--- a/src/test/ui/impl-trait/auto-trait.stderr
+++ b/src/test/ui/impl-trait/auto-trait.stderr
@@ -7,18 +7,6 @@ LL | impl<T: Send> AnotherTrait for T {}
LL | impl AnotherTrait for D<OpaqueType> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
-error: cannot implement trait on type alias impl trait
- --> $DIR/auto-trait.rs:21:25
- |
-LL | impl AnotherTrait for D<OpaqueType> {
- | ^^^^^^^^^^
- |
-note: type alias impl trait defined here
- --> $DIR/auto-trait.rs:7:19
- |
-LL | type OpaqueType = impl OpaqueTrait;
- | ^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr
index bd8d3d3d2..a9fa2da56 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr
@@ -19,17 +19,20 @@ help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc
LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
| ++++++++++++
-error[E0760]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+error[E0658]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
--> $DIR/bound-normalization-fail.rs:41:41
|
LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #103532 <https://github.com/rust-lang/rust/issues/103532> for more information
+ = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable
-error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
+error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'a>>::Assoc`
--> $DIR/bound-normalization-fail.rs:41:41
|
LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'a>>::Assoc`
...
LL | Foo(())
| ------- return type was inferred to be `Foo<()>` here
@@ -40,13 +43,13 @@ note: expected this to be `()`
LL | type Output = T;
| ^
= note: expected unit type `()`
- found associated type `<T as lifetimes::Trait<'static>>::Assoc`
-help: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()`
+ found associated type `<T as lifetimes::Trait<'a>>::Assoc`
+help: consider constraining the associated type `<T as lifetimes::Trait<'a>>::Assoc` to `()`
|
LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
| ++++++++++++
error: aborting due to 3 previous errors
-Some errors have detailed explanations: E0271, E0760.
+Some errors have detailed explanations: E0271, E0658.
For more information about an error, try `rustc --explain E0271`.
diff --git a/src/test/ui/impl-trait/cross-return-site-inference.rs b/src/test/ui/impl-trait/cross-return-site-inference.rs
index d881af9ed..00aed2ad9 100644
--- a/src/test/ui/impl-trait/cross-return-site-inference.rs
+++ b/src/test/ui/impl-trait/cross-return-site-inference.rs
@@ -30,16 +30,19 @@ fn baa(b: bool) -> impl std::fmt::Debug {
fn muh() -> Result<(), impl std::fmt::Debug> {
Err("whoops")?;
- Ok(()) //~ ERROR type annotations needed
+ Ok(())
+ //~^ ERROR type annotations needed
}
fn muh2() -> Result<(), impl std::fmt::Debug> {
- return Err(From::from("foo")); //~ ERROR type annotations needed
+ return Err(From::from("foo"));
+ //~^ ERROR type annotations needed
Ok(())
}
fn muh3() -> Result<(), impl std::fmt::Debug> {
- Err(From::from("foo")) //~ ERROR type annotations needed
+ Err(From::from("foo"))
+ //~^ ERROR type annotations needed
}
fn main() {}
diff --git a/src/test/ui/impl-trait/cross-return-site-inference.stderr b/src/test/ui/impl-trait/cross-return-site-inference.stderr
index 1ff777e65..766614e9e 100644
--- a/src/test/ui/impl-trait/cross-return-site-inference.stderr
+++ b/src/test/ui/impl-trait/cross-return-site-inference.stderr
@@ -10,7 +10,7 @@ LL | Ok::<(), E>(())
| +++++++++
error[E0282]: type annotations needed
- --> $DIR/cross-return-site-inference.rs:37:12
+ --> $DIR/cross-return-site-inference.rs:38:12
|
LL | return Err(From::from("foo"));
| ^^^ cannot infer type of the type parameter `E` declared on the enum `Result`
@@ -21,7 +21,7 @@ LL | return Err::<(), E>(From::from("foo"));
| +++++++++
error[E0282]: type annotations needed
- --> $DIR/cross-return-site-inference.rs:42:5
+ --> $DIR/cross-return-site-inference.rs:44:5
|
LL | Err(From::from("foo"))
| ^^^ cannot infer type of the type parameter `E` declared on the enum `Result`
diff --git a/src/test/ui/impl-trait/deduce-signature-from-supertrait.rs b/src/test/ui/impl-trait/deduce-signature-from-supertrait.rs
new file mode 100644
index 000000000..d2c347920
--- /dev/null
+++ b/src/test/ui/impl-trait/deduce-signature-from-supertrait.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait SuperExpectation: Fn(i32) {}
+
+impl<T: Fn(i32)> SuperExpectation for T {}
+
+type Foo = impl SuperExpectation;
+
+fn main() {
+ let _: Foo = |x| {
+ let _ = x.to_string();
+ };
+}
diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr
index 1841b8e5d..69f4cbbbf 100644
--- a/src/test/ui/impl-trait/equality.stderr
+++ b/src/test/ui/impl-trait/equality.stderr
@@ -30,15 +30,10 @@ LL | n + sum_to(n - 1)
|
= help: the trait `Add<impl Foo>` is not implemented for `u32`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&'a u32 as Add<u32>>
+ <&u32 as Add<&u32>>
+ <u32 as Add<&u32>>
+ <u32 as Add>
error: aborting due to 2 previous errors; 1 warning emitted
diff --git a/src/test/ui/impl-trait/feature-self-return-type.rs b/src/test/ui/impl-trait/feature-self-return-type.rs
new file mode 100644
index 000000000..51877e9cc
--- /dev/null
+++ b/src/test/ui/impl-trait/feature-self-return-type.rs
@@ -0,0 +1,102 @@
+// edition:2018
+#![feature(impl_trait_projections)]
+
+// This test checks that we emit the correct borrowck error when `Self` or a projection is used as
+// a return type. See #61949 for context.
+
+mod with_self {
+ pub struct Foo<'a> {
+ pub bar: &'a i32,
+ }
+
+ impl<'a> Foo<'a> {
+ pub fn new(_bar: &'a i32) -> impl Into<Self> {
+ Foo {
+ bar: &22
+ }
+ }
+ }
+
+ fn foo() {
+ let x = {
+ let bar = 22;
+ Foo::new(&bar).into()
+ //~^ ERROR `bar` does not live long enough
+ };
+ drop(x);
+ }
+}
+
+struct Foo<T>(T);
+
+trait FooLike {
+ type Output;
+}
+
+impl<T> FooLike for Foo<T> {
+ type Output = T;
+}
+
+mod impl_trait {
+ use super::*;
+
+ trait Trait {
+ type Assoc;
+
+ fn make_assoc(self) -> Self::Assoc;
+ }
+
+ /// `T::Assoc` can't be normalized any further here.
+ fn foo<T: Trait>(x: T) -> impl FooLike<Output = T::Assoc> {
+ Foo(x.make_assoc())
+ }
+
+ impl<'a> Trait for &'a () {
+ type Assoc = &'a ();
+
+ fn make_assoc(self) -> &'a () { &() }
+ }
+
+ fn usage() {
+ let x = {
+ let y = ();
+ foo(&y)
+ //~^ ERROR `y` does not live long enough
+ };
+ drop(x);
+ }
+}
+
+// Same with lifetimes in the trait
+
+mod lifetimes {
+ use super::*;
+
+ trait Trait<'a> {
+ type Assoc;
+
+ fn make_assoc(self) -> Self::Assoc;
+ }
+
+ /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further.
+ fn foo<'a, T: Trait<'a>>(x: T) -> impl FooLike<Output = T::Assoc> {
+ Foo(x.make_assoc())
+ }
+
+ impl<'a> Trait<'a> for &'a () {
+ type Assoc = &'a ();
+
+ fn make_assoc(self) -> &'a () { &() }
+ }
+
+ fn usage() {
+ let x = {
+ let y = ();
+ foo(&y)
+ //~^ ERROR `y` does not live long enough
+ };
+ drop(x);
+ }
+}
+
+fn main() { }
diff --git a/src/test/ui/impl-trait/feature-self-return-type.stderr b/src/test/ui/impl-trait/feature-self-return-type.stderr
new file mode 100644
index 000000000..601e53b76
--- /dev/null
+++ b/src/test/ui/impl-trait/feature-self-return-type.stderr
@@ -0,0 +1,39 @@
+error[E0597]: `bar` does not live long enough
+ --> $DIR/feature-self-return-type.rs:23:22
+ |
+LL | let x = {
+ | - borrow later stored here
+LL | let bar = 22;
+LL | Foo::new(&bar).into()
+ | ^^^^ borrowed value does not live long enough
+LL |
+LL | };
+ | - `bar` dropped here while still borrowed
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/feature-self-return-type.rs:63:17
+ |
+LL | let x = {
+ | - borrow later stored here
+LL | let y = ();
+LL | foo(&y)
+ | ^^ borrowed value does not live long enough
+LL |
+LL | };
+ | - `y` dropped here while still borrowed
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/feature-self-return-type.rs:95:17
+ |
+LL | let x = {
+ | - borrow later stored here
+LL | let y = ();
+LL | foo(&y)
+ | ^^ borrowed value does not live long enough
+LL |
+LL | };
+ | - `y` dropped here while still borrowed
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
index 88e2520bf..30fbba168 100644
--- a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
+++ b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr
@@ -9,13 +9,6 @@ help: add `dyn` keyword before this trait
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
| +++
-error[E0277]: the trait bound `(): AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not satisfied
- --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:13
- |
-LL | fn ice() -> impl AsRef<Fn(&())> {
- | ^^^^^^^^^^^^^^^^^^^ the trait `AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not implemented for `()`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-Some errors have detailed explanations: E0277, E0782.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0782`.
diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs
index 5a922697f..bed81c4bc 100644
--- a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs
+++ b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs
@@ -4,8 +4,8 @@
#![allow(warnings)]
fn ice() -> impl AsRef<Fn(&())> {
- //~^ ERROR: the trait bound `(): AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not satisfied [E0277]
- //[edition2021]~| ERROR: trait objects must include the `dyn` keyword [E0782]
+ //[edition2015]~^ ERROR: the trait bound `(): AsRef<(dyn for<'a> Fn(&'a ()) + 'static)>` is not satisfied [E0277]
+ //[edition2021]~^^ ERROR: trait objects must include the `dyn` keyword [E0782]
todo!()
}
diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.rs b/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.rs
new file mode 100644
index 000000000..b0aeded0e
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.rs
@@ -0,0 +1,8 @@
+#![feature(impl_trait_in_fn_trait_return)]
+use std::fmt::Debug;
+
+fn a() -> impl Fn(&u8) -> impl Debug {
+ |x| x //~ ERROR hidden type for `impl Debug` captures lifetime that does not appear in bounds
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.stderr b/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.stderr
new file mode 100644
index 000000000..433b76b7a
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.stderr
@@ -0,0 +1,11 @@
+error[E0700]: hidden type for `impl Debug` captures lifetime that does not appear in bounds
+ --> $DIR/impl-fn-hrtb-bounds-2.rs:5:9
+ |
+LL | |x| x
+ | --- ^
+ | |
+ | hidden type `&u8` captures the anonymous lifetime #1 defined here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs
new file mode 100644
index 000000000..527a4586f
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs
@@ -0,0 +1,24 @@
+#![feature(impl_trait_in_fn_trait_return)]
+use std::fmt::Debug;
+
+fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
+ //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+ |x| x
+}
+
+fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
+ //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+ |x| x
+}
+
+fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
+ //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+ |x| x
+}
+
+fn d() -> impl Fn() -> (impl Debug + '_) {
+ //~^ ERROR missing lifetime specifier
+ || ()
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr
new file mode 100644
index 000000000..443ffeb55
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr
@@ -0,0 +1,51 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/impl-fn-hrtb-bounds.rs:19:38
+ |
+LL | fn d() -> impl Fn() -> (impl Debug + '_) {
+ | ^^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
+ | ~~~~~~~
+
+error: higher kinded lifetime bounds on nested opaque types are not supported yet
+ --> $DIR/impl-fn-hrtb-bounds.rs:4:41
+ |
+LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
+ | ^^
+ |
+note: lifetime declared here
+ --> $DIR/impl-fn-hrtb-bounds.rs:4:19
+ |
+LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
+ | ^
+
+error: higher kinded lifetime bounds on nested opaque types are not supported yet
+ --> $DIR/impl-fn-hrtb-bounds.rs:9:52
+ |
+LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
+ | ^^
+ |
+note: lifetime declared here
+ --> $DIR/impl-fn-hrtb-bounds.rs:9:20
+ |
+LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
+ | ^^
+
+error: higher kinded lifetime bounds on nested opaque types are not supported yet
+ --> $DIR/impl-fn-hrtb-bounds.rs:14:52
+ |
+LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
+ | ^^
+ |
+note: lifetime declared here
+ --> $DIR/impl-fn-hrtb-bounds.rs:14:20
+ |
+LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
+ | ^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs
new file mode 100644
index 000000000..61303a5b2
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs
@@ -0,0 +1,15 @@
+#![feature(impl_trait_in_fn_trait_return)]
+use std::fmt::Debug;
+
+fn a() -> impl Fn(&u8) -> impl Debug + '_ {
+ //~^ ERROR ambiguous `+` in a type
+ //~| ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
+ |x| x
+}
+
+fn b() -> impl Fn() -> impl Debug + Send {
+ //~^ ERROR ambiguous `+` in a type
+ || ()
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
new file mode 100644
index 000000000..cf6e5ef7b
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
@@ -0,0 +1,26 @@
+error: ambiguous `+` in a type
+ --> $DIR/impl-fn-parsing-ambiguities.rs:4:27
+ |
+LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
+ | ^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + '_)`
+
+error: ambiguous `+` in a type
+ --> $DIR/impl-fn-parsing-ambiguities.rs:10:24
+ |
+LL | fn b() -> impl Fn() -> impl Debug + Send {
+ | ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)`
+
+error: higher kinded lifetime bounds on nested opaque types are not supported yet
+ --> $DIR/impl-fn-parsing-ambiguities.rs:4:40
+ |
+LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
+ | ^^
+ |
+note: lifetime declared here
+ --> $DIR/impl-fn-parsing-ambiguities.rs:4:19
+ |
+LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
+ | ^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.rs
new file mode 100644
index 000000000..157786623
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.rs
@@ -0,0 +1,15 @@
+#![feature(impl_trait_in_fn_trait_return)]
+use std::fmt::Debug;
+
+fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
+ //~^ ERROR cannot resolve opaque type
+
+ |x| x
+ //~^ ERROR concrete type differs from previous defining opaque type use
+}
+
+fn _b<'a>() -> impl Fn(&'a u8) -> (impl Debug + 'a) {
+ a()
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
new file mode 100644
index 000000000..c19420bbb
--- /dev/null
+++ b/src/test/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
@@ -0,0 +1,21 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/impl-fn-predefined-lifetimes.rs:7:9
+ |
+LL | |x| x
+ | ^ expected `impl Debug + '_`, got `&u8`
+ |
+note: previous use here
+ --> $DIR/impl-fn-predefined-lifetimes.rs:7:5
+ |
+LL | |x| x
+ | ^^^^^
+
+error[E0720]: cannot resolve opaque type
+ --> $DIR/impl-fn-predefined-lifetimes.rs:4:35
+ |
+LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
+ | ^^^^^^^^^^^^^^^ cannot resolve opaque type
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/src/test/ui/impl-trait/impl_fn_associativity.rs b/src/test/ui/impl-trait/impl_fn_associativity.rs
new file mode 100644
index 000000000..71a8f9c77
--- /dev/null
+++ b/src/test/ui/impl-trait/impl_fn_associativity.rs
@@ -0,0 +1,26 @@
+// run-pass
+#![feature(impl_trait_in_fn_trait_return)]
+use std::fmt::Debug;
+
+fn f_debug() -> impl Fn() -> impl Debug {
+ || ()
+}
+
+fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug {
+ || f_debug()
+}
+
+fn multi() -> impl Fn() -> (impl Debug + Send) {
+ || ()
+}
+
+fn main() {
+ // Check that `ff_debug` is `() -> (() -> Debug)` and not `(() -> ()) -> Debug`
+ let debug = ff_debug()()();
+ assert_eq!(format!("{:?}", debug), "()");
+
+ let x = multi()();
+ assert_eq!(format!("{:?}", x), "()");
+ fn assert_send(_: &impl Send) {}
+ assert_send(&x);
+}
diff --git a/src/test/ui/impl-trait/in-trait/generics-mismatch.rs b/src/test/ui/impl-trait/in-trait/generics-mismatch.rs
new file mode 100644
index 000000000..cc0fc720e
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/generics-mismatch.rs
@@ -0,0 +1,17 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+struct U;
+
+trait Foo {
+ fn bar(&self) -> impl Sized;
+}
+
+impl Foo for U {
+ fn bar<T>(&self) {}
+ //~^ ERROR method `bar` has 1 type parameter but its trait declaration has 0 type parameters
+}
+
+fn main() {
+ U.bar();
+}
diff --git a/src/test/ui/impl-trait/in-trait/generics-mismatch.stderr b/src/test/ui/impl-trait/in-trait/generics-mismatch.stderr
new file mode 100644
index 000000000..cd42683e0
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/generics-mismatch.stderr
@@ -0,0 +1,12 @@
+error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters
+ --> $DIR/generics-mismatch.rs:11:12
+ |
+LL | fn bar(&self) -> impl Sized;
+ | - expected 0 type parameters
+...
+LL | fn bar<T>(&self) {}
+ | ^ found 1 type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0049`.
diff --git a/src/test/ui/impl-trait/in-trait/method-signature-matches.rs b/src/test/ui/impl-trait/in-trait/method-signature-matches.rs
new file mode 100644
index 000000000..c848ee3f6
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/method-signature-matches.rs
@@ -0,0 +1,51 @@
+// edition: 2021
+
+#![feature(return_position_impl_trait_in_trait, async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+trait Uwu {
+ fn owo(x: ()) -> impl Sized;
+}
+
+impl Uwu for () {
+ fn owo(_: u8) {}
+ //~^ ERROR method `owo` has an incompatible type for trait
+}
+
+trait AsyncUwu {
+ async fn owo(x: ()) {}
+}
+
+impl AsyncUwu for () {
+ async fn owo(_: u8) {}
+ //~^ ERROR method `owo` has an incompatible type for trait
+}
+
+trait TooMuch {
+ fn calm_down_please() -> impl Sized;
+}
+
+impl TooMuch for () {
+ fn calm_down_please(_: (), _: (), _: ()) {}
+ //~^ ERROR method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0
+}
+
+trait TooLittle {
+ fn come_on_a_little_more_effort(_: (), _: (), _: ()) -> impl Sized;
+}
+
+impl TooLittle for () {
+ fn come_on_a_little_more_effort() {}
+ //~^ ERROR method `come_on_a_little_more_effort` has 0 parameters but the declaration in trait `TooLittle::come_on_a_little_more_effort` has 3
+}
+
+trait Lifetimes {
+ fn early<'early, T>(x: &'early T) -> impl Sized;
+}
+
+impl Lifetimes for () {
+ fn early<'late, T>(_: &'late ()) {}
+ //~^ ERROR method `early` has an incompatible type for trait
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/method-signature-matches.stderr b/src/test/ui/impl-trait/in-trait/method-signature-matches.stderr
new file mode 100644
index 000000000..2b32c52c8
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/method-signature-matches.stderr
@@ -0,0 +1,84 @@
+error[E0053]: method `owo` has an incompatible type for trait
+ --> $DIR/method-signature-matches.rs:11:15
+ |
+LL | fn owo(_: u8) {}
+ | ^^
+ | |
+ | expected `()`, found `u8`
+ | help: change the parameter type to match the trait: `()`
+ |
+note: type in trait
+ --> $DIR/method-signature-matches.rs:7:15
+ |
+LL | fn owo(x: ()) -> impl Sized;
+ | ^^
+ = note: expected fn pointer `fn(())`
+ found fn pointer `fn(u8)`
+
+error[E0053]: method `owo` has an incompatible type for trait
+ --> $DIR/method-signature-matches.rs:20:21
+ |
+LL | async fn owo(_: u8) {}
+ | ^^
+ | |
+ | expected `()`, found `u8`
+ | help: change the parameter type to match the trait: `()`
+ |
+note: while checking the return type of the `async fn`
+ --> $DIR/method-signature-matches.rs:20:25
+ |
+LL | async fn owo(_: u8) {}
+ | ^ checked the `Output` of this `async fn`, expected opaque type
+note: while checking the return type of the `async fn`
+ --> $DIR/method-signature-matches.rs:20:25
+ |
+LL | async fn owo(_: u8) {}
+ | ^ checked the `Output` of this `async fn`, found opaque type
+note: type in trait
+ --> $DIR/method-signature-matches.rs:16:21
+ |
+LL | async fn owo(x: ()) {}
+ | ^^
+ = note: expected fn pointer `fn(()) -> _`
+ found fn pointer `fn(u8) -> _`
+
+error[E0050]: method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0
+ --> $DIR/method-signature-matches.rs:29:28
+ |
+LL | fn calm_down_please() -> impl Sized;
+ | ------------------------------------ trait requires 0 parameters
+...
+LL | fn calm_down_please(_: (), _: (), _: ()) {}
+ | ^^^^^^^^^^^^^^^^ expected 0 parameters, found 3
+
+error[E0050]: method `come_on_a_little_more_effort` has 0 parameters but the declaration in trait `TooLittle::come_on_a_little_more_effort` has 3
+ --> $DIR/method-signature-matches.rs:38:5
+ |
+LL | fn come_on_a_little_more_effort(_: (), _: (), _: ()) -> impl Sized;
+ | ---------------- trait requires 3 parameters
+...
+LL | fn come_on_a_little_more_effort() {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 3 parameters, found 0
+
+error[E0053]: method `early` has an incompatible type for trait
+ --> $DIR/method-signature-matches.rs:47:27
+ |
+LL | fn early<'late, T>(_: &'late ()) {}
+ | - ^^^^^^^^^
+ | | |
+ | | expected type parameter `T`, found `()`
+ | | help: change the parameter type to match the trait: `&'early T`
+ | this type parameter
+ |
+note: type in trait
+ --> $DIR/method-signature-matches.rs:43:28
+ |
+LL | fn early<'early, T>(x: &'early T) -> impl Sized;
+ | ^^^^^^^^^
+ = note: expected fn pointer `fn(&'early T)`
+ found fn pointer `fn(&())`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0050, E0053.
+For more information about an error, try `rustc --explain E0050`.
diff --git a/src/test/ui/impl-trait/in-trait/object-safety.stderr b/src/test/ui/impl-trait/in-trait/object-safety.stderr
index 9a1554b5e..ca0e760ff 100644
--- a/src/test/ui/impl-trait/in-trait/object-safety.stderr
+++ b/src/test/ui/impl-trait/in-trait/object-safety.stderr
@@ -5,12 +5,12 @@ LL | let i = Box::new(42_u32) as Box<dyn Foo>;
| ^^^^^^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/object-safety.rs:7:8
+ --> $DIR/object-safety.rs:7:22
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn baz(&self) -> impl Debug;
- | ^^^ ...because method `baz` references an `impl Trait` type in its return type
+ | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
error[E0038]: the trait `Foo` cannot be made into an object
@@ -20,12 +20,12 @@ LL | let s = i.baz();
| ^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/object-safety.rs:7:8
+ --> $DIR/object-safety.rs:7:22
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn baz(&self) -> impl Debug;
- | ^^^ ...because method `baz` references an `impl Trait` type in its return type
+ | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
error[E0038]: the trait `Foo` cannot be made into an object
@@ -35,12 +35,12 @@ LL | let i = Box::new(42_u32) as Box<dyn Foo>;
| ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
- --> $DIR/object-safety.rs:7:8
+ --> $DIR/object-safety.rs:7:22
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn baz(&self) -> impl Debug;
- | ^^^ ...because method `baz` references an `impl Trait` type in its return type
+ | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
= note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>`
= note: required by cast to type `Box<dyn Foo>`
diff --git a/src/test/ui/impl-trait/in-trait/specialization-broken.rs b/src/test/ui/impl-trait/in-trait/specialization-broken.rs
new file mode 100644
index 000000000..9d27d3710
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/specialization-broken.rs
@@ -0,0 +1,26 @@
+// FIXME(compiler-errors): I'm not exactly sure if this is expected to pass or not.
+// But we fixed an ICE anyways.
+
+#![feature(specialization)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Foo {
+ fn bar(&self) -> impl Sized;
+}
+
+default impl<U> Foo for U
+where
+ U: Copy,
+{
+ fn bar(&self) -> U {
+ //~^ ERROR method `bar` has an incompatible type for trait
+ *self
+ }
+}
+
+impl Foo for i32 {}
+
+fn main() {
+ 1i32.bar();
+}
diff --git a/src/test/ui/impl-trait/in-trait/specialization-broken.stderr b/src/test/ui/impl-trait/in-trait/specialization-broken.stderr
new file mode 100644
index 000000000..a30e6346b
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/specialization-broken.stderr
@@ -0,0 +1,23 @@
+error[E0053]: method `bar` has an incompatible type for trait
+ --> $DIR/specialization-broken.rs:16:22
+ |
+LL | default impl<U> Foo for U
+ | - this type parameter
+...
+LL | fn bar(&self) -> U {
+ | ^
+ | |
+ | expected associated type, found type parameter `U`
+ | help: change the output type to match the trait: `impl Sized`
+ |
+note: type in trait
+ --> $DIR/specialization-broken.rs:9:22
+ |
+LL | fn bar(&self) -> impl Sized;
+ | ^^^^^^^^^^
+ = note: expected fn pointer `fn(&U) -> impl Sized`
+ found fn pointer `fn(&U) -> U`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/src/test/ui/impl-trait/in-trait/specialization-substs-remap.rs b/src/test/ui/impl-trait/in-trait/specialization-substs-remap.rs
new file mode 100644
index 000000000..c9ee877db
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/specialization-substs-remap.rs
@@ -0,0 +1,24 @@
+// check-pass
+
+#![feature(specialization)]
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Foo {
+ fn bar(&self) -> impl Sized;
+}
+
+impl<U> Foo for U
+where
+ U: Copy,
+{
+ fn bar(&self) -> U {
+ *self
+ }
+}
+
+impl Foo for i32 {}
+
+fn main() {
+ let _: i32 = 1i32.bar();
+}
diff --git a/src/test/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs b/src/test/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs
new file mode 100644
index 000000000..0bbe50ea6
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs
@@ -0,0 +1,17 @@
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+struct S;
+
+trait Foo {
+ fn bar<T>() -> impl Sized;
+}
+
+impl Foo for S {
+ fn bar() -> impl Sized {}
+ //~^ ERROR method `bar` has 0 type parameters but its trait declaration has 1 type parameter
+}
+
+fn main() {
+ S::bar();
+}
diff --git a/src/test/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr b/src/test/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr
new file mode 100644
index 000000000..8ff54cad9
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr
@@ -0,0 +1,12 @@
+error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
+ --> $DIR/trait-more-generics-than-impl.rs:11:11
+ |
+LL | fn bar<T>() -> impl Sized;
+ | - expected 1 type parameter
+...
+LL | fn bar() -> impl Sized {}
+ | ^ found 0 type parameters
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0049`.
diff --git a/src/test/ui/impl-trait/in-trait/where-clause.rs b/src/test/ui/impl-trait/in-trait/where-clause.rs
new file mode 100644
index 000000000..87bac519c
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/where-clause.rs
@@ -0,0 +1,24 @@
+// check-pass
+// edition: 2021
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
+
+trait Foo<Item> {
+ fn foo<'a>(&'a self) -> impl Debug
+ where
+ Item: 'a;
+}
+
+impl<Item, D: Debug + Clone> Foo<Item> for D {
+ fn foo<'a>(&'a self) -> impl Debug
+ where
+ Item: 'a,
+ {
+ self.clone()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-35668.rs b/src/test/ui/impl-trait/issue-35668.rs
index c970163fc..c970163fc 100644
--- a/src/test/ui/issues/issue-35668.rs
+++ b/src/test/ui/impl-trait/issue-35668.rs
diff --git a/src/test/ui/issues/issue-35668.stderr b/src/test/ui/impl-trait/issue-35668.stderr
index 84add5799..84add5799 100644
--- a/src/test/ui/issues/issue-35668.stderr
+++ b/src/test/ui/impl-trait/issue-35668.stderr
diff --git a/src/test/ui/issues/issue-49556.rs b/src/test/ui/impl-trait/issue-49556.rs
index c8c172f0e..c8c172f0e 100644
--- a/src/test/ui/issues/issue-49556.rs
+++ b/src/test/ui/impl-trait/issue-49556.rs
diff --git a/src/test/ui/impl-trait/issue-55872-3.rs b/src/test/ui/impl-trait/issue-55872-3.rs
index 3ffce85e6..91811df93 100644
--- a/src/test/ui/impl-trait/issue-55872-3.rs
+++ b/src/test/ui/impl-trait/issue-55872-3.rs
@@ -12,7 +12,7 @@ pub trait Bar {
impl<S> Bar for S {
type E = impl std::marker::Copy;
fn foo<T>() -> Self::E {
- //~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied [E0277]
+ //~^ ERROR : Copy` is not satisfied [E0277]
async {}
}
}
diff --git a/src/test/ui/impl-trait/issue-55872-3.stderr b/src/test/ui/impl-trait/issue-55872-3.stderr
index 6ab540e87..c6e10f0f3 100644
--- a/src/test/ui/impl-trait/issue-55872-3.stderr
+++ b/src/test/ui/impl-trait/issue-55872-3.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `impl Future<Output = ()>: Copy` is not satisfied
+error[E0277]: the trait bound `[async block@$DIR/issue-55872-3.rs:16:9: 16:17]: Copy` is not satisfied
--> $DIR/issue-55872-3.rs:14:20
|
LL | fn foo<T>() -> Self::E {
- | ^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = ()>`
+ | ^^^^^^^ the trait `Copy` is not implemented for `[async block@$DIR/issue-55872-3.rs:16:9: 16:17]`
error: aborting due to previous error
diff --git a/src/test/ui/impl-trait/issues/issue-104815.rs b/src/test/ui/impl-trait/issues/issue-104815.rs
new file mode 100644
index 000000000..7a9826a8d
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-104815.rs
@@ -0,0 +1,66 @@
+// check-pass
+
+struct It;
+
+struct Data {
+ items: Vec<It>,
+}
+
+impl Data {
+ fn new() -> Self {
+ Self {
+ items: vec![It, It],
+ }
+ }
+
+ fn content(&self) -> impl Iterator<Item = &It> {
+ self.items.iter()
+ }
+}
+
+struct Container<'a> {
+ name: String,
+ resolver: Box<dyn Resolver + 'a>,
+}
+
+impl<'a> Container<'a> {
+ fn new<R: Resolver + 'a>(name: &str, resolver: R) -> Self {
+ Self {
+ name: name.to_owned(),
+ resolver: Box::new(resolver),
+ }
+ }
+}
+
+trait Resolver {}
+
+impl<R: Resolver> Resolver for &R {}
+
+impl Resolver for It {}
+
+fn get<'a>(mut items: impl Iterator<Item = &'a It>) -> impl Resolver + 'a {
+ items.next().unwrap()
+}
+
+fn get2<'a, 'b: 'b>(mut items: impl Iterator<Item = &'a It>) -> impl Resolver + 'a {
+ items.next().unwrap()
+}
+
+fn main() {
+ let data = Data::new();
+ let resolver = get(data.content());
+
+ let _ = ["a", "b"]
+ .iter()
+ .map(|&n| Container::new(n, &resolver))
+ .map(|c| c.name)
+ .collect::<Vec<_>>();
+
+ let resolver = get2(data.content());
+
+ let _ = ["a", "b"]
+ .iter()
+ .map(|&n| Container::new(n, &resolver))
+ .map(|c| c.name)
+ .collect::<Vec<_>>();
+}
diff --git a/src/test/ui/impl-trait/issues/issue-105826.rs b/src/test/ui/impl-trait/issues/issue-105826.rs
new file mode 100644
index 000000000..06dc2d4c8
--- /dev/null
+++ b/src/test/ui/impl-trait/issues/issue-105826.rs
@@ -0,0 +1,39 @@
+// check-pass
+
+use std::io::Write;
+
+struct A(Vec<u8>);
+
+struct B<'a> {
+ one: &'a mut A,
+ two: &'a mut Vec<u8>,
+ three: Vec<u8>,
+}
+
+impl<'a> B<'a> {
+ fn one(&mut self) -> &mut impl Write {
+ &mut self.one.0
+ }
+ fn two(&mut self) -> &mut impl Write {
+ &mut *self.two
+ }
+ fn three(&mut self) -> &mut impl Write {
+ &mut self.three
+ }
+}
+
+struct C<'a>(B<'a>);
+
+impl<'a> C<'a> {
+ fn one(&mut self) -> &mut impl Write {
+ self.0.one()
+ }
+ fn two(&mut self) -> &mut impl Write {
+ self.0.two()
+ }
+ fn three(&mut self) -> &mut impl Write {
+ self.0.three()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/issues/issue-78722.rs b/src/test/ui/impl-trait/issues/issue-78722.rs
index 9ee1ba3d3..78233f300 100644
--- a/src/test/ui/impl-trait/issues/issue-78722.rs
+++ b/src/test/ui/impl-trait/issues/issue-78722.rs
@@ -7,7 +7,7 @@ type F = impl core::future::Future<Output = u8>;
struct Bug {
V1: [(); {
fn concrete_use() -> F {
- //~^ ERROR expected `impl Future<Output = ()>` to be a future that resolves to `u8`, but it resolves to `()`
+ //~^ ERROR to be a future that resolves to `u8`, but it resolves to `()`
async {}
}
let f: F = async { 1 };
diff --git a/src/test/ui/impl-trait/issues/issue-78722.stderr b/src/test/ui/impl-trait/issues/issue-78722.stderr
index a96994f5a..c00df8087 100644
--- a/src/test/ui/impl-trait/issues/issue-78722.stderr
+++ b/src/test/ui/impl-trait/issues/issue-78722.stderr
@@ -16,7 +16,7 @@ LL | let f: F = async { 1 };
LL | }],
| - value is dropped here
-error[E0271]: expected `impl Future<Output = ()>` to be a future that resolves to `u8`, but it resolves to `()`
+error[E0271]: expected `[async block@$DIR/issue-78722.rs:11:13: 11:21]` to be a future that resolves to `u8`, but it resolves to `()`
--> $DIR/issue-78722.rs:9:30
|
LL | fn concrete_use() -> F {
diff --git a/src/test/ui/impl-trait/issues/issue-92305.rs b/src/test/ui/impl-trait/issues/issue-92305.rs
index 1518c116b..4a89238d0 100644
--- a/src/test/ui/impl-trait/issues/issue-92305.rs
+++ b/src/test/ui/impl-trait/issues/issue-92305.rs
@@ -4,11 +4,10 @@ use std::iter;
fn f<T>(data: &[T]) -> impl Iterator<Item = Vec> {
//~^ ERROR: missing generics for struct `Vec` [E0107]
- iter::empty() //~ ERROR: type annotations needed [E0282]
+ iter::empty()
}
fn g<T>(data: &[T], target: T) -> impl Iterator<Item = Vec<T>> {
- //~^ ERROR: type annotations needed [E0282]
f(data).filter(|x| x == target)
}
diff --git a/src/test/ui/impl-trait/issues/issue-92305.stderr b/src/test/ui/impl-trait/issues/issue-92305.stderr
index e8575b76b..34d5c2d61 100644
--- a/src/test/ui/impl-trait/issues/issue-92305.stderr
+++ b/src/test/ui/impl-trait/issues/issue-92305.stderr
@@ -14,24 +14,6 @@ help: add missing generic argument
LL | fn f<T>(data: &[T]) -> impl Iterator<Item = Vec<T>> {
| ~~~~~~
-error[E0282]: type annotations needed
- --> $DIR/issue-92305.rs:7:5
- |
-LL | iter::empty()
- | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
- |
-help: consider specifying the generic argument
- |
-LL | iter::empty::<T>()
- | +++++
-
-error[E0282]: type annotations needed
- --> $DIR/issue-92305.rs:10:35
- |
-LL | fn g<T>(data: &[T], target: T) -> impl Iterator<Item = Vec<T>> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
-Some errors have detailed explanations: E0107, E0282.
-For more information about an error, try `rustc --explain E0107`.
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/impl-trait/negative-reasoning.rs b/src/test/ui/impl-trait/negative-reasoning.rs
index da69bb349..70e24a3a9 100644
--- a/src/test/ui/impl-trait/negative-reasoning.rs
+++ b/src/test/ui/impl-trait/negative-reasoning.rs
@@ -18,7 +18,6 @@ impl<T: std::fmt::Debug> AnotherTrait for T {}
// This is in error, because we cannot assume that `OpaqueType: !Debug`
impl AnotherTrait for D<OpaqueType> {
//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
- //~| ERROR cannot implement trait on type alias impl trait
}
fn main() {}
diff --git a/src/test/ui/impl-trait/negative-reasoning.stderr b/src/test/ui/impl-trait/negative-reasoning.stderr
index 479b45185..6b8cc9e73 100644
--- a/src/test/ui/impl-trait/negative-reasoning.stderr
+++ b/src/test/ui/impl-trait/negative-reasoning.stderr
@@ -9,18 +9,6 @@ LL | impl AnotherTrait for D<OpaqueType> {
|
= note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
-error: cannot implement trait on type alias impl trait
- --> $DIR/negative-reasoning.rs:19:25
- |
-LL | impl AnotherTrait for D<OpaqueType> {
- | ^^^^^^^^^^
- |
-note: type alias impl trait defined here
- --> $DIR/negative-reasoning.rs:7:19
- |
-LL | type OpaqueType = impl OpaqueTrait;
- | ^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/impl-trait/nested-return-type4.rs b/src/test/ui/impl-trait/nested-return-type4.rs
new file mode 100644
index 000000000..cec70bb1a
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-return-type4.rs
@@ -0,0 +1,8 @@
+// edition: 2021
+
+fn test<'s: 's>(s: &'s str) -> impl std::future::Future<Output = impl Sized> {
+ async move { let _s = s; }
+ //~^ ERROR hidden type for `impl Future<Output = impl Sized>` captures lifetime that does not appear in bounds
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/nested-return-type4.stderr b/src/test/ui/impl-trait/nested-return-type4.stderr
new file mode 100644
index 000000000..e761a60e7
--- /dev/null
+++ b/src/test/ui/impl-trait/nested-return-type4.stderr
@@ -0,0 +1,20 @@
+error[E0700]: hidden type for `impl Future<Output = impl Sized>` captures lifetime that does not appear in bounds
+ --> $DIR/nested-return-type4.rs:4:5
+ |
+LL | fn test<'s: 's>(s: &'s str) -> impl std::future::Future<Output = impl Sized> {
+ | -- hidden type `[async block@$DIR/nested-return-type4.rs:4:5: 4:31]` captures the lifetime `'s` as defined here
+LL | async move { let _s = s; }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: to declare that `impl Future<Output = impl Sized>` captures `'s`, you can add an explicit `'s` lifetime bound
+ |
+LL | fn test<'s: 's>(s: &'s str) -> impl std::future::Future<Output = impl Sized> + 's {
+ | ++++
+help: to declare that `impl Sized` captures `'s`, you can add an explicit `'s` lifetime bound
+ |
+LL | fn test<'s: 's>(s: &'s str) -> impl std::future::Future<Output = impl Sized + 's> {
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/impl-trait/nested-rpit-hrtb.rs b/src/test/ui/impl-trait/nested-rpit-hrtb.rs
index abf6a7e95..a5db10d3a 100644
--- a/src/test/ui/impl-trait/nested-rpit-hrtb.rs
+++ b/src/test/ui/impl-trait/nested-rpit-hrtb.rs
@@ -35,26 +35,26 @@ fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {}
fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
-// This should pass.
+// This should resolve.
fn one_hrtb_mention_fn_trait_param<'b>() -> impl for<'a> Foo<'a, Assoc = impl Qux<'b>> {}
-// This should pass.
+// This should resolve.
fn one_hrtb_mention_fn_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'b> {}
-// This should pass.
+// This should resolve.
fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {}
-// This should pass.
+// This should resolve.
fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {}
-// This should pass.
+// This should resolve.
fn two_htrb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Qux<'b>> {}
// `'b` is not in scope for the outlives bound.
fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {}
//~^ ERROR use of undeclared lifetime name `'b` [E0261]
-// This should pass.
+// This should resolve.
fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {}
// `'b` is not in scope for the outlives bound.
diff --git a/src/test/ui/impl-trait/nested_impl_trait.rs b/src/test/ui/impl-trait/nested_impl_trait.rs
index 85c6f8c46..e95fab3b6 100644
--- a/src/test/ui/impl-trait/nested_impl_trait.rs
+++ b/src/test/ui/impl-trait/nested_impl_trait.rs
@@ -1,3 +1,4 @@
+#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;
fn fine(x: impl Into<u32>) -> impl Into<u32> { x }
@@ -25,8 +26,7 @@ fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {
}
fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
-//~^ `impl Trait` only allowed in function and inherent method return types
- || 5
+ || 5u8
}
fn main() {}
diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr
index 3291cad68..9a8f5a340 100644
--- a/src/test/ui/impl-trait/nested_impl_trait.stderr
+++ b/src/test/ui/impl-trait/nested_impl_trait.stderr
@@ -1,5 +1,5 @@
error[E0666]: nested `impl Trait` is not allowed
- --> $DIR/nested_impl_trait.rs:5:56
+ --> $DIR/nested_impl_trait.rs:6:56
|
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ----------^^^^^^^^^^-
@@ -8,7 +8,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| outer `impl Trait`
error[E0666]: nested `impl Trait` is not allowed
- --> $DIR/nested_impl_trait.rs:9:42
+ --> $DIR/nested_impl_trait.rs:10:42
|
LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| ----------^^^^^^^^^^-
@@ -17,7 +17,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| outer `impl Trait`
error[E0666]: nested `impl Trait` is not allowed
- --> $DIR/nested_impl_trait.rs:13:37
+ --> $DIR/nested_impl_trait.rs:14:37
|
LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
| ----------^^^^^^^^^^-
@@ -26,7 +26,7 @@ LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
| outer `impl Trait`
error[E0666]: nested `impl Trait` is not allowed
- --> $DIR/nested_impl_trait.rs:18:44
+ --> $DIR/nested_impl_trait.rs:19:44
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ----------^^^^^^^^^^-
@@ -35,19 +35,13 @@ LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| outer `impl Trait`
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
- --> $DIR/nested_impl_trait.rs:9:32
+ --> $DIR/nested_impl_trait.rs:10:32
|
LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| ^^^^^^^^^^^^^^^^^^^^^
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
- --> $DIR/nested_impl_trait.rs:27:42
- |
-LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
- | ^^^^^^^^^^^^^^
-
error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
- --> $DIR/nested_impl_trait.rs:5:46
+ --> $DIR/nested_impl_trait.rs:6:46
|
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
@@ -56,7 +50,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
- --> $DIR/nested_impl_trait.rs:18:34
+ --> $DIR/nested_impl_trait.rs:19:34
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
@@ -64,7 +58,7 @@ LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
= help: the trait `Into<U>` is implemented for `T`
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
-error: aborting due to 8 previous errors
+error: aborting due to 7 previous errors
Some errors have detailed explanations: E0277, E0562, E0666.
For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
index 621c4ea6e..af9dfe25b 100644
--- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
+++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
@@ -5,13 +5,13 @@ type Foo = impl PartialEq<(Foo, i32)>;
struct Bar;
impl PartialEq<(Foo, i32)> for Bar {
-//~^ ERROR cannot implement trait on type alias impl trait
fn eq(&self, _other: &(Foo, i32)) -> bool {
true
}
}
fn foo() -> Foo {
+ //~^ ERROR can't compare `Bar` with `(Bar, i32)`
Bar
}
diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr
index 2ef1697ba..7b63a3d0b 100644
--- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr
+++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.stderr
@@ -1,14 +1,15 @@
-error: cannot implement trait on type alias impl trait
- --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:7:17
+error[E0277]: can't compare `Bar` with `(Bar, i32)`
+ --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:13:13
|
-LL | impl PartialEq<(Foo, i32)> for Bar {
- | ^^^
+LL | fn foo() -> Foo {
+ | ^^^ no implementation for `Bar == (Bar, i32)`
+LL |
+LL | Bar
+ | --- return type was inferred to be `Bar` here
|
-note: type alias impl trait defined here
- --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:3:12
- |
-LL | type Foo = impl PartialEq<(Foo, i32)>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = help: the trait `PartialEq<(Bar, i32)>` is not implemented for `Bar`
+ = help: the trait `PartialEq<(Foo, i32)>` is implemented for `Bar`
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
index df7966f00..91f1ed481 100644
--- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
+++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs
@@ -2,11 +2,13 @@
mod a {
type Foo = impl PartialEq<(Foo, i32)>;
+ //~^ ERROR: unconstrained opaque type
struct Bar;
impl PartialEq<(Bar, i32)> for Bar {
fn eq(&self, _other: &(Foo, i32)) -> bool {
+ //~^ ERROR: `eq` has an incompatible type for trait
true
}
}
@@ -14,12 +16,13 @@ mod a {
mod b {
type Foo = impl PartialEq<(Foo, i32)>;
+ //~^ ERROR: unconstrained opaque type
struct Bar;
impl PartialEq<(Foo, i32)> for Bar {
- //~^ ERROR cannot implement trait on type alias impl trait
fn eq(&self, _other: &(Bar, i32)) -> bool {
+ //~^ ERROR: `eq` has an incompatible type for trait
true
}
}
diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index 6cd63dcf8..3dda5761a 100644
--- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -1,14 +1,49 @@
-error: cannot implement trait on type alias impl trait
- --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:20:21
+error: unconstrained opaque type
+ --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
-LL | impl PartialEq<(Foo, i32)> for Bar {
- | ^^^
+LL | type Foo = impl PartialEq<(Foo, i32)>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `Foo` must be used in combination with a concrete type within the same module
+
+error[E0053]: method `eq` has an incompatible type for trait
+ --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:30
+ |
+LL | type Foo = impl PartialEq<(Foo, i32)>;
+ | -------------------------- the found opaque type
+...
+LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
+ | ^^^^^^^^^^^
+ | |
+ | expected struct `a::Bar`, found opaque type
+ | help: change the parameter type to match the trait: `&(a::Bar, i32)`
|
-note: type alias impl trait defined here
- --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:16:16
+ = note: expected fn pointer `fn(&a::Bar, &(a::Bar, i32)) -> _`
+ found fn pointer `fn(&a::Bar, &(a::Foo, i32)) -> _`
+
+error: unconstrained opaque type
+ --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `Foo` must be used in combination with a concrete type within the same module
+
+error[E0053]: method `eq` has an incompatible type for trait
+ --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:30
+ |
+LL | type Foo = impl PartialEq<(Foo, i32)>;
+ | -------------------------- the expected opaque type
+...
+LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
+ | ^^^^^^^^^^^
+ | |
+ | expected opaque type, found struct `b::Bar`
+ | help: change the parameter type to match the trait: `&(b::Foo, i32)`
+ |
+ = note: expected fn pointer `fn(&b::Bar, &(b::Foo, i32)) -> _`
+ found fn pointer `fn(&b::Bar, &(b::Bar, i32)) -> _`
-error: aborting due to previous error
+error: aborting due to 4 previous errors
+For more information about this error, try `rustc --explain E0053`.
diff --git a/src/test/ui/impl-trait/where-allowed.rs b/src/test/ui/impl-trait/where-allowed.rs
index c1dd46c7f..ff63b04c2 100644
--- a/src/test/ui/impl-trait/where-allowed.rs
+++ b/src/test/ui/impl-trait/where-allowed.rs
@@ -1,5 +1,6 @@
//! A simple test for testing many permutations of allowedness of
//! impl Trait
+#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;
// Allowed
@@ -39,9 +40,8 @@ fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
//~^ ERROR `impl Trait` only allowed in function and inherent method return types
-// Disallowed
+// Allowed
fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` only allowed in function and inherent method return types
// Disallowed
fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
@@ -57,9 +57,8 @@ fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
//~^ ERROR `impl Trait` only allowed in function and inherent method return types
//~| ERROR nested `impl Trait` is not allowed
-// Disallowed
+// Allowed
fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` only allowed in function and inherent method return types
// Disallowed
fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr
index 2e7c7ca40..3ad0a9f9d 100644
--- a/src/test/ui/impl-trait/where-allowed.stderr
+++ b/src/test/ui/impl-trait/where-allowed.stderr
@@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
| outer `impl Trait`
error[E0658]: `impl Trait` in type aliases is unstable
- --> $DIR/where-allowed.rs:119:16
+ --> $DIR/where-allowed.rs:118:16
|
LL | type Out = impl Debug;
| ^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | type Out = impl Debug;
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
error[E0658]: `impl Trait` in type aliases is unstable
- --> $DIR/where-allowed.rs:154:23
+ --> $DIR/where-allowed.rs:153:23
|
LL | type InTypeAlias<R> = impl Debug;
| ^^^^^^^^^^
@@ -35,7 +35,7 @@ LL | type InTypeAlias<R> = impl Debug;
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
error[E0658]: `impl Trait` in type aliases is unstable
- --> $DIR/where-allowed.rs:157:39
+ --> $DIR/where-allowed.rs:156:39
|
LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
| ^^^^^^^^^^
@@ -44,53 +44,47 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param
- --> $DIR/where-allowed.rs:15:40
+ --> $DIR/where-allowed.rs:16:40
|
LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
- --> $DIR/where-allowed.rs:19:42
+ --> $DIR/where-allowed.rs:20:42
|
LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param
- --> $DIR/where-allowed.rs:23:38
+ --> $DIR/where-allowed.rs:24:38
|
LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
- --> $DIR/where-allowed.rs:27:40
+ --> $DIR/where-allowed.rs:28:40
|
LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
- --> $DIR/where-allowed.rs:31:49
+ --> $DIR/where-allowed.rs:32:49
|
LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
- --> $DIR/where-allowed.rs:35:51
+ --> $DIR/where-allowed.rs:36:51
|
LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
- --> $DIR/where-allowed.rs:39:55
+ --> $DIR/where-allowed.rs:40:55
|
LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
- --> $DIR/where-allowed.rs:43:57
- |
-LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
- | ^^^^^^^^^^
-
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
--> $DIR/where-allowed.rs:47:51
|
@@ -109,56 +103,50 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t
LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
- --> $DIR/where-allowed.rs:61:59
- |
-LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
- | ^^^^^^^^^^
-
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
- --> $DIR/where-allowed.rs:65:38
+ --> $DIR/where-allowed.rs:64:38
|
LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
- --> $DIR/where-allowed.rs:69:40
+ --> $DIR/where-allowed.rs:68:40
|
LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:82:32
+ --> $DIR/where-allowed.rs:81:32
|
LL | struct InBraceStructField { x: impl Debug }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in path
- --> $DIR/where-allowed.rs:86:41
+ --> $DIR/where-allowed.rs:85:41
|
LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:90:27
+ --> $DIR/where-allowed.rs:89:27
|
LL | struct InTupleStructField(impl Debug);
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:95:25
+ --> $DIR/where-allowed.rs:94:25
|
LL | InBraceVariant { x: impl Debug },
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:97:20
+ --> $DIR/where-allowed.rs:96:20
|
LL | InTupleVariant(impl Debug),
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
- --> $DIR/where-allowed.rs:108:23
+ --> $DIR/where-allowed.rs:107:23
|
LL | fn in_return() -> impl Debug;
| ^^^^^^^^^^
@@ -167,7 +155,7 @@ LL | fn in_return() -> impl Debug;
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return
- --> $DIR/where-allowed.rs:125:34
+ --> $DIR/where-allowed.rs:124:34
|
LL | fn in_trait_impl_return() -> impl Debug { () }
| ^^^^^^^^^^
@@ -176,127 +164,127 @@ LL | fn in_trait_impl_return() -> impl Debug { () }
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` param
- --> $DIR/where-allowed.rs:138:33
+ --> $DIR/where-allowed.rs:137:33
|
LL | fn in_foreign_parameters(_: impl Debug);
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return
- --> $DIR/where-allowed.rs:141:31
+ --> $DIR/where-allowed.rs:140:31
|
LL | fn in_foreign_return() -> impl Debug;
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
- --> $DIR/where-allowed.rs:157:39
+ --> $DIR/where-allowed.rs:156:39
|
LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait
- --> $DIR/where-allowed.rs:162:16
+ --> $DIR/where-allowed.rs:161:16
|
LL | impl PartialEq<impl Debug> for () {
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:167:24
+ --> $DIR/where-allowed.rs:166:24
|
LL | impl PartialEq<()> for impl Debug {
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:172:6
+ --> $DIR/where-allowed.rs:171:6
|
LL | impl impl Debug {
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:178:24
+ --> $DIR/where-allowed.rs:177:24
|
LL | impl InInherentImplAdt<impl Debug> {
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:184:11
+ --> $DIR/where-allowed.rs:183:11
|
LL | where impl Debug: Debug
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:191:15
+ --> $DIR/where-allowed.rs:190:15
|
LL | where Vec<impl Debug>: Debug
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound
- --> $DIR/where-allowed.rs:198:24
+ --> $DIR/where-allowed.rs:197:24
|
LL | where T: PartialEq<impl Debug>
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
- --> $DIR/where-allowed.rs:205:17
+ --> $DIR/where-allowed.rs:204:17
|
LL | where T: Fn(impl Debug)
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
- --> $DIR/where-allowed.rs:212:22
+ --> $DIR/where-allowed.rs:211:22
|
LL | where T: Fn() -> impl Debug
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:218:40
+ --> $DIR/where-allowed.rs:217:40
|
LL | struct InStructGenericParamDefault<T = impl Debug>(T);
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:222:36
+ --> $DIR/where-allowed.rs:221:36
|
LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:226:38
+ --> $DIR/where-allowed.rs:225:38
|
LL | trait InTraitGenericParamDefault<T = impl Debug> {}
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:230:41
+ --> $DIR/where-allowed.rs:229:41
|
LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:234:11
+ --> $DIR/where-allowed.rs:233:11
|
LL | impl <T = impl Debug> T {}
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
- --> $DIR/where-allowed.rs:241:40
+ --> $DIR/where-allowed.rs:240:40
|
LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
| ^^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
- --> $DIR/where-allowed.rs:247:29
+ --> $DIR/where-allowed.rs:246:29
|
LL | let _in_local_variable: impl Fn() = || {};
| ^^^^^^^^^
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return
- --> $DIR/where-allowed.rs:249:46
+ --> $DIR/where-allowed.rs:248:46
|
LL | let _in_return_in_local_variable = || -> impl Fn() { || {} };
| ^^^^^^^^^
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
- --> $DIR/where-allowed.rs:234:7
+ --> $DIR/where-allowed.rs:233:7
|
LL | impl <T = impl Debug> T {}
| ^^^^^^^^^^^^^^
@@ -306,7 +294,7 @@ LL | impl <T = impl Debug> T {}
= note: `#[deny(invalid_type_param_default)]` on by default
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
- --> $DIR/where-allowed.rs:241:36
+ --> $DIR/where-allowed.rs:240:36
|
LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
| ^^^^^^^^^^^^^^
@@ -315,14 +303,14 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
error[E0118]: no nominal type found for inherent implementation
- --> $DIR/where-allowed.rs:234:23
+ --> $DIR/where-allowed.rs:233:23
|
LL | impl <T = impl Debug> T {}
| ^ impl requires a nominal type
|
= note: either implement a trait on it or create a newtype to wrap it instead
-error: aborting due to 49 previous errors
+error: aborting due to 47 previous errors
Some errors have detailed explanations: E0118, E0562, E0658, E0666.
For more information about an error, try `rustc --explain E0118`.
diff --git a/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs b/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
index d9de73a38..79844dcbd 100644
--- a/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
+++ b/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
@@ -31,6 +31,16 @@ fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T {
sadness.cast()
}
+fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) {
+ //~^ ERROR lifetime mismatch
+ let _: &'out T = sadness.cast();
+}
+
+fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: &'in_ T) {
+ //~^ ERROR lifetime mismatch
+ let _: &'out T = sadness.cast();
+}
+
fn bad<'short, T>(value: &'short T) -> &'static T {
let x: for<'in_, 'out> fn(Foo<'in_, 'out, T>, &'in_ T) -> &'out T = badboi;
let x: for<'out> fn(Foo<'short, 'out, T>, &'short T) -> &'out T = x;
diff --git a/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr b/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr
index b020ea64b..0c00bbc38 100644
--- a/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr
+++ b/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.stderr
@@ -7,6 +7,24 @@ LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out
| this parameter and the return type are declared with different lifetimes...
| ...but data from `x` is returned here
-error: aborting due to previous error
+error[E0623]: lifetime mismatch
+ --> $DIR/hrlt-implied-trait-bounds-guard.rs:34:30
+ |
+LL | fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) {
+ | ^^^^^^^^^^^^^^^^^^
+ | |
+ | this type is declared with multiple lifetimes...
+ | ...but data with one lifetime flows into the other here
+
+error[E0623]: lifetime mismatch
+ --> $DIR/hrlt-implied-trait-bounds-guard.rs:39:30
+ |
+LL | fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: &'in_ T) {
+ | ^^^^^^^^^^^^^^^^^-------^^-------^^
+ | | |
+ | | these two types are declared with different lifetimes...
+ | ...but data from `a` flows into `a` here
+
+error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0623`.
diff --git a/src/test/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs b/src/test/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
new file mode 100644
index 000000000..6ccbb5bb2
--- /dev/null
+++ b/src/test/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
@@ -0,0 +1,22 @@
+#![deny(implied_bounds_entailment)]
+
+trait Project {
+ type Ty;
+}
+impl Project for &'_ &'_ () {
+ type Ty = ();
+}
+trait Trait {
+ fn get<'s>(s: &'s str, _: ()) -> &'static str;
+}
+impl Trait for () {
+ fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
+ //~^ ERROR impl method assumes more implied bounds than the corresponding trait method
+ //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ s
+ }
+}
+fn main() {
+ let val = <() as Trait>::get(&String::from("blah blah blah"), ());
+ println!("{}", val);
+}
diff --git a/src/test/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr b/src/test/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
new file mode 100644
index 000000000..0ac31c642
--- /dev/null
+++ b/src/test/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
@@ -0,0 +1,16 @@
+error: impl method assumes more implied bounds than the corresponding trait method
+ --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:5
+ |
+LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572>
+note: the lint level is defined here
+ --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9
+ |
+LL | #![deny(implied_bounds_entailment)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/implied-bounds/impl-implied-bounds-compatibility.rs b/src/test/ui/implied-bounds/impl-implied-bounds-compatibility.rs
new file mode 100644
index 000000000..d097bc16a
--- /dev/null
+++ b/src/test/ui/implied-bounds/impl-implied-bounds-compatibility.rs
@@ -0,0 +1,21 @@
+#![deny(implied_bounds_entailment)]
+
+use std::cell::RefCell;
+
+pub struct MessageListeners<'a> {
+ listeners: RefCell<Vec<Box<dyn FnMut(()) + 'a>>>,
+}
+
+pub trait MessageListenersInterface {
+ fn listeners<'c>(&'c self) -> &'c MessageListeners<'c>;
+}
+
+impl<'a> MessageListenersInterface for MessageListeners<'a> {
+ fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
+ //~^ ERROR impl method assumes more implied bounds than the corresponding trait method
+ //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ self
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/implied-bounds/impl-implied-bounds-compatibility.stderr b/src/test/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
new file mode 100644
index 000000000..0dfa8167a
--- /dev/null
+++ b/src/test/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
@@ -0,0 +1,16 @@
+error: impl method assumes more implied bounds than the corresponding trait method
+ --> $DIR/impl-implied-bounds-compatibility.rs:14:5
+ |
+LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572>
+note: the lint level is defined here
+ --> $DIR/impl-implied-bounds-compatibility.rs:1:9
+ |
+LL | #![deny(implied_bounds_entailment)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/inference/cannot-infer-async.rs b/src/test/ui/inference/cannot-infer-async.rs
index e7fabd0ff..b5152d04f 100644
--- a/src/test/ui/inference/cannot-infer-async.rs
+++ b/src/test/ui/inference/cannot-infer-async.rs
@@ -10,6 +10,7 @@ fn main() {
let fut = async {
make_unit()?;
- Ok(()) //~ ERROR type annotations needed
+ Ok(())
+ //~^ ERROR type annotations needed
};
}
diff --git a/src/test/ui/inference/cannot-infer-closure.rs b/src/test/ui/inference/cannot-infer-closure.rs
index 1c350b18f..bd5d10b41 100644
--- a/src/test/ui/inference/cannot-infer-closure.rs
+++ b/src/test/ui/inference/cannot-infer-closure.rs
@@ -1,6 +1,7 @@
fn main() {
let x = |a: (), b: ()| {
Err(a)?;
- Ok(b) //~ ERROR type annotations needed
+ Ok(b)
+ //~^ ERROR type annotations needed
};
}
diff --git a/src/test/ui/inference/deref-suggestion.stderr b/src/test/ui/inference/deref-suggestion.stderr
index d729f2d68..034005697 100644
--- a/src/test/ui/inference/deref-suggestion.stderr
+++ b/src/test/ui/inference/deref-suggestion.stderr
@@ -157,11 +157,11 @@ error[E0308]: `if` and `else` have incompatible types
--> $DIR/deref-suggestion.rs:69:12
|
LL | let val = if true {
- | _______________-
-LL | | *a
- | | -- expected because of this
-LL | | } else if true {
- | |____________^
+ | ________________-
+LL | | *a
+ | | -- expected because of this
+LL | | } else if true {
+ | | ____________^
LL | ||
LL | || b
LL | || } else {
@@ -169,7 +169,7 @@ LL | || &0
LL | || };
| || ^
| ||_____|
- | |______`if` and `else` have incompatible types
+ | |_____`if` and `else` have incompatible types
| expected `i32`, found `&{integer}`
error: aborting due to 13 previous errors
diff --git a/src/test/ui/inference/issue-103587.rs b/src/test/ui/inference/issue-103587.rs
new file mode 100644
index 000000000..11536f9f4
--- /dev/null
+++ b/src/test/ui/inference/issue-103587.rs
@@ -0,0 +1,12 @@
+fn main() {
+ let x = Some(123);
+
+ if let Some(_) == x {}
+ //~^ ERROR expected `=`, found `==`
+
+ if Some(_) = x {}
+ //~^ ERROR mismatched types
+
+ if None = x { }
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/inference/issue-103587.stderr b/src/test/ui/inference/issue-103587.stderr
new file mode 100644
index 000000000..b373fbfbb
--- /dev/null
+++ b/src/test/ui/inference/issue-103587.stderr
@@ -0,0 +1,40 @@
+error: expected `=`, found `==`
+ --> $DIR/issue-103587.rs:4:20
+ |
+LL | if let Some(_) == x {}
+ | ^^
+ |
+help: consider using `=` here
+ |
+LL | if let Some(_) = x {}
+ | ~
+
+error[E0308]: mismatched types
+ --> $DIR/issue-103587.rs:7:8
+ |
+LL | if Some(_) = x {}
+ | ^^^^^^^^^^^ expected `bool`, found `()`
+ |
+help: consider adding `let`
+ |
+LL | if let Some(_) = x {}
+ | +++
+
+error[E0308]: mismatched types
+ --> $DIR/issue-103587.rs:10:8
+ |
+LL | if None = x { }
+ | ^^^^^^^^ expected `bool`, found `()`
+ |
+help: you might have meant to use pattern matching
+ |
+LL | if let None = x { }
+ | +++
+help: you might have meant to compare for equality
+ |
+LL | if None == x { }
+ | +
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/inference/issue-104649.rs b/src/test/ui/inference/issue-104649.rs
new file mode 100644
index 000000000..4637b884d
--- /dev/null
+++ b/src/test/ui/inference/issue-104649.rs
@@ -0,0 +1,32 @@
+type Result<T, E = Error> = ::std::result::Result<T, E>;
+struct Error;
+
+trait ForEach {
+ type Input;
+ fn for_each<F, U>(self, f: F)
+ where
+ F: FnOnce(Self::Input) -> U;
+}
+
+impl<T> ForEach for A<T> {
+ type Input = T;
+ fn for_each<F, U>(self, f: F)
+ where
+ F: FnOnce(Self::Input) -> U,
+ {
+ todo!()
+ }
+}
+
+struct A<T>(T);
+
+fn main() {
+ let a = A(Result::Ok(Result::Ok(()))); //~ ERROR type annotations needed
+ a.for_each(|a: Result<_>| {
+ let f = || match a {
+ Ok(Ok(a)) => {}
+ Ok(Err(a)) => {}
+ Err(a) => {}
+ };
+ });
+}
diff --git a/src/test/ui/inference/issue-104649.stderr b/src/test/ui/inference/issue-104649.stderr
new file mode 100644
index 000000000..4962b21f9
--- /dev/null
+++ b/src/test/ui/inference/issue-104649.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), E>, Error>>`
+ --> $DIR/issue-104649.rs:24:9
+ |
+LL | let a = A(Result::Ok(Result::Ok(())));
+ | ^
+ |
+help: consider giving `a` an explicit type, where the type for type parameter `E` is specified
+ |
+LL | let a: A<std::result::Result<std::result::Result<(), E>, Error>> = A(Result::Ok(Result::Ok(())));
+ | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/inference/issue-71732.rs b/src/test/ui/inference/issue-71732.rs
index 30063a095..8a9d2b235 100644
--- a/src/test/ui/inference/issue-71732.rs
+++ b/src/test/ui/inference/issue-71732.rs
@@ -15,7 +15,8 @@ use std::collections::hash_map::HashMap;
fn foo(parameters: &HashMap<String, String>) -> bool {
parameters
- .get(&"key".into()) //~ ERROR: type annotations needed
+ .get(&"key".into())
+ //~^ ERROR type annotations needed
.and_then(|found: &String| Some(false))
.unwrap_or(false)
}
diff --git a/src/test/ui/inference/issue-72616.rs b/src/test/ui/inference/issue-72616.rs
index 5e5a3babf..69ade1a75 100644
--- a/src/test/ui/inference/issue-72616.rs
+++ b/src/test/ui/inference/issue-72616.rs
@@ -1,3 +1,5 @@
+// ignore-wasm32 FIXME: ignoring wasm as it suggests slightly different impls
+
// Regression test for #72616, it used to emit incorrect diagnostics, like:
// error[E0283]: type annotations needed for `String`
// --> src/main.rs:8:30
@@ -18,7 +20,8 @@ pub fn main() {
}
{
if String::from("a") == "a".try_into().unwrap() {}
- //~^ ERROR: type annotations needed
+ //~^ ERROR type annotations needed
+ //~| ERROR type annotations needed
}
{
let _: String = match "_".try_into() {
diff --git a/src/test/ui/inference/issue-72616.stderr b/src/test/ui/inference/issue-72616.stderr
index a71ce9a8e..6ee0626ca 100644
--- a/src/test/ui/inference/issue-72616.stderr
+++ b/src/test/ui/inference/issue-72616.stderr
@@ -1,5 +1,5 @@
error[E0283]: type annotations needed
- --> $DIR/issue-72616.rs:20:37
+ --> $DIR/issue-72616.rs:22:37
|
LL | if String::from("a") == "a".try_into().unwrap() {}
| -- ^^^^^^^^
@@ -16,6 +16,22 @@ help: try using a fully qualified path to specify the expected types
LL | if String::from("a") == <&str as TryInto<T>>::try_into("a").unwrap() {}
| +++++++++++++++++++++++++++++++ ~
-error: aborting due to previous error
+error[E0283]: type annotations needed
+ --> $DIR/issue-72616.rs:22:37
+ |
+LL | if String::from("a") == "a".try_into().unwrap() {}
+ | ^^^^^^^^
+ |
+ = note: multiple `impl`s satisfying `_: TryFrom<&str>` found in the following crates: `core`, `std`:
+ - impl<> TryFrom<&str> for std::sys_common::net::LookupHost;
+ - impl<T, U> TryFrom<U> for T
+ where U: Into<T>;
+ = note: required for `&str` to implement `TryInto<_>`
+help: try using a fully qualified path to specify the expected types
+ |
+LL | if String::from("a") == <&str as TryInto<T>>::try_into("a").unwrap() {}
+ | +++++++++++++++++++++++++++++++ ~
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0283`.
diff --git a/src/test/ui/inference/question-mark-type-infer.rs b/src/test/ui/inference/question-mark-type-infer.rs
index 64333a293..10560f85e 100644
--- a/src/test/ui/inference/question-mark-type-infer.rs
+++ b/src/test/ui/inference/question-mark-type-infer.rs
@@ -7,7 +7,8 @@ fn f(x: &i32) -> Result<i32, ()> {
fn g() -> Result<Vec<i32>, ()> {
let l = [1, 2, 3, 4];
- l.iter().map(f).collect()? //~ ERROR type annotations needed
+ l.iter().map(f).collect()?
+ //~^ ERROR type annotations needed
}
fn main() {
diff --git a/src/test/ui/infinite/infinite-instantiation.stderr b/src/test/ui/infinite/infinite-instantiation.stderr
index 52f578134..951e0f587 100644
--- a/src/test/ui/infinite/infinite-instantiation.stderr
+++ b/src/test/ui/infinite/infinite-instantiation.stderr
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `function::<Option<Option<Option<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `function::<Option<Option<Option<Option<Option<...>>>>>>`
--> $DIR/infinite-instantiation.rs:22:9
|
LL | function(counter - 1, t.to_option());
diff --git a/src/test/ui/infinite/infinite-recursion-const-fn.stderr b/src/test/ui/infinite/infinite-recursion-const-fn.stderr
index 620c9e110..53b603a47 100644
--- a/src/test/ui/infinite/infinite-recursion-const-fn.stderr
+++ b/src/test/ui/infinite/infinite-recursion-const-fn.stderr
@@ -2,143 +2,648 @@ error[E0080]: evaluation of constant value failed
--> $DIR/infinite-recursion-const-fn.rs:4:5
|
LL | b()
+ | ^^^ reached the configured maximum number of stack frames
+ |
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
| ^^^
- | |
- | reached the configured maximum number of stack frames
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
- | inside `a` at $DIR/infinite-recursion-const-fn.rs:4:5
-...
-LL | a()
- | ---
- | |
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
- | inside `b` at $DIR/infinite-recursion-const-fn.rs:7:5
-LL | }
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `b`
+ --> $DIR/infinite-recursion-const-fn.rs:7:5
+ |
+LL | a()
+ | ^^^
+note: inside `a`
+ --> $DIR/infinite-recursion-const-fn.rs:4:5
+ |
+LL | b()
+ | ^^^
+note: inside `ARR::{constant#0}`
+ --> $DIR/infinite-recursion-const-fn.rs:9:18
+ |
LL | const ARR: [i32; a()] = [5; 6];
- | --- inside `ARR::{constant#0}` at $DIR/infinite-recursion-const-fn.rs:9:18
+ | ^^^
error: aborting due to previous error
diff --git a/src/test/ui/inline-const/expr-with-block-err.rs b/src/test/ui/inline-const/expr-with-block-err.rs
new file mode 100644
index 000000000..f7547742d
--- /dev/null
+++ b/src/test/ui/inline-const/expr-with-block-err.rs
@@ -0,0 +1,6 @@
+#![feature(inline_const)]
+
+fn main() {
+ const { 2 } - const { 1 };
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/inline-const/expr-with-block-err.stderr b/src/test/ui/inline-const/expr-with-block-err.stderr
new file mode 100644
index 000000000..6f7408f4e
--- /dev/null
+++ b/src/test/ui/inline-const/expr-with-block-err.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+ --> $DIR/expr-with-block-err.rs:4:13
+ |
+LL | const { 2 } - const { 1 };
+ | ^ expected `()`, found integer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/inline-const/expr-with-block.rs b/src/test/ui/inline-const/expr-with-block.rs
new file mode 100644
index 000000000..391872476
--- /dev/null
+++ b/src/test/ui/inline-const/expr-with-block.rs
@@ -0,0 +1,10 @@
+// check-pass
+#![feature(inline_const)]
+fn main() {
+ match true {
+ true => const {}
+ false => ()
+ }
+ const {}
+ ()
+}
diff --git a/src/test/ui/issues/issue-105330.rs b/src/test/ui/issues/issue-105330.rs
new file mode 100644
index 000000000..86e45f10b
--- /dev/null
+++ b/src/test/ui/issues/issue-105330.rs
@@ -0,0 +1,21 @@
+pub trait TraitWAssocConst {
+ const A: usize;
+}
+pub struct Demo {}
+
+impl TraitWAssocConst for impl Demo { //~ ERROR E0404
+ //~^ ERROR E0562
+ pubconst A: str = 32; //~ ERROR expected one of
+}
+
+fn foo<A: TraitWAssocConst<A=32>>() { //~ ERROR E0658
+ foo::<Demo>()(); //~ ERROR E0271
+ //~^ ERROR E0618
+ //~| ERROR E0277
+}
+
+fn main<A: TraitWAssocConst<A=32>>() { //~ ERROR E0131
+ //~^ ERROR E0658
+ foo::<Demo>(); //~ ERROR E0277
+ //~^ ERROR E0271
+}
diff --git a/src/test/ui/issues/issue-105330.stderr b/src/test/ui/issues/issue-105330.stderr
new file mode 100644
index 000000000..92f2ccb65
--- /dev/null
+++ b/src/test/ui/issues/issue-105330.stderr
@@ -0,0 +1,109 @@
+error: expected one of `!` or `::`, found `A`
+ --> $DIR/issue-105330.rs:8:14
+ |
+LL | impl TraitWAssocConst for impl Demo {
+ | - while parsing this item list starting here
+LL |
+LL | pubconst A: str = 32;
+ | ^ expected one of `!` or `::`
+LL | }
+ | - the item list ends here
+
+error[E0404]: expected trait, found struct `Demo`
+ --> $DIR/issue-105330.rs:6:32
+ |
+LL | impl TraitWAssocConst for impl Demo {
+ | ^^^^ not a trait
+
+error[E0658]: associated const equality is incomplete
+ --> $DIR/issue-105330.rs:11:28
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^
+ |
+ = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
+ = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+
+error[E0658]: associated const equality is incomplete
+ --> $DIR/issue-105330.rs:17:29
+ |
+LL | fn main<A: TraitWAssocConst<A=32>>() {
+ | ^^^^
+ |
+ = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
+ = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
+
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
+ --> $DIR/issue-105330.rs:6:27
+ |
+LL | impl TraitWAssocConst for impl Demo {
+ | ^^^^^^^^^
+
+error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
+ --> $DIR/issue-105330.rs:12:11
+ |
+LL | foo::<Demo>()();
+ | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
+ |
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:11
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
+ --> $DIR/issue-105330.rs:12:11
+ |
+LL | foo::<Demo>()();
+ | ^^^^ types differ
+ |
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:28
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^ required by this bound in `foo`
+
+error[E0618]: expected function, found `()`
+ --> $DIR/issue-105330.rs:12:5
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ----------------------------------- `foo::<Demo>` defined here returns `()`
+LL | foo::<Demo>()();
+ | ^^^^^^^^^^^^^--
+ | |
+ | call expression requires function
+
+error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
+ --> $DIR/issue-105330.rs:19:11
+ |
+LL | foo::<Demo>();
+ | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
+ |
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:11
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
+ --> $DIR/issue-105330.rs:19:11
+ |
+LL | foo::<Demo>();
+ | ^^^^ types differ
+ |
+note: required by a bound in `foo`
+ --> $DIR/issue-105330.rs:11:28
+ |
+LL | fn foo<A: TraitWAssocConst<A=32>>() {
+ | ^^^^ required by this bound in `foo`
+
+error[E0131]: `main` function is not allowed to have generic parameters
+ --> $DIR/issue-105330.rs:17:8
+ |
+LL | fn main<A: TraitWAssocConst<A=32>>() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters
+
+error: aborting due to 11 previous errors
+
+Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658.
+For more information about an error, try `rustc --explain E0131`.
diff --git a/src/test/ui/issues/issue-12127.rs b/src/test/ui/issues/issue-12127.rs
index 8b30ddc2d..199d542e8 100644
--- a/src/test/ui/issues/issue-12127.rs
+++ b/src/test/ui/issues/issue-12127.rs
@@ -1,6 +1,6 @@
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, tuple_trait)]
-fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
+fn to_fn_once<A:std::marker::Tuple,F:FnOnce<A>>(f: F) -> F { f }
fn do_it(x: &isize) { }
fn main() {
diff --git a/src/test/ui/issues/issue-13497-2.stderr b/src/test/ui/issues/issue-13497-2.stderr
index 6f72b79f2..3abeadf9e 100644
--- a/src/test/ui/issues/issue-13497-2.stderr
+++ b/src/test/ui/issues/issue-13497-2.stderr
@@ -2,12 +2,12 @@ error[E0515]: cannot return value referencing local variable `rawLines`
--> $DIR/issue-13497-2.rs:3:5
|
LL | rawLines
- | _____^
- | |_____|
+ | ______^
+ | | _____|
| ||
LL | || .iter().map(|l| l.trim()).collect()
| ||_______________-___________________________^ returns a value referencing data owned by the current function
- | |________________|
+ | |_______________|
| `rawLines` is borrowed here
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-1460.stderr b/src/test/ui/issues/issue-1460.stderr
index f0ff2cafd..eb7661fad 100644
--- a/src/test/ui/issues/issue-1460.stderr
+++ b/src/test/ui/issues/issue-1460.stderr
@@ -2,7 +2,7 @@ warning: unused closure that must be used
--> $DIR/issue-1460.rs:6:5
|
LL | {|i: u32| if 1 == i { }};
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: closures are lazy and do nothing unless called
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/issues/issue-16256.stderr b/src/test/ui/issues/issue-16256.stderr
index ca8e9a1be..d920530b5 100644
--- a/src/test/ui/issues/issue-16256.stderr
+++ b/src/test/ui/issues/issue-16256.stderr
@@ -2,7 +2,7 @@ warning: unused closure that must be used
--> $DIR/issue-16256.rs:6:5
|
LL | |c: u8| buf.push(c);
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^
|
= note: closures are lazy and do nothing unless called
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr
index 4856418ed..aca5242b2 100644
--- a/src/test/ui/issues/issue-17252.stderr
+++ b/src/test/ui/issues/issue-17252.stderr
@@ -1,8 +1,8 @@
error[E0391]: cycle detected when const-evaluating + checking `FOO`
- --> $DIR/issue-17252.rs:1:1
+ --> $DIR/issue-17252.rs:1:20
|
LL | const FOO: usize = FOO;
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^
|
= note: ...which immediately requires const-evaluating + checking `FOO` again
note: cycle used when const-evaluating + checking `main::{constant#0}`
diff --git a/src/test/ui/issues/issue-19086.rs b/src/test/ui/issues/issue-19086.rs
index cc83874cb..42148c5f5 100644
--- a/src/test/ui/issues/issue-19086.rs
+++ b/src/test/ui/issues/issue-19086.rs
@@ -8,6 +8,6 @@ fn main() {
let f = FooB { x: 3, y: 4 };
match f {
FooB(a, b) => println!("{} {}", a, b),
- //~^ ERROR expected tuple struct or tuple variant, found struct variant `FooB`
+ //~^ ERROR expected tuple struct or tuple variant, found variant `FooB`
}
}
diff --git a/src/test/ui/issues/issue-19086.stderr b/src/test/ui/issues/issue-19086.stderr
index a54f1008e..a3c06a725 100644
--- a/src/test/ui/issues/issue-19086.stderr
+++ b/src/test/ui/issues/issue-19086.stderr
@@ -1,4 +1,4 @@
-error[E0532]: expected tuple struct or tuple variant, found struct variant `FooB`
+error[E0532]: expected tuple struct or tuple variant, found variant `FooB`
--> $DIR/issue-19086.rs:10:9
|
LL | FooB { x: i32, y: i32 }
diff --git a/src/test/ui/issues/issue-20413.rs b/src/test/ui/issues/issue-20413.rs
index 138a235e6..4de22f0c9 100644
--- a/src/test/ui/issues/issue-20413.rs
+++ b/src/test/ui/issues/issue-20413.rs
@@ -1,3 +1,4 @@
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
trait Foo {
fn answer(self);
}
diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr
index 2db60b641..78df44597 100644
--- a/src/test/ui/issues/issue-20413.stderr
+++ b/src/test/ui/issues/issue-20413.stderr
@@ -1,5 +1,5 @@
error[E0392]: parameter `T` is never used
- --> $DIR/issue-20413.rs:5:15
+ --> $DIR/issue-20413.rs:6:15
|
LL | struct NoData<T>;
| ^ unused parameter
@@ -7,58 +7,63 @@ LL | struct NoData<T>;
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
-error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
- --> $DIR/issue-20413.rs:8:36
+error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>: Foo`
+ --> $DIR/issue-20413.rs:9:36
|
LL | impl<T> Foo for T where NoData<T>: Foo {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
- --> $DIR/issue-20413.rs:8:9
+note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>>>>>>>` to implement `Foo`
+ --> $DIR/issue-20413.rs:9:9
|
LL | impl<T> Foo for T where NoData<T>: Foo {
| ^^^ ^
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
= note: 127 redundant requirements hidden
= note: required for `NoData<T>` to implement `Foo`
-error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Baz`
- --> $DIR/issue-20413.rs:27:42
+error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>: Baz`
+ --> $DIR/issue-20413.rs:28:42
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
- --> $DIR/issue-20413.rs:27:9
+note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>` to implement `Bar`
+ --> $DIR/issue-20413.rs:28:9
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^ ^
-note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
- --> $DIR/issue-20413.rs:34:9
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
+note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>` to implement `Baz`
+ --> $DIR/issue-20413.rs:35:9
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^ ^
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
= note: 126 redundant requirements hidden
= note: required for `EvenLessData<T>` to implement `Baz`
-error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Bar`
- --> $DIR/issue-20413.rs:34:42
+error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>: Bar`
+ --> $DIR/issue-20413.rs:35:42
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
-note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
- --> $DIR/issue-20413.rs:34:9
+note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>` to implement `Baz`
+ --> $DIR/issue-20413.rs:35:9
|
LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
| ^^^ ^
-note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
- --> $DIR/issue-20413.rs:27:9
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
+note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>` to implement `Bar`
+ --> $DIR/issue-20413.rs:28:9
|
LL | impl<T> Bar for T where EvenLessData<T>: Baz {
| ^^^ ^
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-20413/issue-20413.long-type-hash.txt'
= note: 126 redundant requirements hidden
= note: required for `AlmostNoData<T>` to implement `Bar`
diff --git a/src/test/ui/issues/issue-22638.stderr b/src/test/ui/issues/issue-22638.stderr
index 1354ec8e8..1caa4221f 100644
--- a/src/test/ui/issues/issue-22638.stderr
+++ b/src/test/ui/issues/issue-22638.stderr
@@ -9,7 +9,6 @@ note: `A::matches` defined here
|
LL | pub fn matches<F: Fn()>(&self, f: &F) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-22638/issue-22638.long-type.txt'
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr
index 73f93c51d..dc8b34a70 100644
--- a/src/test/ui/issues/issue-23024.stderr
+++ b/src/test/ui/issues/issue-23024.stderr
@@ -16,7 +16,7 @@ LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3));
note: trait defined here, with 1 generic parameter: `Args`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
-LL | pub trait Fn<Args>: FnMut<Args> {
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
| ^^ ----
help: add missing generic argument
|
diff --git a/src/test/ui/issues/issue-23122-2.stderr b/src/test/ui/issues/issue-23122-2.stderr
index 0111cf569..1f50b06a0 100644
--- a/src/test/ui/issues/issue-23122-2.stderr
+++ b/src/test/ui/issues/issue-23122-2.stderr
@@ -1,15 +1,16 @@
-error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
+error[E0275]: overflow evaluating the requirement `<<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
--> $DIR/issue-23122-2.rs:11:17
|
LL | type Next = <GetNext<T::Next> as Next>::Next;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`)
-note: required for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next`
+note: required for `GetNext<<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next`
--> $DIR/issue-23122-2.rs:10:15
|
LL | impl<T: Next> Next for GetNext<T> {
| ^^^^ ^^^^^^^^^^
+ = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-23122-2/issue-23122-2.long-type-hash.txt'
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-23302-3.stderr b/src/test/ui/issues/issue-23302-3.stderr
index 074939f68..c6cafe575 100644
--- a/src/test/ui/issues/issue-23302-3.stderr
+++ b/src/test/ui/issues/issue-23302-3.stderr
@@ -1,14 +1,14 @@
error[E0391]: cycle detected when const-evaluating + checking `A`
- --> $DIR/issue-23302-3.rs:1:1
+ --> $DIR/issue-23302-3.rs:1:16
|
LL | const A: i32 = B;
- | ^^^^^^^^^^^^^^^^^
+ | ^
|
note: ...which requires const-evaluating + checking `B`...
- --> $DIR/issue-23302-3.rs:3:1
+ --> $DIR/issue-23302-3.rs:3:16
|
LL | const B: i32 = A;
- | ^^^^^^^^^^^^^^^^^
+ | ^
= note: ...which again requires const-evaluating + checking `A`, completing the cycle
note: cycle used when simplifying constant for the type system `A`
--> $DIR/issue-23302-3.rs:1:1
diff --git a/src/test/ui/issues/issue-24352.stderr b/src/test/ui/issues/issue-24352.stderr
index 118f37f69..1f51b6e29 100644
--- a/src/test/ui/issues/issue-24352.stderr
+++ b/src/test/ui/issues/issue-24352.stderr
@@ -6,15 +6,10 @@ LL | 1.0f64 - 1
|
= help: the trait `Sub<{integer}>` is not implemented for `f64`
= help: the following other types implement trait `Sub<Rhs>`:
- <&'a f32 as Sub<f32>>
<&'a f64 as Sub<f64>>
- <&'a i128 as Sub<i128>>
- <&'a i16 as Sub<i16>>
- <&'a i32 as Sub<i32>>
- <&'a i64 as Sub<i64>>
- <&'a i8 as Sub<i8>>
- <&'a isize as Sub<isize>>
- and 48 others
+ <&f64 as Sub<&f64>>
+ <f64 as Sub<&f64>>
+ <f64 as Sub>
help: consider using a floating-point literal by writing it with `.0`
|
LL | 1.0f64 - 1.0
diff --git a/src/test/ui/issues/issue-28105.stderr b/src/test/ui/issues/issue-28105.stderr
index 42ed838d7..f450256f3 100644
--- a/src/test/ui/issues/issue-28105.stderr
+++ b/src/test/ui/issues/issue-28105.stderr
@@ -4,11 +4,11 @@ error[E0268]: `continue` outside of a loop
LL | continue
| ^^^^^^^^ cannot `continue` outside of a loop
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/issue-28105.rs:6:5
|
LL | break
- | ^^^^^ cannot `break` outside of a loop
+ | ^^^^^ cannot `break` outside of a loop or labeled block
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-28568.stderr b/src/test/ui/issues/issue-28568.stderr
index be3f7c627..960259080 100644
--- a/src/test/ui/issues/issue-28568.stderr
+++ b/src/test/ui/issues/issue-28568.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `MyStruct`
+error[E0119]: conflicting implementations of trait `Drop` for type `MyStruct`
--> $DIR/issue-28568.rs:7:1
|
LL | impl Drop for MyStruct {
diff --git a/src/test/ui/issues/issue-28992-empty.stderr b/src/test/ui/issues/issue-28992-empty.stderr
index 71f337278..f69773b8c 100644
--- a/src/test/ui/issues/issue-28992-empty.stderr
+++ b/src/test/ui/issues/issue-28992-empty.stderr
@@ -8,7 +8,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated constant
--> $DIR/issue-28992-empty.rs:14:12
|
LL | if let S::C2(..) = 0 {}
- | ^^^^^^^^^ not a tuple variant or struct
+ | ^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-29723.stderr b/src/test/ui/issues/issue-29723.stderr
index e39ddfc81..92ee5cf22 100644
--- a/src/test/ui/issues/issue-29723.stderr
+++ b/src/test/ui/issues/issue-29723.stderr
@@ -9,6 +9,11 @@ LL | 0 if { drop(s); false } => String::from("oops"),
...
LL | s
| ^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | 0 if { drop(s.clone()); false } => String::from("oops"),
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-30490.rs b/src/test/ui/issues/issue-30490.rs
index 68d9c4de4..4f0eeac8f 100644
--- a/src/test/ui/issues/issue-30490.rs
+++ b/src/test/ui/issues/issue-30490.rs
@@ -10,7 +10,7 @@
// This test checks to avoid that regression.
#![cfg_attr(unix, feature(rustc_private))]
-#![cfg_attr(windows, allow(unused_imports))]
+#![cfg_attr(not(unix), allow(unused_imports))]
#[cfg(unix)]
extern crate libc;
diff --git a/src/test/ui/issues/issue-32655.stderr b/src/test/ui/issues/issue-32655.stderr
index 2d9ce430a..5a758c700 100644
--- a/src/test/ui/issues/issue-32655.stderr
+++ b/src/test/ui/issues/issue-32655.stderr
@@ -2,18 +2,28 @@ error: cannot find attribute `derive_Clone` in this scope
--> $DIR/issue-32655.rs:3:11
|
LL | #[derive_Clone]
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const`
...
LL | foo!();
| ------ in this macro invocation
|
+ ::: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ |
+LL | pub macro derive_const($item:item) {
+ | ---------------------- similarly named attribute macro `derive_const` defined here
+ |
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot find attribute `derive_Clone` in this scope
--> $DIR/issue-32655.rs:15:7
|
LL | #[derive_Clone]
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const`
+ |
+ ::: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ |
+LL | pub macro derive_const($item:item) {
+ | ---------------------- similarly named attribute macro `derive_const` defined here
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-35976.rs b/src/test/ui/issues/issue-35976.rs
index d075794d9..aa6f74cb5 100644
--- a/src/test/ui/issues/issue-35976.rs
+++ b/src/test/ui/issues/issue-35976.rs
@@ -1,5 +1,9 @@
+// revisions: imported unimported
+//[imported] check-pass
+
mod private {
pub trait Future {
+ //[unimported]~^^ HELP perhaps add a `use` for it
fn wait(&self) where Self: Sized;
}
@@ -8,13 +12,13 @@ mod private {
}
}
-//use private::Future;
+#[cfg(imported)]
+use private::Future;
fn bar(arg: Box<dyn private::Future>) {
+ // Importing the trait means that we don't autoderef `Box<dyn Future>`
arg.wait();
- //~^ ERROR the `wait` method cannot be invoked on a trait object
+ //[unimported]~^ ERROR the `wait` method cannot be invoked on a trait object
}
-fn main() {
-
-}
+fn main() {}
diff --git a/src/test/ui/issues/issue-35976.stderr b/src/test/ui/issues/issue-35976.unimported.stderr
index fe16f97b9..5d61bb8ea 100644
--- a/src/test/ui/issues/issue-35976.stderr
+++ b/src/test/ui/issues/issue-35976.unimported.stderr
@@ -1,11 +1,16 @@
error: the `wait` method cannot be invoked on a trait object
- --> $DIR/issue-35976.rs:14:9
+ --> $DIR/issue-35976.rs:20:9
|
LL | fn wait(&self) where Self: Sized;
| ----- this has a `Sized` requirement
...
LL | arg.wait();
| ^^^^
+ |
+help: another candidate was found in the following trait, perhaps add a `use` for it:
+ |
+LL | use private::Future;
+ |
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-3707.stderr b/src/test/ui/issues/issue-3707.stderr
index 6ca2deee3..07c8101cb 100644
--- a/src/test/ui/issues/issue-3707.stderr
+++ b/src/test/ui/issues/issue-3707.stderr
@@ -2,10 +2,10 @@ error[E0599]: no method named `boom` found for reference `&Obj` in the current s
--> $DIR/issue-3707.rs:10:14
|
LL | self.boom();
- | -----^^^^
+ | -----^^^^--
| | |
| | this is an associated function, not a method
- | help: use associated function syntax instead: `Obj::boom`
+ | help: use associated function syntax instead: `Obj::boom()`
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in an impl for the type `Obj`
diff --git a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
index 93aeb8946..5b8299fe8 100644
--- a/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
+++ b/src/test/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `<(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(.....), ...), ...) as Foo>::recurse`
+error: reached the recursion limit while instantiating `<(&(&(..., ...), ...), ...) as Foo>::recurse`
--> $DIR/issue-37311.rs:17:9
|
LL | (self, self).recurse();
diff --git a/src/test/ui/issues/issue-41394.rs b/src/test/ui/issues/issue-41394.rs
index 64873ac35..07cad8796 100644
--- a/src/test/ui/issues/issue-41394.rs
+++ b/src/test/ui/issues/issue-41394.rs
@@ -5,7 +5,7 @@ enum Foo {
enum Bar {
A = Foo::A as isize
- //~^ ERROR evaluation of constant value failed
+ //~^ const
}
fn main() {}
diff --git a/src/test/ui/issues/issue-41394.stderr b/src/test/ui/issues/issue-41394.stderr
index 47a24547d..1b5c64628 100644
--- a/src/test/ui/issues/issue-41394.stderr
+++ b/src/test/ui/issues/issue-41394.stderr
@@ -6,13 +6,12 @@ LL | A = "" + 1
| |
| &str
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-41394.rs:7:9
|
LL | A = Foo::A as isize
- | ^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-Some errors have detailed explanations: E0080, E0369.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/issues/issue-42796.stderr b/src/test/ui/issues/issue-42796.stderr
index f3e0e7b20..f2971df5d 100644
--- a/src/test/ui/issues/issue-42796.stderr
+++ b/src/test/ui/issues/issue-42796.stderr
@@ -10,6 +10,10 @@ LL | println!("{}", s);
| ^ value borrowed here after move
|
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let mut s_copy = s.clone();
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr
index a443db407..40d920005 100644
--- a/src/test/ui/issues/issue-43162.stderr
+++ b/src/test/ui/issues/issue-43162.stderr
@@ -1,14 +1,14 @@
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/issue-43162.rs:3:5
|
LL | break true;
- | ^^^^^^^^^^ cannot `break` outside of a loop
+ | ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/issue-43162.rs:7:5
|
LL | break {};
- | ^^^^^^^^ cannot `break` outside of a loop
+ | ^^^^^^^^ cannot `break` outside of a loop or labeled block
error[E0308]: mismatched types
--> $DIR/issue-43162.rs:1:13
diff --git a/src/test/ui/issues/issue-43355.stderr b/src/test/ui/issues/issue-43355.stderr
index 531130fec..57adc8ad5 100644
--- a/src/test/ui/issues/issue-43355.stderr
+++ b/src/test/ui/issues/issue-43355.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `Trait1<std::boxed::Box<_>>` for type `A`
+error[E0119]: conflicting implementations of trait `Trait1<Box<_>>` for type `A`
--> $DIR/issue-43355.rs:13:1
|
LL | impl<X, T> Trait1<X> for T where T: Trait2<X> {
diff --git a/src/test/ui/issues/issue-47184.stderr b/src/test/ui/issues/issue-47184.stderr
index f97713b4a..c2c7df7a3 100644
--- a/src/test/ui/issues/issue-47184.stderr
+++ b/src/test/ui/issues/issue-47184.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let _vec: Vec<&'static String> = vec![&String::new()];
| -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| | |
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| type annotation requires that borrow lasts for `'static`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-47511.stderr b/src/test/ui/issues/issue-47511.stderr
deleted file mode 100644
index 9998ee0e8..000000000
--- a/src/test/ui/issues/issue-47511.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
- --> $DIR/issue-47511.rs:8:15
- |
-LL | fn f(_: X) -> X {
- | ^
- |
- = note: lifetimes appearing in an associated or opaque type are not considered constrained
- = note: consider introducing a named lifetime parameter
-
-error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
- --> $DIR/issue-47511.rs:12:23
- |
-LL | fn g<'a>(_: X<'a>) -> X<'a> {
- | ^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0581`.
diff --git a/src/test/ui/issues/issue-48728.rs b/src/test/ui/issues/issue-48728.rs
index 8405a3047..cbdc10bd2 100644
--- a/src/test/ui/issues/issue-48728.rs
+++ b/src/test/ui/issues/issue-48728.rs
@@ -1,7 +1,7 @@
// Regression test for #48728, an ICE that occurred computing
// coherence "help" information.
-#[derive(Clone)] //~ ERROR conflicting implementations of trait `std::clone::Clone`
+#[derive(Clone)] //~ ERROR conflicting implementations of trait `Clone`
struct Node<T: ?Sized>(Box<T>);
impl<T: Clone + ?Sized> Clone for Node<[T]> {
diff --git a/src/test/ui/issues/issue-48728.stderr b/src/test/ui/issues/issue-48728.stderr
index 628f026b6..0bb46724f 100644
--- a/src/test/ui/issues/issue-48728.stderr
+++ b/src/test/ui/issues/issue-48728.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `Node<[_]>`
+error[E0119]: conflicting implementations of trait `Clone` for type `Node<[_]>`
--> $DIR/issue-48728.rs:4:10
|
LL | #[derive(Clone)]
diff --git a/src/test/ui/issues/issue-50576.stderr b/src/test/ui/issues/issue-50576.stderr
index 9fea14110..4ec22fde9 100644
--- a/src/test/ui/issues/issue-50576.stderr
+++ b/src/test/ui/issues/issue-50576.stderr
@@ -4,17 +4,17 @@ error[E0426]: use of undeclared label `'L`
LL | |bool: [u8; break 'L]| 0;
| ^^ undeclared label `'L`
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/issue-50576.rs:2:17
|
LL | |bool: [u8; break 'L]| 0;
- | ^^^^^^^^ cannot `break` outside of a loop
+ | ^^^^^^^^ cannot `break` outside of a loop or labeled block
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/issue-50576.rs:5:16
|
LL | Vec::<[u8; break]>::new();
- | ^^^^^ cannot `break` outside of a loop
+ | ^^^^^ cannot `break` outside of a loop or labeled block
error: aborting due to 3 previous errors
diff --git a/src/test/ui/issues/issue-50581.stderr b/src/test/ui/issues/issue-50581.stderr
index 35d6fc49c..07b6df072 100644
--- a/src/test/ui/issues/issue-50581.stderr
+++ b/src/test/ui/issues/issue-50581.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/issue-50581.rs:2:14
|
LL | |_: [u8; break]| ();
- | ^^^^^ cannot `break` outside of a loop
+ | ^^^^^ cannot `break` outside of a loop or labeled block
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-52049.stderr b/src/test/ui/issues/issue-52049.stderr
index 55929d85d..b25dbd1cb 100644
--- a/src/test/ui/issues/issue-52049.stderr
+++ b/src/test/ui/issues/issue-52049.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | foo(&unpromotable(5u32));
| -----^^^^^^^^^^^^^^^^^^-
| | |
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| argument requires that borrow lasts for `'static`
LL | }
| - temporary value is freed at the end of this statement
diff --git a/src/test/ui/issues/issue-52262.rs b/src/test/ui/issues/issue-52262.rs
index 2195b8955..547643f0d 100644
--- a/src/test/ui/issues/issue-52262.rs
+++ b/src/test/ui/issues/issue-52262.rs
@@ -1,4 +1,3 @@
-// compile-flags:-Ztreat-err-as-bug=5
#[derive(Debug)]
enum MyError {
NotFound { key: Vec<u8> },
diff --git a/src/test/ui/issues/issue-52262.stderr b/src/test/ui/issues/issue-52262.stderr
index c0bde4b23..ef41f078b 100644
--- a/src/test/ui/issues/issue-52262.stderr
+++ b/src/test/ui/issues/issue-52262.stderr
@@ -1,5 +1,5 @@
error[E0507]: cannot move out of `*key` which is behind a shared reference
- --> $DIR/issue-52262.rs:16:35
+ --> $DIR/issue-52262.rs:15:35
|
LL | String::from_utf8(*key).unwrap()
| ^^^^ move occurs because `*key` has type `Vec<u8>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/issues/issue-56835.stderr b/src/test/ui/issues/issue-56835.stderr
index c200ba8d5..e949ae7b3 100644
--- a/src/test/ui/issues/issue-56835.stderr
+++ b/src/test/ui/issues/issue-56835.stderr
@@ -8,7 +8,7 @@ error[E0164]: expected tuple struct or tuple variant, found self constructor `Se
--> $DIR/issue-56835.rs:4:12
|
LL | fn bar(Self(foo): Self) {}
- | ^^^^^^^^^ not a tuple variant or struct
+ | ^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-63983.stderr b/src/test/ui/issues/issue-63983.stderr
index eb0428341..f90c81116 100644
--- a/src/test/ui/issues/issue-63983.stderr
+++ b/src/test/ui/issues/issue-63983.stderr
@@ -7,15 +7,13 @@ LL | Tuple(i32),
LL | MyEnum::Tuple => "",
| ^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `MyEnum::Tuple(_)`
-error[E0532]: expected unit struct, unit variant or constant, found struct variant `MyEnum::Struct`
+error[E0533]: expected unit struct, unit variant or constant, found struct variant `MyEnum::Struct`
--> $DIR/issue-63983.rs:10:9
|
-LL | Struct{ s: i32 },
- | ---------------- `MyEnum::Struct` defined here
-...
LL | MyEnum::Struct => "",
- | ^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `MyEnum::Struct { s }`
+ | ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0532`.
+Some errors have detailed explanations: E0532, E0533.
+For more information about an error, try `rustc --explain E0532`.
diff --git a/src/test/ui/issues/issue-67552.stderr b/src/test/ui/issues/issue-67552.stderr
index 2968be7c7..4746f918b 100644
--- a/src/test/ui/issues/issue-67552.stderr
+++ b/src/test/ui/issues/issue-67552.stderr
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &... &mut &mut &mut &mut &mut Empty>`
+error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>`
--> $DIR/issue-67552.rs:29:9
|
LL | rec(identity(&mut it))
diff --git a/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr b/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr
index f581429a2..89aeafeba 100644
--- a/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr
+++ b/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr
@@ -2,10 +2,7 @@ error[E0428]: the name `A` is defined multiple times
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:13
|
LL | const A = "A".$fn();
- | ^^^^^^^^^^^^^^^^^^^^
- | |
- | `A` redefined here
- | previous definition of the value `A` here
+ | ^^^^^^^^^^^^^^^^^^^^ `A` redefined here
...
LL | / suite! {
LL | | len;
diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
index 6851b67cb..e98affc5c 100644
--- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
+++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
@@ -19,5 +19,5 @@ impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA`
fn main() {
let _ = [0; B::VALUE];
- //~^ ERROR evaluation of constant value failed
+ //~^ constant
}
diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
index 2c2cd5c52..ba385d887 100644
--- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
+++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
@@ -13,13 +13,13 @@ LL | type MyA: TraitA;
LL | impl TraitB for B {
| ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17
|
LL | let _ = [0; B::VALUE];
- | ^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0046, E0080, E0437.
+Some errors have detailed explanations: E0046, E0437.
For more information about an error, try `rustc --explain E0046`.
diff --git a/src/test/ui/issues/issue-71584.rs b/src/test/ui/issues/issue-71584.rs
index c96cd598f..7bf3ed60e 100644
--- a/src/test/ui/issues/issue-71584.rs
+++ b/src/test/ui/issues/issue-71584.rs
@@ -1,5 +1,6 @@
fn main() {
let n: u32 = 1;
let mut d: u64 = 2;
- d = d % n.into(); //~ ERROR type annotations needed
+ d = d % n.into();
+ //~^ ERROR type annotations needed
}
diff --git a/src/test/ui/issues/issue-7607-1.stderr b/src/test/ui/issues/issue-7607-1.stderr
index ecff8b42b..f1ab0ad26 100644
--- a/src/test/ui/issues/issue-7607-1.stderr
+++ b/src/test/ui/issues/issue-7607-1.stderr
@@ -6,8 +6,8 @@ LL | impl Fo {
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
-LL | pub trait Fn<Args>: FnMut<Args> {
- | ------------------------------- similarly named trait `Fn` defined here
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | -------------------------------------- similarly named trait `Fn` defined here
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-7970a.stderr b/src/test/ui/issues/issue-7970a.stderr
index ea400d7e1..b04a0eef3 100644
--- a/src/test/ui/issues/issue-7970a.stderr
+++ b/src/test/ui/issues/issue-7970a.stderr
@@ -6,6 +6,12 @@ LL | macro_rules! one_arg_macro {
...
LL | one_arg_macro!();
| ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
+ |
+note: while trying to match meta-variable `$fmt:expr`
+ --> $DIR/issue-7970a.rs:2:6
+ |
+LL | ($fmt:expr) => (print!(concat!($fmt, "\n")));
+ | ^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-83048.rs b/src/test/ui/issues/issue-83048.rs
index 520ae9743..8e4fb6eae 100644
--- a/src/test/ui/issues/issue-83048.rs
+++ b/src/test/ui/issues/issue-83048.rs
@@ -1,5 +1,5 @@
// compile-flags: -Z unpretty=thir-tree
pub fn main() {
- break; //~ ERROR: `break` outside of a loop [E0268]
+ break; //~ ERROR: `break` outside of a loop or labeled block [E0268]
}
diff --git a/src/test/ui/issues/issue-83048.stderr b/src/test/ui/issues/issue-83048.stderr
index 62d67d758..dade9e469 100644
--- a/src/test/ui/issues/issue-83048.stderr
+++ b/src/test/ui/issues/issue-83048.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of a loop
+error[E0268]: `break` outside of a loop or labeled block
--> $DIR/issue-83048.rs:4:5
|
LL | break;
- | ^^^^^ cannot `break` outside of a loop
+ | ^^^^^ cannot `break` outside of a loop or labeled block
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-8727.stderr b/src/test/ui/issues/issue-8727.stderr
index 5e1fdad60..22332b357 100644
--- a/src/test/ui/issues/issue-8727.stderr
+++ b/src/test/ui/issues/issue-8727.stderr
@@ -9,7 +9,7 @@ LL | generic::<Option<T>>();
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default
-error: reached the recursion limit while instantiating `generic::<Option<Option<Option<O...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `generic::<Option<Option<Option<Option<Option<...>>>>>>`
--> $DIR/issue-8727.rs:8:5
|
LL | generic::<Option<T>>();
diff --git a/src/test/ui/iterators/collect-into-array.rs b/src/test/ui/iterators/collect-into-array.rs
index 7d35da825..4c424999b 100644
--- a/src/test/ui/iterators/collect-into-array.rs
+++ b/src/test/ui/iterators/collect-into-array.rs
@@ -1,5 +1,4 @@
fn main() {
- //~^ NOTE required by a bound in this
let whatever: [u32; 10] = (0..10).collect();
//~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator
//~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()`
diff --git a/src/test/ui/iterators/collect-into-array.stderr b/src/test/ui/iterators/collect-into-array.stderr
index 7fe9707e6..a23a36a88 100644
--- a/src/test/ui/iterators/collect-into-array.stderr
+++ b/src/test/ui/iterators/collect-into-array.stderr
@@ -1,5 +1,5 @@
error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator
- --> $DIR/collect-into-array.rs:3:31
+ --> $DIR/collect-into-array.rs:2:31
|
LL | let whatever: [u32; 10] = (0..10).collect();
| ^^^^^^^ ------- required by a bound introduced by this call
diff --git a/src/test/ui/iterators/collect-into-slice.rs b/src/test/ui/iterators/collect-into-slice.rs
index 5eade0756..09832c260 100644
--- a/src/test/ui/iterators/collect-into-slice.rs
+++ b/src/test/ui/iterators/collect-into-slice.rs
@@ -1,6 +1,4 @@
fn process_slice(data: &[i32]) {
- //~^ NOTE required by a bound in this
- //~| NOTE required by a bound in this
todo!()
}
diff --git a/src/test/ui/iterators/collect-into-slice.stderr b/src/test/ui/iterators/collect-into-slice.stderr
index bce40118b..bc152467c 100644
--- a/src/test/ui/iterators/collect-into-slice.stderr
+++ b/src/test/ui/iterators/collect-into-slice.stderr
@@ -1,5 +1,5 @@
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
- --> $DIR/collect-into-slice.rs:8:9
+ --> $DIR/collect-into-slice.rs:6:9
|
LL | let some_generated_vec = (0..10).collect();
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -9,7 +9,7 @@ LL | let some_generated_vec = (0..10).collect();
= help: unsized locals are gated as an unstable feature
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
- --> $DIR/collect-into-slice.rs:8:38
+ --> $DIR/collect-into-slice.rs:6:38
|
LL | let some_generated_vec = (0..10).collect();
| ^^^^^^^ doesn't have a size known at compile-time
@@ -22,7 +22,7 @@ LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^ required by this bound in `collect`
error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size
- --> $DIR/collect-into-slice.rs:8:30
+ --> $DIR/collect-into-slice.rs:6:30
|
LL | let some_generated_vec = (0..10).collect();
| ^^^^^^^ ------- required by a bound introduced by this call
diff --git a/src/test/ui/kindck/kindck-copy.stderr b/src/test/ui/kindck/kindck-copy.stderr
index 025a5008d..9af89159a 100644
--- a/src/test/ui/kindck/kindck-copy.stderr
+++ b/src/test/ui/kindck/kindck-copy.stderr
@@ -4,16 +4,7 @@ error[E0277]: the trait bound `&'static mut isize: Copy` is not satisfied
LL | assert_copy::<&'static mut isize>();
| ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'static mut isize`
|
- = help: the following other types implement trait `Copy`:
- f32
- f64
- i128
- i16
- i32
- i64
- i8
- isize
- and 6 others
+ = help: the trait `Copy` is implemented for `isize`
note: required by a bound in `assert_copy`
--> $DIR/kindck-copy.rs:5:18
|
@@ -26,16 +17,7 @@ error[E0277]: the trait bound `&'a mut isize: Copy` is not satisfied
LL | assert_copy::<&'a mut isize>();
| ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'a mut isize`
|
- = help: the following other types implement trait `Copy`:
- f32
- f64
- i128
- i16
- i32
- i64
- i8
- isize
- and 6 others
+ = help: the trait `Copy` is implemented for `isize`
note: required by a bound in `assert_copy`
--> $DIR/kindck-copy.rs:5:18
|
diff --git a/src/test/ui/lang-items/lang-item-generic-requirements.rs b/src/test/ui/lang-items/lang-item-generic-requirements.rs
index fbb56e528..3d33adf68 100644
--- a/src/test/ui/lang-items/lang-item-generic-requirements.rs
+++ b/src/test/ui/lang-items/lang-item-generic-requirements.rs
@@ -22,8 +22,6 @@ trait MyIndex<'a, T> {}
#[lang = "phantom_data"]
//~^ ERROR `phantom_data` language item must be applied to a struct with 1 generic argument
struct MyPhantomData<T, U>;
-//~^ ERROR parameter `T` is never used
-//~| ERROR parameter `U` is never used
#[lang = "owned_box"]
//~^ ERROR `owned_box` language item must be applied to a struct with at least 1 generic argument
diff --git a/src/test/ui/lang-items/lang-item-generic-requirements.stderr b/src/test/ui/lang-items/lang-item-generic-requirements.stderr
index 326f5b0d5..4d349a25f 100644
--- a/src/test/ui/lang-items/lang-item-generic-requirements.stderr
+++ b/src/test/ui/lang-items/lang-item-generic-requirements.stderr
@@ -33,7 +33,7 @@ LL | struct MyPhantomData<T, U>;
| ------ this struct has 2 generic arguments
error[E0718]: `owned_box` language item must be applied to a struct with at least 1 generic argument
- --> $DIR/lang-item-generic-requirements.rs:28:1
+ --> $DIR/lang-item-generic-requirements.rs:26:1
|
LL | #[lang = "owned_box"]
| ^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +42,7 @@ LL | struct Foo;
| - this struct has 0 generic arguments
error[E0718]: `start` language item must be applied to a function with 1 generic argument
- --> $DIR/lang-item-generic-requirements.rs:34:1
+ --> $DIR/lang-item-generic-requirements.rs:32:1
|
LL | #[lang = "start"]
| ^^^^^^^^^^^^^^^^^
@@ -50,25 +50,6 @@ LL |
LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
| - this function has 0 generic arguments
-error[E0392]: parameter `T` is never used
- --> $DIR/lang-item-generic-requirements.rs:24:22
- |
-LL | struct MyPhantomData<T, U>;
- | ^ unused parameter
- |
- = help: consider removing `T` or referring to it in a field
- = help: if you intended `T` to be a const parameter, use `const T: usize` instead
-
-error[E0392]: parameter `U` is never used
- --> $DIR/lang-item-generic-requirements.rs:24:25
- |
-LL | struct MyPhantomData<T, U>;
- | ^ unused parameter
- |
- = help: consider removing `U` or referring to it in a field
- = help: if you intended `U` to be a const parameter, use `const U: usize` instead
-
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
-Some errors have detailed explanations: E0392, E0718.
-For more information about an error, try `rustc --explain E0392`.
+For more information about this error, try `rustc --explain E0718`.
diff --git a/src/test/ui/lang-items/lang-item-missing-generator.rs b/src/test/ui/lang-items/lang-item-missing-generator.rs
index 0c3295429..9b9aff38e 100644
--- a/src/test/ui/lang-items/lang-item-missing-generator.rs
+++ b/src/test/ui/lang-items/lang-item-missing-generator.rs
@@ -1,12 +1,14 @@
// error-pattern: requires `generator` lang_item
-#![feature(no_core, lang_items, unboxed_closures)]
+#![feature(no_core, lang_items, unboxed_closures, tuple_trait)]
#![no_core]
#[lang = "sized"] pub trait Sized { }
+#[lang = "tuple_trait"] pub trait Tuple { }
+
#[lang = "fn_once"]
#[rustc_paren_sugar]
-pub trait FnOnce<Args> {
+pub trait FnOnce<Args: Tuple> {
type Output;
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
diff --git a/src/test/ui/lang-items/lang-item-missing-generator.stderr b/src/test/ui/lang-items/lang-item-missing-generator.stderr
index fa13bf0b1..a24fdb5fb 100644
--- a/src/test/ui/lang-items/lang-item-missing-generator.stderr
+++ b/src/test/ui/lang-items/lang-item-missing-generator.stderr
@@ -1,8 +1,15 @@
+error[E0635]: unknown feature `tuple_trait`
+ --> $DIR/lang-item-missing-generator.rs:2:51
+ |
+LL | #![feature(no_core, lang_items, unboxed_closures, tuple_trait)]
+ | ^^^^^^^^^^^
+
error: requires `generator` lang_item
- --> $DIR/lang-item-missing-generator.rs:15:17
+ --> $DIR/lang-item-missing-generator.rs:17:17
|
LL | pub fn abc() -> impl FnOnce(f32) {
| ^^^^^^^^^^^^^^^^
-error: aborting due to previous error
+error: aborting due to 2 previous errors
+For more information about this error, try `rustc --explain E0635`.
diff --git a/src/test/ui/lang-items/missing-clone-for-suggestion.rs b/src/test/ui/lang-items/missing-clone-for-suggestion.rs
new file mode 100644
index 000000000..e8290c009
--- /dev/null
+++ b/src/test/ui/lang-items/missing-clone-for-suggestion.rs
@@ -0,0 +1,20 @@
+// Avoid panicking if the Clone trait is not found while building error suggestions
+// See #104870
+
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+fn g<T>(x: T) {}
+
+fn f(x: *mut u8) {
+ g(x);
+ g(x); //~ ERROR use of moved value: `x`
+}
+
+fn main() {}
diff --git a/src/test/ui/lang-items/missing-clone-for-suggestion.stderr b/src/test/ui/lang-items/missing-clone-for-suggestion.stderr
new file mode 100644
index 000000000..35783a1be
--- /dev/null
+++ b/src/test/ui/lang-items/missing-clone-for-suggestion.stderr
@@ -0,0 +1,21 @@
+error[E0382]: use of moved value: `x`
+ --> $DIR/missing-clone-for-suggestion.rs:17:7
+ |
+LL | fn f(x: *mut u8) {
+ | - move occurs because `x` has type `*mut u8`, which does not implement the `Copy` trait
+LL | g(x);
+ | - value moved here
+LL | g(x);
+ | ^ value used here after move
+ |
+note: consider changing this parameter type in function `g` to borrow instead if owning the value isn't necessary
+ --> $DIR/missing-clone-for-suggestion.rs:13:12
+ |
+LL | fn g<T>(x: T) {}
+ | - ^ this parameter takes ownership of the value
+ | |
+ | in this function
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/late-bound-lifetimes/auxiliary/upstream_alias.rs b/src/test/ui/late-bound-lifetimes/auxiliary/upstream_alias.rs
new file mode 100644
index 000000000..5b9dc0e43
--- /dev/null
+++ b/src/test/ui/late-bound-lifetimes/auxiliary/upstream_alias.rs
@@ -0,0 +1,5 @@
+pub trait Trait<'a> {
+ type Assoc;
+}
+
+pub type Alias<'a, T> = <T as Trait<'a>>::Assoc;
diff --git a/src/test/ui/late-bound-lifetimes/cross_crate_alias.rs b/src/test/ui/late-bound-lifetimes/cross_crate_alias.rs
new file mode 100644
index 000000000..4154c2792
--- /dev/null
+++ b/src/test/ui/late-bound-lifetimes/cross_crate_alias.rs
@@ -0,0 +1,10 @@
+// aux-build:upstream_alias.rs
+// check-pass
+
+extern crate upstream_alias;
+
+fn foo<'a, T: for<'b> upstream_alias::Trait<'b>>(_: upstream_alias::Alias<'a, T>) -> &'a () {
+ todo!()
+}
+
+fn main() {}
diff --git a/src/test/ui/late-bound-lifetimes/downgraded_to_early_through_alias.rs b/src/test/ui/late-bound-lifetimes/downgraded_to_early_through_alias.rs
new file mode 100644
index 000000000..e56a34218
--- /dev/null
+++ b/src/test/ui/late-bound-lifetimes/downgraded_to_early_through_alias.rs
@@ -0,0 +1,24 @@
+// check-pass
+
+trait Gats<'a> {
+ type Assoc;
+ type Assoc2;
+}
+
+trait Trait: for<'a> Gats<'a> {
+ fn foo<'a>(_: &mut <Self as Gats<'a>>::Assoc) -> <Self as Gats<'a>>::Assoc2;
+}
+
+impl<'a> Gats<'a> for () {
+ type Assoc = &'a u32;
+ type Assoc2 = ();
+}
+
+type GatsAssoc<'a, T> = <T as Gats<'a>>::Assoc;
+type GatsAssoc2<'a, T> = <T as Gats<'a>>::Assoc2;
+
+impl Trait for () {
+ fn foo<'a>(_: &mut GatsAssoc<'a, Self>) -> GatsAssoc2<'a, Self> {}
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-47511.rs b/src/test/ui/late-bound-lifetimes/issue-47511.rs
index eb4860e75..789443515 100644
--- a/src/test/ui/issues/issue-47511.rs
+++ b/src/test/ui/late-bound-lifetimes/issue-47511.rs
@@ -1,9 +1,4 @@
-// check-fail
-// known-bug: #47511
-
-// Regression test for #47511: anonymous lifetimes can appear
-// unconstrained in a return type, but only if they appear just once
-// in the input, as the input to a projection.
+// check-pass
fn f(_: X) -> X {
unimplemented!()
diff --git a/src/test/ui/late-bound-lifetimes/late_bound_through_alias.rs b/src/test/ui/late-bound-lifetimes/late_bound_through_alias.rs
new file mode 100644
index 000000000..91839673c
--- /dev/null
+++ b/src/test/ui/late-bound-lifetimes/late_bound_through_alias.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+fn f(_: X) -> X {
+ unimplemented!()
+}
+
+fn g<'a>(_: X<'a>) -> X<'a> {
+ unimplemented!()
+}
+
+type X<'a> = &'a ();
+
+fn main() {
+ let _: for<'a> fn(X<'a>) -> X<'a> = g;
+ let _: for<'a> fn(X<'a>) -> X<'a> = f;
+}
diff --git a/src/test/ui/late-bound-lifetimes/mismatched_arg_count.rs b/src/test/ui/late-bound-lifetimes/mismatched_arg_count.rs
new file mode 100644
index 000000000..0b331e203
--- /dev/null
+++ b/src/test/ui/late-bound-lifetimes/mismatched_arg_count.rs
@@ -0,0 +1,12 @@
+// ensures that we don't ICE when there are too many args supplied to the alias.
+
+trait Trait<'a> {
+ type Assoc;
+}
+
+type Alias<'a, T> = <T as Trait<'a>>::Assoc;
+
+fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {}
+//~^ error: this type alias takes 1 lifetime argument but 2 lifetime arguments were supplied
+
+fn main() {}
diff --git a/src/test/ui/late-bound-lifetimes/mismatched_arg_count.stderr b/src/test/ui/late-bound-lifetimes/mismatched_arg_count.stderr
new file mode 100644
index 000000000..3704d9bb9
--- /dev/null
+++ b/src/test/ui/late-bound-lifetimes/mismatched_arg_count.stderr
@@ -0,0 +1,17 @@
+error[E0107]: this type alias takes 1 lifetime argument but 2 lifetime arguments were supplied
+ --> $DIR/mismatched_arg_count.rs:9:29
+ |
+LL | fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {}
+ | ^^^^^ -- help: remove this lifetime argument
+ | |
+ | expected 1 lifetime argument
+ |
+note: type alias defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/mismatched_arg_count.rs:7:6
+ |
+LL | type Alias<'a, T> = <T as Trait<'a>>::Assoc;
+ | ^^^^^ --
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
index bfabe2d12..20d4c418e 100644
--- a/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
+++ b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
@@ -370,23 +370,23 @@ error: layout_of(NicheFirst) = Layout {
pref: $PREF_ALIGN,
},
abi: ScalarPair(
- Initialized {
+ Union {
value: Int(
I8,
false,
),
- valid_range: 0..=4,
},
- Union {
+ Initialized {
value: Int(
I8,
false,
),
+ valid_range: 0..=4,
},
),
fields: Arbitrary {
offsets: [
- Size(0 bytes),
+ Size(1 bytes),
],
memory_index: [
0,
@@ -394,7 +394,7 @@ error: layout_of(NicheFirst) = Layout {
},
largest_niche: Some(
Niche {
- offset: Size(0 bytes),
+ offset: Size(1 bytes),
value: Int(
I8,
false,
@@ -429,29 +429,29 @@ error: layout_of(NicheFirst) = Layout {
I8,
false,
),
- valid_range: 0..=2,
+ valid_range: 0..=255,
},
Initialized {
value: Int(
I8,
false,
),
- valid_range: 0..=255,
+ valid_range: 0..=2,
},
),
fields: Arbitrary {
offsets: [
- Size(0 bytes),
Size(1 bytes),
+ Size(0 bytes),
],
memory_index: [
- 0,
1,
+ 0,
],
},
largest_niche: Some(
Niche {
- offset: Size(0 bytes),
+ offset: Size(1 bytes),
value: Int(
I8,
false,
diff --git a/src/test/ui/layout/valid_range_oob.rs b/src/test/ui/layout/valid_range_oob.rs
new file mode 100644
index 000000000..74aa47fe4
--- /dev/null
+++ b/src/test/ui/layout/valid_range_oob.rs
@@ -0,0 +1,15 @@
+// failure-status: 101
+// normalize-stderr-test "note: .*\n\n" -> ""
+// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+// rustc-env:RUST_BACKTRACE=0
+
+#![feature(rustc_attrs)]
+
+#[rustc_layout_scalar_valid_range_end(257)]
+struct Foo(i8);
+
+// Need to do in a constant, as runtime codegen
+// does not compute the layout of `Foo` in check builds.
+const FOO: Foo = unsafe { Foo(1) };
+
+fn main() {}
diff --git a/src/test/ui/layout/valid_range_oob.stderr b/src/test/ui/layout/valid_range_oob.stderr
new file mode 100644
index 000000000..7398f0164
--- /dev/null
+++ b/src/test/ui/layout/valid_range_oob.stderr
@@ -0,0 +1,6 @@
+error: internal compiler error: unexpected panic
+
+query stack during panic:
+#0 [layout_of] computing layout of `Foo`
+#1 [eval_to_allocation_raw] const-evaluating + checking `FOO`
+end of query stack
diff --git a/src/test/ui/lazy-type-alias-impl-trait/freeze_cycle.rs b/src/test/ui/lazy-type-alias-impl-trait/freeze_cycle.rs
index 10f6bd740..f02a93ed4 100644
--- a/src/test/ui/lazy-type-alias-impl-trait/freeze_cycle.rs
+++ b/src/test/ui/lazy-type-alias-impl-trait/freeze_cycle.rs
@@ -1,6 +1,6 @@
// check-pass
-#![feature(gen_future, generator_trait, negative_impls)]
+#![feature(generator_trait, negative_impls)]
use std::ops::{Generator, GeneratorState};
use std::task::{Poll, Context};
diff --git a/src/test/ui/let-else/let-else-irrefutable.rs b/src/test/ui/let-else/let-else-irrefutable.rs
index 1cb68ecb8..f4b338eb0 100644
--- a/src/test/ui/let-else/let-else-irrefutable.rs
+++ b/src/test/ui/let-else/let-else-irrefutable.rs
@@ -1,7 +1,11 @@
// check-pass
-
-
fn main() {
let x = 1 else { return }; //~ WARN irrefutable `let...else` pattern
+
+ // Multiline else blocks should not get printed
+ let x = 1 else { //~ WARN irrefutable `let...else` pattern
+ eprintln!("problem case encountered");
+ return
+ };
}
diff --git a/src/test/ui/let-else/let-else-irrefutable.stderr b/src/test/ui/let-else/let-else-irrefutable.stderr
index e0581f4d9..73d4e5f34 100644
--- a/src/test/ui/let-else/let-else-irrefutable.stderr
+++ b/src/test/ui/let-else/let-else-irrefutable.stderr
@@ -1,12 +1,21 @@
warning: irrefutable `let...else` pattern
- --> $DIR/let-else-irrefutable.rs:6:5
+ --> $DIR/let-else-irrefutable.rs:4:5
|
LL | let x = 1 else { return };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^
|
= note: this pattern will always match, so the `else` clause is useless
= help: consider removing the `else` clause
= note: `#[warn(irrefutable_let_patterns)]` on by default
-warning: 1 warning emitted
+warning: irrefutable `let...else` pattern
+ --> $DIR/let-else-irrefutable.rs:7:5
+ |
+LL | let x = 1 else {
+ | ^^^^^^^^^
+ |
+ = note: this pattern will always match, so the `else` clause is useless
+ = help: consider removing the `else` clause
+
+warning: 2 warnings emitted
diff --git a/src/test/ui/lexer/error-stage.rs b/src/test/ui/lexer/error-stage.rs
new file mode 100644
index 000000000..c8d88f745
--- /dev/null
+++ b/src/test/ui/lexer/error-stage.rs
@@ -0,0 +1,80 @@
+// This test is about the treatment of invalid literals. In particular, some
+// literals are only considered invalid if they survive to HIR lowering.
+//
+// Literals with bad suffixes
+// --------------------------
+// Literals consist of a primary part and an optional suffix.
+// https://doc.rust-lang.org/reference/tokens.html#suffixes says:
+//
+// Any kind of literal (string, integer, etc) with any suffix is valid as a
+// token, and can be passed to a macro without producing an error. The macro
+// itself will decide how to interpret such a token and whether to produce an
+// error or not.
+//
+// ```
+// macro_rules! blackhole { ($tt:tt) => () }
+// blackhole!("string"suffix); // OK
+// ```
+//
+// However, suffixes on literal tokens parsed as Rust code are restricted.
+// Any suffixes are rejected on non-numeric literal tokens, and numeric
+// literal tokens are accepted only with suffixes from the list below.
+//
+// Integer: u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize
+// Floating-point: f32, f64
+//
+// This means that something like `"string"any_suffix` is a token accepted by
+// the lexer, but rejected later for being an invalid combination of primary
+// part and suffix.
+//
+// `0b10f32` is a similar case. `0b10` is a valid primary part that is a valid
+// *integer* literal when no suffix is present. It only causes an error later
+// when combined with the `f32` float suffix.
+//
+// However, `0b10.0f32` is different. It is rejected by the lexer because
+// `0b10.0` is not a valid token even on its own.
+//
+// This difference is unfortunate, but it's baked into the language now.
+//
+// Too-large integer literals
+// --------------------------
+// https://doc.rust-lang.org/reference/tokens.html#integer-literals says that
+// literals like `128_i8` and `256_u8` "are too big for their type, but are
+// still valid tokens".
+
+macro_rules! sink {
+ ($($x:tt;)*) => {()}
+}
+
+// The invalid literals are ignored because the macro consumes them. Except for
+// `0b10.0f32` because it's a lexer error.
+const _: () = sink! {
+ "string"any_suffix; // OK
+ 10u123; // OK
+ 10.0f123; // OK
+ 0b10f32; // OK
+ 0b10.0f32; //~ ERROR binary float literal is not supported
+ 999340282366920938463463374607431768211455999; // OK
+};
+
+// The invalid literals used to cause errors, but this was changed by #102944.
+// Except for `0b010.0f32`, because it's a lexer error.
+#[cfg(FALSE)]
+fn configured_out() {
+ "string"any_suffix; // OK
+ 10u123; // OK
+ 10.0f123; // OK
+ 0b10f32; // OK
+ 0b10.0f32; //~ ERROR binary float literal is not supported
+ 999340282366920938463463374607431768211455999; // OK
+}
+
+// All the invalid literals cause errors.
+fn main() {
+ "string"any_suffix; //~ ERROR suffixes on string literals are invalid
+ 10u123; //~ ERROR invalid width `123` for integer literal
+ 10.0f123; //~ ERROR invalid width `123` for float literal
+ 0b10f32; //~ ERROR binary float literal is not supported
+ 0b10.0f32; //~ ERROR binary float literal is not supported
+ 999340282366920938463463374607431768211455999; //~ ERROR integer literal is too large
+}
diff --git a/src/test/ui/lexer/error-stage.stderr b/src/test/ui/lexer/error-stage.stderr
new file mode 100644
index 000000000..697a7c28d
--- /dev/null
+++ b/src/test/ui/lexer/error-stage.stderr
@@ -0,0 +1,54 @@
+error: binary float literal is not supported
+ --> $DIR/error-stage.rs:56:5
+ |
+LL | 0b10.0f32;
+ | ^^^^^^
+
+error: binary float literal is not supported
+ --> $DIR/error-stage.rs:68:5
+ |
+LL | 0b10.0f32;
+ | ^^^^^^
+
+error: binary float literal is not supported
+ --> $DIR/error-stage.rs:78:5
+ |
+LL | 0b10.0f32;
+ | ^^^^^^
+
+error: suffixes on string literals are invalid
+ --> $DIR/error-stage.rs:74:5
+ |
+LL | "string"any_suffix;
+ | ^^^^^^^^^^^^^^^^^^ invalid suffix `any_suffix`
+
+error: invalid width `123` for integer literal
+ --> $DIR/error-stage.rs:75:5
+ |
+LL | 10u123;
+ | ^^^^^^
+ |
+ = help: valid widths are 8, 16, 32, 64 and 128
+
+error: invalid width `123` for float literal
+ --> $DIR/error-stage.rs:76:5
+ |
+LL | 10.0f123;
+ | ^^^^^^^^
+ |
+ = help: valid widths are 32 and 64
+
+error: binary float literal is not supported
+ --> $DIR/error-stage.rs:77:5
+ |
+LL | 0b10f32;
+ | ^^^^^^^ not supported
+
+error: integer literal is too large
+ --> $DIR/error-stage.rs:79:5
+ |
+LL | 999340282366920938463463374607431768211455999;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/lexer/lex-bad-char-literals-6.stderr b/src/test/ui/lexer/lex-bad-char-literals-6.stderr
index afef0cb60..ce4194246 100644
--- a/src/test/ui/lexer/lex-bad-char-literals-6.stderr
+++ b/src/test/ui/lexer/lex-bad-char-literals-6.stderr
@@ -42,12 +42,11 @@ LL | if x == y {}
<&'a str as PartialEq<OsString>>
<&'a str as PartialEq<String>>
<&'b str as PartialEq<Cow<'a, str>>>
- <String as PartialEq<&'a str>>
- <String as PartialEq<Cow<'a, str>>>
- <String as PartialEq<str>>
- <String as PartialEq>
<str as PartialEq<Cow<'a, str>>>
- and 4 others
+ <str as PartialEq<OsStr>>
+ <str as PartialEq<OsString>>
+ <str as PartialEq<String>>
+ <str as PartialEq>
error[E0308]: mismatched types
--> $DIR/lex-bad-char-literals-6.rs:15:20
@@ -68,12 +67,11 @@ LL | if x == z {}
<&'a str as PartialEq<OsString>>
<&'a str as PartialEq<String>>
<&'b str as PartialEq<Cow<'a, str>>>
- <String as PartialEq<&'a str>>
- <String as PartialEq<Cow<'a, str>>>
- <String as PartialEq<str>>
- <String as PartialEq>
<str as PartialEq<Cow<'a, str>>>
- and 4 others
+ <str as PartialEq<OsStr>>
+ <str as PartialEq<OsString>>
+ <str as PartialEq<String>>
+ <str as PartialEq>
error: aborting due to 6 previous errors
diff --git a/src/test/ui/lexical-scopes.stderr b/src/test/ui/lexical-scopes.stderr
index 535985452..f0eaa1a5c 100644
--- a/src/test/ui/lexical-scopes.stderr
+++ b/src/test/ui/lexical-scopes.stderr
@@ -2,7 +2,7 @@ error[E0574]: expected struct, variant or union type, found type parameter `T`
--> $DIR/lexical-scopes.rs:3:13
|
LL | struct T { i: i32 }
- | ------------------- you might have meant to refer to this struct
+ | - you might have meant to refer to this struct
LL | fn f<T>() {
| - found this type parameter
LL | let t = T { i: 0 };
diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
index bbf04c984..987b051b1 100644
--- a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
+++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let mut x = vec![1].iter();
| ^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
LL |
LL | x.use_mut();
| ----------- borrow later used here
diff --git a/src/test/ui/limits/issue-55878.stderr b/src/test/ui/limits/issue-55878.stderr
index ee6aab748..f17f8141b 100644
--- a/src/test/ui/limits/issue-55878.stderr
+++ b/src/test/ui/limits/issue-55878.stderr
@@ -2,21 +2,43 @@ error[E0080]: values of the type `[u8; SIZE]` are too big for the current archit
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | intrinsics::size_of::<T>()
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ inside `std::mem::size_of::<[u8; SIZE]>` at $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- ::: $DIR/issue-55878.rs:7:26
+note: inside `std::mem::size_of::<[u8; SIZE]>`
+ --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+ |
+LL | intrinsics::size_of::<T>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `main`
+ --> $DIR/issue-55878.rs:7:26
+ |
+LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/issue-55878.rs:7:26
|
LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
- | ---------------------------------------------- inside `main` at $DIR/issue-55878.rs:7:26
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/issue-55878.rs:7:26
+ |
+LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/issue-55878.rs:7:26
|
LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>());
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/linkage-attr/auxiliary/def_illtyped_external.rs b/src/test/ui/linkage-attr/auxiliary/def_external.rs
index 2300930e5..2300930e5 100644
--- a/src/test/ui/linkage-attr/auxiliary/def_illtyped_external.rs
+++ b/src/test/ui/linkage-attr/auxiliary/def_external.rs
diff --git a/src/test/ui/linkage-attr/link-attr-validation-late.rs b/src/test/ui/linkage-attr/link-attr-validation-late.rs
index b454fbd0e..34f720dd2 100644
--- a/src/test/ui/linkage-attr/link-attr-validation-late.rs
+++ b/src/test/ui/linkage-attr/link-attr-validation-late.rs
@@ -1,4 +1,3 @@
-#![feature(native_link_modifiers_verbatim)]
#![feature(link_cfg)]
// Top-level ill-formed
diff --git a/src/test/ui/linkage-attr/link-attr-validation-late.stderr b/src/test/ui/linkage-attr/link-attr-validation-late.stderr
index dd0f1dba2..1ad5fbaf7 100644
--- a/src/test/ui/linkage-attr/link-attr-validation-late.stderr
+++ b/src/test/ui/linkage-attr/link-attr-validation-late.stderr
@@ -1,143 +1,143 @@
error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
- --> $DIR/link-attr-validation-late.rs:5:22
+ --> $DIR/link-attr-validation-late.rs:4:22
|
LL | #[link(name = "...", "literal")]
| ^^^^^^^^^
error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type
- --> $DIR/link-attr-validation-late.rs:6:22
+ --> $DIR/link-attr-validation-late.rs:5:22
|
LL | #[link(name = "...", unknown)]
| ^^^^^^^
error: multiple `name` arguments in a single `#[link]` attribute
- --> $DIR/link-attr-validation-late.rs:10:22
+ --> $DIR/link-attr-validation-late.rs:9:22
|
LL | #[link(name = "foo", name = "bar")]
| ^^^^^^^^^^^^
error: multiple `kind` arguments in a single `#[link]` attribute
- --> $DIR/link-attr-validation-late.rs:11:38
+ --> $DIR/link-attr-validation-late.rs:10:38
|
LL | #[link(name = "...", kind = "dylib", kind = "bar")]
| ^^^^^^^^^^^^
error: multiple `modifiers` arguments in a single `#[link]` attribute
- --> $DIR/link-attr-validation-late.rs:12:47
+ --> $DIR/link-attr-validation-late.rs:11:47
|
LL | #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")]
| ^^^^^^^^^^^^^^^^^
error: multiple `cfg` arguments in a single `#[link]` attribute
- --> $DIR/link-attr-validation-late.rs:13:34
+ --> $DIR/link-attr-validation-late.rs:12:34
|
LL | #[link(name = "...", cfg(FALSE), cfg(FALSE))]
| ^^^^^^^^^^
error: multiple `wasm_import_module` arguments in a single `#[link]` attribute
- --> $DIR/link-attr-validation-late.rs:14:36
+ --> $DIR/link-attr-validation-late.rs:13:36
|
LL | #[link(wasm_import_module = "foo", wasm_import_module = "bar")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: link name must be of the form `name = "string"`
- --> $DIR/link-attr-validation-late.rs:18:8
+ --> $DIR/link-attr-validation-late.rs:17:8
|
LL | #[link(name)]
| ^^^^
error[E0459]: `#[link]` attribute requires a `name = "string"` argument
- --> $DIR/link-attr-validation-late.rs:18:1
+ --> $DIR/link-attr-validation-late.rs:17:1
|
LL | #[link(name)]
| ^^^^^^^^^^^^^ missing `name` argument
error: link name must be of the form `name = "string"`
- --> $DIR/link-attr-validation-late.rs:20:8
+ --> $DIR/link-attr-validation-late.rs:19:8
|
LL | #[link(name())]
| ^^^^^^
error[E0459]: `#[link]` attribute requires a `name = "string"` argument
- --> $DIR/link-attr-validation-late.rs:20:1
+ --> $DIR/link-attr-validation-late.rs:19:1
|
LL | #[link(name())]
| ^^^^^^^^^^^^^^^ missing `name` argument
error: link kind must be of the form `kind = "string"`
- --> $DIR/link-attr-validation-late.rs:22:22
+ --> $DIR/link-attr-validation-late.rs:21:22
|
LL | #[link(name = "...", kind)]
| ^^^^
error: link kind must be of the form `kind = "string"`
- --> $DIR/link-attr-validation-late.rs:23:22
+ --> $DIR/link-attr-validation-late.rs:22:22
|
LL | #[link(name = "...", kind())]
| ^^^^^^
error: link modifiers must be of the form `modifiers = "string"`
- --> $DIR/link-attr-validation-late.rs:24:22
+ --> $DIR/link-attr-validation-late.rs:23:22
|
LL | #[link(name = "...", modifiers)]
| ^^^^^^^^^
error: link modifiers must be of the form `modifiers = "string"`
- --> $DIR/link-attr-validation-late.rs:25:22
+ --> $DIR/link-attr-validation-late.rs:24:22
|
LL | #[link(name = "...", modifiers())]
| ^^^^^^^^^^^
error: link cfg must be of the form `cfg(/* predicate */)`
- --> $DIR/link-attr-validation-late.rs:26:22
+ --> $DIR/link-attr-validation-late.rs:25:22
|
LL | #[link(name = "...", cfg)]
| ^^^
error: link cfg must be of the form `cfg(/* predicate */)`
- --> $DIR/link-attr-validation-late.rs:27:22
+ --> $DIR/link-attr-validation-late.rs:26:22
|
LL | #[link(name = "...", cfg = "literal")]
| ^^^^^^^^^^^^^^^
error: link cfg must have a single predicate argument
- --> $DIR/link-attr-validation-late.rs:28:22
+ --> $DIR/link-attr-validation-late.rs:27:22
|
LL | #[link(name = "...", cfg("literal"))]
| ^^^^^^^^^^^^^^
error: wasm import module must be of the form `wasm_import_module = "string"`
- --> $DIR/link-attr-validation-late.rs:29:22
+ --> $DIR/link-attr-validation-late.rs:28:22
|
LL | #[link(name = "...", wasm_import_module)]
| ^^^^^^^^^^^^^^^^^^
error: wasm import module must be of the form `wasm_import_module = "string"`
- --> $DIR/link-attr-validation-late.rs:30:22
+ --> $DIR/link-attr-validation-late.rs:29:22
|
LL | #[link(name = "...", wasm_import_module())]
| ^^^^^^^^^^^^^^^^^^^^
error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
- --> $DIR/link-attr-validation-late.rs:34:34
+ --> $DIR/link-attr-validation-late.rs:33:34
|
LL | #[link(name = "...", modifiers = "")]
| ^^
error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
- --> $DIR/link-attr-validation-late.rs:35:34
+ --> $DIR/link-attr-validation-late.rs:34:34
|
LL | #[link(name = "...", modifiers = "no-plus-minus")]
| ^^^^^^^^^^^^^^^
error: unknown linking modifier `unknown`, expected one of: bundle, verbatim, whole-archive, as-needed
- --> $DIR/link-attr-validation-late.rs:36:34
+ --> $DIR/link-attr-validation-late.rs:35:34
|
LL | #[link(name = "...", modifiers = "+unknown")]
| ^^^^^^^^^^
error: multiple `verbatim` modifiers in a single `modifiers` argument
- --> $DIR/link-attr-validation-late.rs:37:34
+ --> $DIR/link-attr-validation-late.rs:36:34
|
LL | #[link(name = "...", modifiers = "+verbatim,+verbatim")]
| ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/linkage-attr/linkage-import.rs b/src/test/ui/linkage-attr/linkage-import.rs
new file mode 100644
index 000000000..f754ddc6e
--- /dev/null
+++ b/src/test/ui/linkage-attr/linkage-import.rs
@@ -0,0 +1,8 @@
+// build-pass
+// aux-build:def_external.rs
+
+extern crate def_external as dep;
+
+fn main() {
+ println!("{:p}", &dep::EXTERN);
+}
diff --git a/src/test/ui/linkage-attr/linkage-requires-raw-ptr.rs b/src/test/ui/linkage-attr/linkage-requires-raw-ptr.rs
deleted file mode 100644
index 93afc537f..000000000
--- a/src/test/ui/linkage-attr/linkage-requires-raw-ptr.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// rust-lang/rust#59548: We used to ICE when trying to use a static
-// with a type that violated its own `#[linkage]`.
-
-// build-fail
-// aux-build:def_illtyped_external.rs
-
-extern crate def_illtyped_external as dep;
-
-fn main() {
- println!("{:p}", &dep::EXTERN);
-}
diff --git a/src/test/ui/linkage-attr/linkage-requires-raw-ptr.stderr b/src/test/ui/linkage-attr/linkage-requires-raw-ptr.stderr
deleted file mode 100644
index 5abbe745c..000000000
--- a/src/test/ui/linkage-attr/linkage-requires-raw-ptr.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: must have type `*const T` or `*mut T` due to `#[linkage]` attribute
- --> $DIR/auxiliary/def_illtyped_external.rs:5:1
- |
-LL | pub static EXTERN: u32 = 0;
- | ^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/linkage-attr/linkage2.rs b/src/test/ui/linkage-attr/linkage2.rs
index a7be19852..aa42874f7 100644
--- a/src/test/ui/linkage-attr/linkage2.rs
+++ b/src/test/ui/linkage-attr/linkage2.rs
@@ -1,16 +1,11 @@
-// FIXME https://github.com/rust-lang/rust/issues/59774
-
-// build-fail
-// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> ""
-// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
-// ignore-sgx no weak linkages permitted
+// check-fail
#![feature(linkage)]
extern "C" {
#[linkage = "extern_weak"]
static foo: i32;
-//~^ ERROR: must have type `*const T` or `*mut T` due to `#[linkage]` attribute
+//~^ ERROR: invalid type for variable with `#[linkage]` attribute
}
fn main() {
diff --git a/src/test/ui/linkage-attr/linkage2.stderr b/src/test/ui/linkage-attr/linkage2.stderr
index a6ac0aad0..7265f711f 100644
--- a/src/test/ui/linkage-attr/linkage2.stderr
+++ b/src/test/ui/linkage-attr/linkage2.stderr
@@ -1,8 +1,9 @@
-error: must have type `*const T` or `*mut T` due to `#[linkage]` attribute
- --> $DIR/linkage2.rs:12:5
+error[E0791]: invalid type for variable with `#[linkage]` attribute
+ --> $DIR/linkage2.rs:7:5
|
LL | static foo: i32;
| ^^^^^^^^^^^^^^^
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0791`.
diff --git a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs
index e3935cf91..2003e1e29 100644
--- a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs
+++ b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs
@@ -7,7 +7,7 @@ struct Bar {
b: usize, //~ ERROR field `b` is never read
#[deny(dead_code)]
c: usize, //~ ERROR fields `c` and `e` are never read
- d: usize, //~ WARN fields `d`, `f` and `g` are never read
+ d: usize, //~ WARN fields `d`, `f`, and `g` are never read
#[deny(dead_code)]
e: usize,
f: usize,
diff --git a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
index c0f1ed38f..0e5c78a71 100644
--- a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
+++ b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
@@ -1,4 +1,4 @@
-warning: fields `d`, `f` and `g` are never read
+warning: fields `d`, `f`, and `g` are never read
--> $DIR/multiple-dead-codes-in-the-same-struct.rs:10:5
|
LL | struct Bar {
diff --git a/src/test/ui/lint/dead-code/tuple-struct-field.rs b/src/test/ui/lint/dead-code/tuple-struct-field.rs
index b15d70636..14fb30be9 100644
--- a/src/test/ui/lint/dead-code/tuple-struct-field.rs
+++ b/src/test/ui/lint/dead-code/tuple-struct-field.rs
@@ -11,7 +11,7 @@ struct SingleUnused(i32, [u8; LEN], String);
//~| HELP: consider changing the field to be of unit type
struct MultipleUnused(i32, f32, String, u8);
-//~^ ERROR: fields `0`, `1`, `2` and `3` are never read
+//~^ ERROR: fields `0`, `1`, `2`, and `3` are never read
//~| NOTE: fields in this struct
//~| HELP: consider changing the fields to be of unit type
diff --git a/src/test/ui/lint/dead-code/tuple-struct-field.stderr b/src/test/ui/lint/dead-code/tuple-struct-field.stderr
index ca0989f5b..b8ad5cbe4 100644
--- a/src/test/ui/lint/dead-code/tuple-struct-field.stderr
+++ b/src/test/ui/lint/dead-code/tuple-struct-field.stderr
@@ -16,7 +16,7 @@ help: consider changing the field to be of unit type to suppress this warning wh
LL | struct SingleUnused(i32, (), String);
| ~~
-error: fields `0`, `1`, `2` and `3` are never read
+error: fields `0`, `1`, `2`, and `3` are never read
--> $DIR/tuple-struct-field.rs:13:23
|
LL | struct MultipleUnused(i32, f32, String, u8);
diff --git a/src/test/ui/lint/fn_must_use.stderr b/src/test/ui/lint/fn_must_use.stderr
index 2805720f0..657f23c60 100644
--- a/src/test/ui/lint/fn_must_use.stderr
+++ b/src/test/ui/lint/fn_must_use.stderr
@@ -2,7 +2,7 @@ warning: unused return value of `need_to_use_this_value` that must be used
--> $DIR/fn_must_use.rs:55:5
|
LL | need_to_use_this_value();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: it's important
note: the lint level is defined here
@@ -15,13 +15,13 @@ warning: unused return value of `MyStruct::need_to_use_this_method_value` that m
--> $DIR/fn_must_use.rs:60:5
|
LL | m.need_to_use_this_method_value();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused return value of `EvenNature::is_even` that must be used
--> $DIR/fn_must_use.rs:61:5
|
LL | m.is_even(); // trait method!
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^
|
= note: no side effects
@@ -29,19 +29,19 @@ warning: unused return value of `MyStruct::need_to_use_this_associated_function_
--> $DIR/fn_must_use.rs:64:5
|
LL | MyStruct::need_to_use_this_associated_function_value();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused return value of `std::cmp::PartialEq::eq` that must be used
--> $DIR/fn_must_use.rs:70:5
|
LL | 2.eq(&3);
- | ^^^^^^^^^
+ | ^^^^^^^^
warning: unused return value of `std::cmp::PartialEq::eq` that must be used
--> $DIR/fn_must_use.rs:71:5
|
LL | m.eq(&n);
- | ^^^^^^^^^
+ | ^^^^^^^^
warning: unused comparison that must be used
--> $DIR/fn_must_use.rs:74:5
diff --git a/src/test/ui/lint/invalid_value.stderr b/src/test/ui/lint/invalid_value.stderr
index 76afb765f..5370660d6 100644
--- a/src/test/ui/lint/invalid_value.stderr
+++ b/src/test/ui/lint/invalid_value.stderr
@@ -34,7 +34,8 @@ LL | let _val: Wrap<&'static T> = mem::zeroed();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: references must be non-null (in this struct field)
+ = note: `Wrap<&T>` must be non-null
+note: because references must be non-null (in this struct field)
--> $DIR/invalid_value.rs:17:18
|
LL | struct Wrap<T> { wrapped: T }
@@ -49,7 +50,8 @@ LL | let _val: Wrap<&'static T> = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: references must be non-null (in this struct field)
+ = note: `Wrap<&T>` must be non-null
+note: because references must be non-null (in this struct field)
--> $DIR/invalid_value.rs:17:18
|
LL | struct Wrap<T> { wrapped: T }
@@ -97,7 +99,7 @@ LL | let _val: (i32, !) = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
- = note: integers must not be uninitialized
+ = note: integers must be initialized
error: the type `Void` does not permit zero-initialization
--> $DIR/invalid_value.rs:71:26
@@ -160,7 +162,8 @@ LL | let _val: Ref = mem::zeroed();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: references must be non-null (in this struct field)
+ = note: `Ref` must be non-null
+note: because references must be non-null (in this struct field)
--> $DIR/invalid_value.rs:14:12
|
LL | struct Ref(&'static i32);
@@ -175,7 +178,8 @@ LL | let _val: Ref = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: references must be non-null (in this struct field)
+ = note: `Ref` must be non-null
+note: because references must be non-null (in this struct field)
--> $DIR/invalid_value.rs:14:12
|
LL | struct Ref(&'static i32);
@@ -212,7 +216,8 @@ LL | let _val: Wrap<fn()> = mem::zeroed();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: function pointers must be non-null (in this struct field)
+ = note: `Wrap<fn()>` must be non-null
+note: because function pointers must be non-null (in this struct field)
--> $DIR/invalid_value.rs:17:18
|
LL | struct Wrap<T> { wrapped: T }
@@ -227,7 +232,8 @@ LL | let _val: Wrap<fn()> = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: function pointers must be non-null (in this struct field)
+ = note: `Wrap<fn()>` must be non-null
+note: because function pointers must be non-null (in this struct field)
--> $DIR/invalid_value.rs:17:18
|
LL | struct Wrap<T> { wrapped: T }
@@ -242,7 +248,8 @@ LL | let _val: WrapEnum<fn()> = mem::zeroed();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: function pointers must be non-null (in this field of the only potentially inhabited enum variant)
+ = note: `WrapEnum<fn()>` must be non-null
+note: because function pointers must be non-null (in this field of the only potentially inhabited enum variant)
--> $DIR/invalid_value.rs:18:28
|
LL | enum WrapEnum<T> { Wrapped(T) }
@@ -257,7 +264,8 @@ LL | let _val: WrapEnum<fn()> = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: function pointers must be non-null (in this field of the only potentially inhabited enum variant)
+ = note: `WrapEnum<fn()>` must be non-null
+note: because function pointers must be non-null (in this field of the only potentially inhabited enum variant)
--> $DIR/invalid_value.rs:18:28
|
LL | enum WrapEnum<T> { Wrapped(T) }
@@ -272,7 +280,12 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: references must be non-null (in this struct field)
+note: `RefPair` must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:17:18
+ |
+LL | struct Wrap<T> { wrapped: T }
+ | ^^^^^^^^^^
+note: because references must be non-null (in this struct field)
--> $DIR/invalid_value.rs:15:16
|
LL | struct RefPair((&'static i32, i32));
@@ -287,7 +300,12 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: references must be non-null (in this struct field)
+note: `RefPair` must be non-null (in this struct field)
+ --> $DIR/invalid_value.rs:17:18
+ |
+LL | struct Wrap<T> { wrapped: T }
+ | ^^^^^^^^^^
+note: because references must be non-null (in this struct field)
--> $DIR/invalid_value.rs:15:16
|
LL | struct RefPair((&'static i32, i32));
@@ -314,6 +332,7 @@ LL | let _val: NonNull<i32> = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= note: `std::ptr::NonNull<i32>` must be non-null
+ = note: raw pointers must be initialized
error: the type `(NonZeroU32, i32)` does not permit zero-initialization
--> $DIR/invalid_value.rs:95:39
@@ -336,6 +355,7 @@ LL | let _val: (NonZeroU32, i32) = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= note: `std::num::NonZeroU32` must be non-null
+ = note: integers must be initialized
error: the type `*const dyn Send` does not permit zero-initialization
--> $DIR/invalid_value.rs:98:37
@@ -420,7 +440,8 @@ LL | let _val: OneFruitNonZero = mem::zeroed();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
+ = note: `OneFruitNonZero` must be non-null
+note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
--> $DIR/invalid_value.rs:39:12
|
LL | Banana(NonZeroU32),
@@ -435,11 +456,13 @@ LL | let _val: OneFruitNonZero = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
-note: `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
+ = note: `OneFruitNonZero` must be non-null
+note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
--> $DIR/invalid_value.rs:39:12
|
LL | Banana(NonZeroU32),
| ^^^^^^^^^^
+ = note: integers must be initialized
error: the type `bool` does not permit being left uninitialized
--> $DIR/invalid_value.rs:112:26
@@ -461,6 +484,7 @@ LL | let _val: Wrap<char> = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
+ = note: `Wrap<char>` must be initialized inside its custom valid range
note: characters must be a valid Unicode codepoint (in this struct field)
--> $DIR/invalid_value.rs:17:18
|
@@ -477,6 +501,11 @@ LL | let _val: NonBig = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= note: `NonBig` must be initialized inside its custom valid range
+note: integers must be initialized (in this struct field)
+ --> $DIR/invalid_value.rs:23:26
+ |
+LL | pub(crate) struct NonBig(u64);
+ | ^^^
error: the type `Fruit` does not permit being left uninitialized
--> $DIR/invalid_value.rs:121:27
@@ -513,7 +542,7 @@ LL | let _val: i32 = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
- = note: integers must not be uninitialized
+ = note: integers must be initialized
error: the type `f32` does not permit being left uninitialized
--> $DIR/invalid_value.rs:130:25
@@ -524,7 +553,7 @@ LL | let _val: f32 = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
- = note: floats must not be uninitialized
+ = note: floats must be initialized
error: the type `*const ()` does not permit being left uninitialized
--> $DIR/invalid_value.rs:133:31
@@ -535,7 +564,7 @@ LL | let _val: *const () = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
- = note: raw pointers must not be uninitialized
+ = note: raw pointers must be initialized
error: the type `*const [()]` does not permit being left uninitialized
--> $DIR/invalid_value.rs:136:33
@@ -546,7 +575,7 @@ LL | let _val: *const [()] = mem::uninitialized();
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
- = note: raw pointers must not be uninitialized
+ = note: raw pointers must be initialized
error: the type `WrapAroundRange` does not permit being left uninitialized
--> $DIR/invalid_value.rs:139:37
@@ -558,6 +587,11 @@ LL | let _val: WrapAroundRange = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= note: `WrapAroundRange` must be initialized inside its custom valid range
+note: integers must be initialized (in this struct field)
+ --> $DIR/invalid_value.rs:49:35
+ |
+LL | pub(crate) struct WrapAroundRange(u8);
+ | ^^
error: the type `Result<i32, i32>` does not permit being left uninitialized
--> $DIR/invalid_value.rs:144:38
@@ -628,6 +662,7 @@ LL | let _val: NonNull<i32> = MaybeUninit::uninit().assume_init();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= note: `std::ptr::NonNull<i32>` must be non-null
+ = note: raw pointers must be initialized
error: the type `bool` does not permit being left uninitialized
--> $DIR/invalid_value.rs:159:26
diff --git a/src/test/ui/lint/issue-103317.fixed b/src/test/ui/lint/issue-103317.fixed
new file mode 100644
index 000000000..5a987423e
--- /dev/null
+++ b/src/test/ui/lint/issue-103317.fixed
@@ -0,0 +1,14 @@
+// check-pass
+// run-rustfix
+
+#[warn(unreachable_pub)]
+mod inner {
+ #[allow(unused)]
+ pub(crate) enum T {
+ //~^ WARN unreachable `pub` item
+ A(u8),
+ X { a: f32, b: () },
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/issue-103317.rs b/src/test/ui/lint/issue-103317.rs
new file mode 100644
index 000000000..c2ba939e1
--- /dev/null
+++ b/src/test/ui/lint/issue-103317.rs
@@ -0,0 +1,14 @@
+// check-pass
+// run-rustfix
+
+#[warn(unreachable_pub)]
+mod inner {
+ #[allow(unused)]
+ pub enum T {
+ //~^ WARN unreachable `pub` item
+ A(u8),
+ X { a: f32, b: () },
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/issue-103317.stderr b/src/test/ui/lint/issue-103317.stderr
new file mode 100644
index 000000000..9c982ddc3
--- /dev/null
+++ b/src/test/ui/lint/issue-103317.stderr
@@ -0,0 +1,17 @@
+warning: unreachable `pub` item
+ --> $DIR/issue-103317.rs:7:5
+ |
+LL | pub enum T {
+ | ---^^^^^^^
+ | |
+ | help: consider restricting its visibility: `pub(crate)`
+ |
+ = help: or consider exporting it for use by other crates
+note: the lint level is defined here
+ --> $DIR/issue-103317.rs:4:8
+ |
+LL | #[warn(unreachable_pub)]
+ | ^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/lint/issue-103435-extra-parentheses.fixed b/src/test/ui/lint/issue-103435-extra-parentheses.fixed
new file mode 100644
index 000000000..2b01b414b
--- /dev/null
+++ b/src/test/ui/lint/issue-103435-extra-parentheses.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+#![deny(unused_parens)]
+
+fn main() {
+ if let Some(_) = Some(1) {}
+ //~^ ERROR unnecessary parentheses around pattern
+
+ for _x in 1..10 {}
+ //~^ ERROR unnecessary parentheses around pattern
+
+ if 2 == 1 {}
+ //~^ ERROR unnecessary parentheses around `if` condition
+
+ // reported by parser
+ for _x in 1..10 {}
+ //~^ ERROR expected one of
+ //~| ERROR unexpected parentheses surrounding
+}
diff --git a/src/test/ui/lint/issue-103435-extra-parentheses.rs b/src/test/ui/lint/issue-103435-extra-parentheses.rs
new file mode 100644
index 000000000..8261610cf
--- /dev/null
+++ b/src/test/ui/lint/issue-103435-extra-parentheses.rs
@@ -0,0 +1,18 @@
+// run-rustfix
+#![deny(unused_parens)]
+
+fn main() {
+ if let(Some(_))= Some(1) {}
+ //~^ ERROR unnecessary parentheses around pattern
+
+ for(_x)in 1..10 {}
+ //~^ ERROR unnecessary parentheses around pattern
+
+ if(2 == 1){}
+ //~^ ERROR unnecessary parentheses around `if` condition
+
+ // reported by parser
+ for(_x in 1..10){}
+ //~^ ERROR expected one of
+ //~| ERROR unexpected parentheses surrounding
+}
diff --git a/src/test/ui/lint/issue-103435-extra-parentheses.stderr b/src/test/ui/lint/issue-103435-extra-parentheses.stderr
new file mode 100644
index 000000000..29c41c910
--- /dev/null
+++ b/src/test/ui/lint/issue-103435-extra-parentheses.stderr
@@ -0,0 +1,61 @@
+error: expected one of `)`, `,`, `@`, or `|`, found keyword `in`
+ --> $DIR/issue-103435-extra-parentheses.rs:15:12
+ |
+LL | for(_x in 1..10){}
+ | ^^ expected one of `)`, `,`, `@`, or `|`
+
+error: unexpected parentheses surrounding `for` loop head
+ --> $DIR/issue-103435-extra-parentheses.rs:15:8
+ |
+LL | for(_x in 1..10){}
+ | ^ ^
+ |
+help: remove parentheses in `for` loop
+ |
+LL - for(_x in 1..10){}
+LL + for _x in 1..10 {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-103435-extra-parentheses.rs:5:11
+ |
+LL | if let(Some(_))= Some(1) {}
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-103435-extra-parentheses.rs:2:9
+ |
+LL | #![deny(unused_parens)]
+ | ^^^^^^^^^^^^^
+help: remove these parentheses
+ |
+LL - if let(Some(_))= Some(1) {}
+LL + if let Some(_) = Some(1) {}
+ |
+
+error: unnecessary parentheses around pattern
+ --> $DIR/issue-103435-extra-parentheses.rs:8:8
+ |
+LL | for(_x)in 1..10 {}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - for(_x)in 1..10 {}
+LL + for _x in 1..10 {}
+ |
+
+error: unnecessary parentheses around `if` condition
+ --> $DIR/issue-103435-extra-parentheses.rs:11:7
+ |
+LL | if(2 == 1){}
+ | ^ ^
+ |
+help: remove these parentheses
+ |
+LL - if(2 == 1){}
+LL + if 2 == 1 {}
+ |
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/lint/issue-104392.rs b/src/test/ui/lint/issue-104392.rs
new file mode 100644
index 000000000..d5608edb4
--- /dev/null
+++ b/src/test/ui/lint/issue-104392.rs
@@ -0,0 +1,11 @@
+fn main() {
+ { unsafe 92 } //~ ERROR expected `{`, found `92`
+}
+
+fn foo() {
+ { mod 92 } //~ ERROR expected identifier, found `92`
+}
+
+fn bar() {
+ { trait 92 } //~ ERROR expected identifier, found `92`
+}
diff --git a/src/test/ui/lint/issue-104392.stderr b/src/test/ui/lint/issue-104392.stderr
new file mode 100644
index 000000000..8e466439a
--- /dev/null
+++ b/src/test/ui/lint/issue-104392.stderr
@@ -0,0 +1,27 @@
+error: expected `{`, found `92`
+ --> $DIR/issue-104392.rs:2:14
+ |
+LL | { unsafe 92 }
+ | ------ ^^ expected `{`
+ | |
+ | while parsing this `unsafe` expression
+ |
+help: try placing this code inside a block
+ |
+LL | { unsafe { 92 } }
+ | + +
+
+error: expected identifier, found `92`
+ --> $DIR/issue-104392.rs:6:11
+ |
+LL | { mod 92 }
+ | ^^ expected identifier
+
+error: expected identifier, found `92`
+ --> $DIR/issue-104392.rs:10:13
+ |
+LL | { trait 92 }
+ | ^^ expected identifier
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/lint/issue-104897.rs b/src/test/ui/lint/issue-104897.rs
new file mode 100644
index 000000000..5fbc658f1
--- /dev/null
+++ b/src/test/ui/lint/issue-104897.rs
@@ -0,0 +1,6 @@
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: format argument must be a string literal
+
+fn f(){(print!(á
diff --git a/src/test/ui/lint/issue-104897.stderr b/src/test/ui/lint/issue-104897.stderr
new file mode 100644
index 000000000..817a93c2f
--- /dev/null
+++ b/src/test/ui/lint/issue-104897.stderr
@@ -0,0 +1,43 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-104897.rs:6:18
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-104897.rs:6:18
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-104897.rs:6:18
+ |
+LL | fn f(){(print!(á
+ | -- - ^
+ | || |
+ | || unclosed delimiter
+ | |unclosed delimiter
+ | unclosed delimiter
+
+error: format argument must be a string literal
+ --> $DIR/issue-104897.rs:6:16
+ |
+LL | fn f(){(print!(á
+ | ^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | fn f(){(print!("{}", á
+ | +++++
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/lint/issue-97094.interleaved.stderr b/src/test/ui/lint/issue-97094.interleaved.stderr
deleted file mode 100644
index a25816589..000000000
--- a/src/test/ui/lint/issue-97094.interleaved.stderr
+++ /dev/null
@@ -1,53 +0,0 @@
-error: unknown lint: `nonex_lint_top_level`
- --> $DIR/issue-97094.rs:14:26
- |
-LL | #![cfg_attr(all(), allow(nonex_lint_top_level))]
- | ^^^^^^^^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/issue-97094.rs:10:9
- |
-LL | #![deny(warnings)]
- | ^^^^^^^^
- = note: `#[deny(unknown_lints)]` implied by `#[deny(warnings)]`
-
-error: lint `bare_trait_object` has been renamed to `bare_trait_objects`
- --> $DIR/issue-97094.rs:16:26
- |
-LL | #![cfg_attr(all(), allow(bare_trait_object))]
- | ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects`
- |
- = note: `#[deny(renamed_and_removed_lints)]` implied by `#[deny(warnings)]`
-
-error: unknown lint: `nonex_lint_mod`
- --> $DIR/issue-97094.rs:19:25
- |
-LL | #[cfg_attr(all(), allow(nonex_lint_mod))]
- | ^^^^^^^^^^^^^^
-
-error: unknown lint: `nonex_lint_mod_inner`
- --> $DIR/issue-97094.rs:22:30
- |
-LL | #![cfg_attr(all(), allow(nonex_lint_mod_inner))]
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: unknown lint: `nonex_lint_fn`
- --> $DIR/issue-97094.rs:26:25
- |
-LL | #[cfg_attr(all(), allow(nonex_lint_fn))]
- | ^^^^^^^^^^^^^
-
-error: unknown lint: `nonex_lint_in_macro`
- --> $DIR/issue-97094.rs:37:29
- |
-LL | #[cfg_attr(all(), allow(nonex_lint_in_macro))]
- | ^^^^^^^^^^^^^^^^^^^
-
-error: unknown lint: `nonex_lint_fn`
- --> $DIR/issue-97094.rs:56:13
- |
-LL | #[allow(nonex_lint_fn)]
- | ^^^^^^^^^^^^^
-
-error: aborting due to 7 previous errors
-
diff --git a/src/test/ui/lint/issue-97094.rs b/src/test/ui/lint/issue-97094.rs
index aeaead1bd..22525ca11 100644
--- a/src/test/ui/lint/issue-97094.rs
+++ b/src/test/ui/lint/issue-97094.rs
@@ -1,12 +1,3 @@
-// revisions: interleaved nointerleaved
-// [nointerleaved]compile-flags: -Z no-interleave-lints
-
-// This test has two revisions because the logic change
-// needed to make this test pass had to be adjusted
-// for no-interleave-lints. Should the debug option
-// be removed one day, please don't remove this
-// test entirely, just remove the revision from it.
-
#![deny(warnings)]
// Ensure that unknown lints inside cfg-attr's are linted for
diff --git a/src/test/ui/lint/issue-97094.nointerleaved.stderr b/src/test/ui/lint/issue-97094.stderr
index a25816589..1a0a3eaf2 100644
--- a/src/test/ui/lint/issue-97094.nointerleaved.stderr
+++ b/src/test/ui/lint/issue-97094.stderr
@@ -1,18 +1,18 @@
error: unknown lint: `nonex_lint_top_level`
- --> $DIR/issue-97094.rs:14:26
+ --> $DIR/issue-97094.rs:5:26
|
LL | #![cfg_attr(all(), allow(nonex_lint_top_level))]
| ^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/issue-97094.rs:10:9
+ --> $DIR/issue-97094.rs:1:9
|
LL | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(unknown_lints)]` implied by `#[deny(warnings)]`
error: lint `bare_trait_object` has been renamed to `bare_trait_objects`
- --> $DIR/issue-97094.rs:16:26
+ --> $DIR/issue-97094.rs:7:26
|
LL | #![cfg_attr(all(), allow(bare_trait_object))]
| ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects`
@@ -20,31 +20,31 @@ LL | #![cfg_attr(all(), allow(bare_trait_object))]
= note: `#[deny(renamed_and_removed_lints)]` implied by `#[deny(warnings)]`
error: unknown lint: `nonex_lint_mod`
- --> $DIR/issue-97094.rs:19:25
+ --> $DIR/issue-97094.rs:10:25
|
LL | #[cfg_attr(all(), allow(nonex_lint_mod))]
| ^^^^^^^^^^^^^^
error: unknown lint: `nonex_lint_mod_inner`
- --> $DIR/issue-97094.rs:22:30
+ --> $DIR/issue-97094.rs:13:30
|
LL | #![cfg_attr(all(), allow(nonex_lint_mod_inner))]
| ^^^^^^^^^^^^^^^^^^^^
error: unknown lint: `nonex_lint_fn`
- --> $DIR/issue-97094.rs:26:25
+ --> $DIR/issue-97094.rs:17:25
|
LL | #[cfg_attr(all(), allow(nonex_lint_fn))]
| ^^^^^^^^^^^^^
error: unknown lint: `nonex_lint_in_macro`
- --> $DIR/issue-97094.rs:37:29
+ --> $DIR/issue-97094.rs:28:29
|
LL | #[cfg_attr(all(), allow(nonex_lint_in_macro))]
| ^^^^^^^^^^^^^^^^^^^
error: unknown lint: `nonex_lint_fn`
- --> $DIR/issue-97094.rs:56:13
+ --> $DIR/issue-97094.rs:47:13
|
LL | #[allow(nonex_lint_fn)]
| ^^^^^^^^^^^^^
diff --git a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr
index 2cc4d382d..553ab3869 100644
--- a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr
+++ b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr
@@ -1,36 +1,36 @@
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:5:1
|
LL | impl Foo for dyn Send {}
| --------------------- first implementation here
LL |
LL | impl Foo for dyn Send + Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
= note: `#[deny(order_dependent_trait_objects)]` on by default
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
|
LL | impl Foo for dyn Send + Sync {}
| ---------------------------- first implementation here
LL |
LL | impl Foo for dyn Sync + Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:15:1
|
LL | impl Foo for dyn Sync + Send {}
| ---------------------------- first implementation here
...
LL | impl Foo for dyn Send + Sync + Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@@ -38,42 +38,42 @@ LL | impl Foo for dyn Send + Sync + Send {}
error: aborting due to 3 previous errors
Future incompatibility report: Future breakage diagnostic:
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:5:1
|
LL | impl Foo for dyn Send {}
| --------------------- first implementation here
LL |
LL | impl Foo for dyn Send + Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
= note: `#[deny(order_dependent_trait_objects)]` on by default
Future breakage diagnostic:
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:11:1
|
LL | impl Foo for dyn Send + Sync {}
| ---------------------------- first implementation here
LL |
LL | impl Foo for dyn Sync + Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
= note: `#[deny(order_dependent_trait_objects)]` on by default
Future breakage diagnostic:
-error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+error: conflicting implementations of trait `Foo` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/lint-incoherent-auto-trait-objects.rs:15:1
|
LL | impl Foo for dyn Sync + Send {}
| ---------------------------- first implementation here
...
LL | impl Foo for dyn Send + Sync + Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
diff --git a/src/test/ui/lint/opaque-ty-ffi-normalization-cycle.rs b/src/test/ui/lint/opaque-ty-ffi-normalization-cycle.rs
new file mode 100644
index 000000000..c83bca4a4
--- /dev/null
+++ b/src/test/ui/lint/opaque-ty-ffi-normalization-cycle.rs
@@ -0,0 +1,41 @@
+#![feature(type_alias_impl_trait)]
+#![allow(unused)]
+#![deny(improper_ctypes)]
+
+pub trait TraitA {
+ type Assoc;
+}
+
+impl TraitA for u32 {
+ type Assoc = u32;
+}
+
+pub trait TraitB {
+ type Assoc;
+}
+
+impl<T> TraitB for T
+where
+ T: TraitA,
+{
+ type Assoc = <T as TraitA>::Assoc;
+}
+
+type AliasA = impl TraitA<Assoc = u32>;
+
+type AliasB = impl TraitB;
+
+fn use_of_a() -> AliasA {
+ 3
+}
+
+fn use_of_b() -> AliasB {
+ 3
+}
+
+extern "C" {
+ fn lint_me() -> <AliasB as TraitB>::Assoc;
+ //~^ ERROR `extern` block uses type `AliasB`, which is not FFI-safe
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/opaque-ty-ffi-normalization-cycle.stderr b/src/test/ui/lint/opaque-ty-ffi-normalization-cycle.stderr
new file mode 100644
index 000000000..e8d696477
--- /dev/null
+++ b/src/test/ui/lint/opaque-ty-ffi-normalization-cycle.stderr
@@ -0,0 +1,15 @@
+error: `extern` block uses type `AliasB`, which is not FFI-safe
+ --> $DIR/opaque-ty-ffi-normalization-cycle.rs:37:21
+ |
+LL | fn lint_me() -> <AliasB as TraitB>::Assoc;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+ |
+ = note: opaque types have no C equivalent
+note: the lint level is defined here
+ --> $DIR/opaque-ty-ffi-normalization-cycle.rs:3:9
+ |
+LL | #![deny(improper_ctypes)]
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr
index f4c0e2141..4caee777a 100644
--- a/src/test/ui/lint/suggestions.stderr
+++ b/src/test/ui/lint/suggestions.stderr
@@ -41,12 +41,12 @@ warning: variable does not need to be mutable
--> $DIR/suggestions.rs:54:13
|
LL | let mut
- | _____________^
- | |_____________|
+ | ______________^
+ | | _____________|
| ||
LL | || b = 1;
| ||____________-^
- | |____________|
+ | |_____________|
| help: remove this `mut`
error: const items should never be `#[no_mangle]`
diff --git a/src/test/ui/lint/unused/issue-104397.rs b/src/test/ui/lint/unused/issue-104397.rs
new file mode 100644
index 000000000..94e15cd96
--- /dev/null
+++ b/src/test/ui/lint/unused/issue-104397.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![warn(unused)]
+#![deny(warnings)]
+
+struct Inv<'a>(&'a mut &'a ());
+
+trait Trait {}
+impl Trait for for<'a> fn(Inv<'a>) {}
+
+fn with_bound()
+where
+ (for<'a> fn(Inv<'a>)): Trait,
+{}
+
+fn main() {
+ with_bound();
+}
diff --git a/src/test/ui/lint/unused/issue-88519-unused-paren.rs b/src/test/ui/lint/unused/issue-88519-unused-paren.rs
index be02fcd3f..ce3d15ac1 100644
--- a/src/test/ui/lint/unused/issue-88519-unused-paren.rs
+++ b/src/test/ui/lint/unused/issue-88519-unused-paren.rs
@@ -51,22 +51,13 @@ mod casts {
mod typeascription {
fn outside() -> u8 {
- ({ 0 }): u8
- }
- fn inside() -> u8 {
- ({ 0 }: u8)
+ type_ascribe!(({ 0 }), u8)
}
fn outside_match() -> u8 {
- (match 0 { x => x }): u8
- }
- fn inside_match() -> u8 {
- (match 0 { x => x }: u8)
+ type_ascribe!((match 0 { x => x }), u8)
}
fn outside_if() -> u8 {
- (if false { 0 } else { 0 }): u8
- }
- fn inside_if() -> u8 {
- (if false { 0 } else { 0 }: u8)
+ type_ascribe!((if false { 0 } else { 0 }), u8)
}
}
diff --git a/src/test/ui/lint/unused/must-use-box-from-raw.stderr b/src/test/ui/lint/unused/must-use-box-from-raw.stderr
index 011acc3bf..721182757 100644
--- a/src/test/ui/lint/unused/must-use-box-from-raw.stderr
+++ b/src/test/ui/lint/unused/must-use-box-from-raw.stderr
@@ -2,7 +2,7 @@ warning: unused return value of `Box::<T>::from_raw` that must be used
--> $DIR/must-use-box-from-raw.rs:8:5
|
LL | Box::from_raw(ptr);
- | ^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^
|
= note: call `drop(from_raw(ptr))` if you intend to drop the `Box`
note: the lint level is defined here
diff --git a/src/test/ui/lint/unused/must-use-ops.rs b/src/test/ui/lint/unused/must-use-ops.rs
index 3e425727e..60f877aa8 100644
--- a/src/test/ui/lint/unused/must-use-ops.rs
+++ b/src/test/ui/lint/unused/must-use-ops.rs
@@ -3,12 +3,18 @@
// check-pass
#![warn(unused_must_use)]
+#![feature(never_type)]
+
+fn deref_never(x: &!) {
+ // Don't lint for uninhabited typess
+ *x;
+}
fn main() {
let val = 1;
let val_pointer = &val;
-// Comparison Operators
+ // Comparison Operators
val == 1; //~ WARNING unused comparison
val < 1; //~ WARNING unused comparison
val <= 1; //~ WARNING unused comparison
@@ -16,26 +22,30 @@ fn main() {
val >= 1; //~ WARNING unused comparison
val > 1; //~ WARNING unused comparison
-// Arithmetic Operators
+ // Arithmetic Operators
val + 2; //~ WARNING unused arithmetic operation
val - 2; //~ WARNING unused arithmetic operation
val / 2; //~ WARNING unused arithmetic operation
val * 2; //~ WARNING unused arithmetic operation
val % 2; //~ WARNING unused arithmetic operation
-// Logical Operators
+ // Logical Operators
true && true; //~ WARNING unused logical operation
false || true; //~ WARNING unused logical operation
-// Bitwise Operators
+ // Bitwise Operators
5 ^ val; //~ WARNING unused bitwise operation
5 & val; //~ WARNING unused bitwise operation
5 | val; //~ WARNING unused bitwise operation
5 << val; //~ WARNING unused bitwise operation
5 >> val; //~ WARNING unused bitwise operation
-// Unary Operators
+ // Unary Operators
!val; //~ WARNING unused unary operation
-val; //~ WARNING unused unary operation
*val_pointer; //~ WARNING unused unary operation
+
+ if false {
+ deref_never(&panic!());
+ }
}
diff --git a/src/test/ui/lint/unused/must-use-ops.stderr b/src/test/ui/lint/unused/must-use-ops.stderr
index b248dd0fe..79a53d39c 100644
--- a/src/test/ui/lint/unused/must-use-ops.stderr
+++ b/src/test/ui/lint/unused/must-use-ops.stderr
@@ -1,5 +1,5 @@
warning: unused comparison that must be used
- --> $DIR/must-use-ops.rs:12:5
+ --> $DIR/must-use-ops.rs:18:5
|
LL | val == 1;
| ^^^^^^^^ the comparison produces a value
@@ -15,7 +15,7 @@ LL | let _ = val == 1;
| +++++++
warning: unused comparison that must be used
- --> $DIR/must-use-ops.rs:13:5
+ --> $DIR/must-use-ops.rs:19:5
|
LL | val < 1;
| ^^^^^^^ the comparison produces a value
@@ -26,7 +26,7 @@ LL | let _ = val < 1;
| +++++++
warning: unused comparison that must be used
- --> $DIR/must-use-ops.rs:14:5
+ --> $DIR/must-use-ops.rs:20:5
|
LL | val <= 1;
| ^^^^^^^^ the comparison produces a value
@@ -37,7 +37,7 @@ LL | let _ = val <= 1;
| +++++++
warning: unused comparison that must be used
- --> $DIR/must-use-ops.rs:15:5
+ --> $DIR/must-use-ops.rs:21:5
|
LL | val != 1;
| ^^^^^^^^ the comparison produces a value
@@ -48,7 +48,7 @@ LL | let _ = val != 1;
| +++++++
warning: unused comparison that must be used
- --> $DIR/must-use-ops.rs:16:5
+ --> $DIR/must-use-ops.rs:22:5
|
LL | val >= 1;
| ^^^^^^^^ the comparison produces a value
@@ -59,7 +59,7 @@ LL | let _ = val >= 1;
| +++++++
warning: unused comparison that must be used
- --> $DIR/must-use-ops.rs:17:5
+ --> $DIR/must-use-ops.rs:23:5
|
LL | val > 1;
| ^^^^^^^ the comparison produces a value
@@ -70,7 +70,7 @@ LL | let _ = val > 1;
| +++++++
warning: unused arithmetic operation that must be used
- --> $DIR/must-use-ops.rs:20:5
+ --> $DIR/must-use-ops.rs:26:5
|
LL | val + 2;
| ^^^^^^^ the arithmetic operation produces a value
@@ -81,7 +81,7 @@ LL | let _ = val + 2;
| +++++++
warning: unused arithmetic operation that must be used
- --> $DIR/must-use-ops.rs:21:5
+ --> $DIR/must-use-ops.rs:27:5
|
LL | val - 2;
| ^^^^^^^ the arithmetic operation produces a value
@@ -92,7 +92,7 @@ LL | let _ = val - 2;
| +++++++
warning: unused arithmetic operation that must be used
- --> $DIR/must-use-ops.rs:22:5
+ --> $DIR/must-use-ops.rs:28:5
|
LL | val / 2;
| ^^^^^^^ the arithmetic operation produces a value
@@ -103,7 +103,7 @@ LL | let _ = val / 2;
| +++++++
warning: unused arithmetic operation that must be used
- --> $DIR/must-use-ops.rs:23:5
+ --> $DIR/must-use-ops.rs:29:5
|
LL | val * 2;
| ^^^^^^^ the arithmetic operation produces a value
@@ -114,7 +114,7 @@ LL | let _ = val * 2;
| +++++++
warning: unused arithmetic operation that must be used
- --> $DIR/must-use-ops.rs:24:5
+ --> $DIR/must-use-ops.rs:30:5
|
LL | val % 2;
| ^^^^^^^ the arithmetic operation produces a value
@@ -125,7 +125,7 @@ LL | let _ = val % 2;
| +++++++
warning: unused logical operation that must be used
- --> $DIR/must-use-ops.rs:27:5
+ --> $DIR/must-use-ops.rs:33:5
|
LL | true && true;
| ^^^^^^^^^^^^ the logical operation produces a value
@@ -136,7 +136,7 @@ LL | let _ = true && true;
| +++++++
warning: unused logical operation that must be used
- --> $DIR/must-use-ops.rs:28:5
+ --> $DIR/must-use-ops.rs:34:5
|
LL | false || true;
| ^^^^^^^^^^^^^ the logical operation produces a value
@@ -147,7 +147,7 @@ LL | let _ = false || true;
| +++++++
warning: unused bitwise operation that must be used
- --> $DIR/must-use-ops.rs:31:5
+ --> $DIR/must-use-ops.rs:37:5
|
LL | 5 ^ val;
| ^^^^^^^ the bitwise operation produces a value
@@ -158,7 +158,7 @@ LL | let _ = 5 ^ val;
| +++++++
warning: unused bitwise operation that must be used
- --> $DIR/must-use-ops.rs:32:5
+ --> $DIR/must-use-ops.rs:38:5
|
LL | 5 & val;
| ^^^^^^^ the bitwise operation produces a value
@@ -169,7 +169,7 @@ LL | let _ = 5 & val;
| +++++++
warning: unused bitwise operation that must be used
- --> $DIR/must-use-ops.rs:33:5
+ --> $DIR/must-use-ops.rs:39:5
|
LL | 5 | val;
| ^^^^^^^ the bitwise operation produces a value
@@ -180,7 +180,7 @@ LL | let _ = 5 | val;
| +++++++
warning: unused bitwise operation that must be used
- --> $DIR/must-use-ops.rs:34:5
+ --> $DIR/must-use-ops.rs:40:5
|
LL | 5 << val;
| ^^^^^^^^ the bitwise operation produces a value
@@ -191,7 +191,7 @@ LL | let _ = 5 << val;
| +++++++
warning: unused bitwise operation that must be used
- --> $DIR/must-use-ops.rs:35:5
+ --> $DIR/must-use-ops.rs:41:5
|
LL | 5 >> val;
| ^^^^^^^^ the bitwise operation produces a value
@@ -202,7 +202,7 @@ LL | let _ = 5 >> val;
| +++++++
warning: unused unary operation that must be used
- --> $DIR/must-use-ops.rs:38:5
+ --> $DIR/must-use-ops.rs:44:5
|
LL | !val;
| ^^^^ the unary operation produces a value
@@ -213,7 +213,7 @@ LL | let _ = !val;
| +++++++
warning: unused unary operation that must be used
- --> $DIR/must-use-ops.rs:39:5
+ --> $DIR/must-use-ops.rs:45:5
|
LL | -val;
| ^^^^ the unary operation produces a value
@@ -224,7 +224,7 @@ LL | let _ = -val;
| +++++++
warning: unused unary operation that must be used
- --> $DIR/must-use-ops.rs:40:5
+ --> $DIR/must-use-ops.rs:46:5
|
LL | *val_pointer;
| ^^^^^^^^^^^^ the unary operation produces a value
diff --git a/src/test/ui/lint/unused/must_use-array.rs b/src/test/ui/lint/unused/must_use-array.rs
index 97825dd2f..b7bae4b0a 100644
--- a/src/test/ui/lint/unused/must_use-array.rs
+++ b/src/test/ui/lint/unused/must_use-array.rs
@@ -1,6 +1,7 @@
#![deny(unused_must_use)]
#[must_use]
+#[derive(Clone, Copy)]
struct S;
struct A;
@@ -34,6 +35,10 @@ fn array_of_arrays_of_arrays() -> [[[S; 1]; 2]; 1] {
[[[S], [S]]]
}
+fn usize_max() -> [S; usize::MAX] {
+ [S; usize::MAX]
+}
+
fn main() {
empty(); // ok
singleton(); //~ ERROR unused array of `S` that must be used
@@ -44,4 +49,6 @@ fn main() {
//~^ ERROR unused array of boxed `T` trait objects in tuple element 1 that must be used
array_of_arrays_of_arrays();
//~^ ERROR unused array of arrays of arrays of `S` that must be used
+ usize_max();
+ //~^ ERROR unused array of `S` that must be used
}
diff --git a/src/test/ui/lint/unused/must_use-array.stderr b/src/test/ui/lint/unused/must_use-array.stderr
index 45a5317fc..61ef2088d 100644
--- a/src/test/ui/lint/unused/must_use-array.stderr
+++ b/src/test/ui/lint/unused/must_use-array.stderr
@@ -1,8 +1,8 @@
error: unused array of `S` that must be used
- --> $DIR/must_use-array.rs:39:5
+ --> $DIR/must_use-array.rs:44:5
|
LL | singleton();
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/must_use-array.rs:1:9
@@ -11,34 +11,40 @@ LL | #![deny(unused_must_use)]
| ^^^^^^^^^^^^^^^
error: unused array of `S` that must be used
- --> $DIR/must_use-array.rs:40:5
+ --> $DIR/must_use-array.rs:45:5
|
LL | many();
- | ^^^^^^^
+ | ^^^^^^
error: unused array of `S` in tuple element 0 that must be used
- --> $DIR/must_use-array.rs:41:6
+ --> $DIR/must_use-array.rs:46:6
|
LL | ([S], 0, ());
| ^^^
error: unused array of implementers of `T` that must be used
- --> $DIR/must_use-array.rs:42:5
+ --> $DIR/must_use-array.rs:47:5
|
LL | array_of_impl_trait();
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: unused array of boxed `T` trait objects in tuple element 1 that must be used
- --> $DIR/must_use-array.rs:43:5
+ --> $DIR/must_use-array.rs:48:5
|
LL | impl_array();
| ^^^^^^^^^^^^
error: unused array of arrays of arrays of `S` that must be used
- --> $DIR/must_use-array.rs:45:5
+ --> $DIR/must_use-array.rs:50:5
|
LL | array_of_arrays_of_arrays();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unused array of `S` that must be used
+ --> $DIR/must_use-array.rs:52:5
+ |
+LL | usize_max();
+ | ^^^^^^^^^^^
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
diff --git a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
index f5199f43c..ef738708d 100644
--- a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
+++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
@@ -2,7 +2,7 @@ error: unused implementer of `Iterator` that must be used
--> $DIR/must_use-in-stdlib-traits.rs:42:4
|
LL | iterator();
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^
|
= note: iterators are lazy and do nothing unless consumed
note: the lint level is defined here
@@ -15,7 +15,7 @@ error: unused implementer of `Future` that must be used
--> $DIR/must_use-in-stdlib-traits.rs:43:4
|
LL | future();
- | ^^^^^^^^^
+ | ^^^^^^^^
|
= note: futures do nothing unless you `.await` or poll them
@@ -23,7 +23,7 @@ error: unused implementer of `FnOnce` that must be used
--> $DIR/must_use-in-stdlib-traits.rs:44:4
|
LL | square_fn_once();
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
|
= note: closures are lazy and do nothing unless called
@@ -31,7 +31,7 @@ error: unused implementer of `FnMut` that must be used
--> $DIR/must_use-in-stdlib-traits.rs:45:4
|
LL | square_fn_mut();
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^
|
= note: closures are lazy and do nothing unless called
@@ -39,7 +39,7 @@ error: unused implementer of `Fn` that must be used
--> $DIR/must_use-in-stdlib-traits.rs:46:4
|
LL | square_fn();
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^
|
= note: closures are lazy and do nothing unless called
diff --git a/src/test/ui/lint/unused/must_use-trait.stderr b/src/test/ui/lint/unused/must_use-trait.stderr
index a42eb8841..2f5496484 100644
--- a/src/test/ui/lint/unused/must_use-trait.stderr
+++ b/src/test/ui/lint/unused/must_use-trait.stderr
@@ -2,7 +2,7 @@ error: unused implementer of `Critical` that must be used
--> $DIR/must_use-trait.rs:33:5
|
LL | get_critical();
- | ^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/must_use-trait.rs:1:9
@@ -14,13 +14,13 @@ error: unused boxed `Critical` trait object that must be used
--> $DIR/must_use-trait.rs:34:5
|
LL | get_boxed_critical();
- | ^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^
error: unused boxed boxed `Critical` trait object that must be used
--> $DIR/must_use-trait.rs:35:5
|
LL | get_nested_boxed_critical();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unused boxed `Critical` trait object in tuple element 1 that must be used
--> $DIR/must_use-trait.rs:37:5
diff --git a/src/test/ui/lint/unused/must_use-unit.stderr b/src/test/ui/lint/unused/must_use-unit.stderr
index 7f25a1935..9fcbc5074 100644
--- a/src/test/ui/lint/unused/must_use-unit.stderr
+++ b/src/test/ui/lint/unused/must_use-unit.stderr
@@ -2,7 +2,7 @@ error: unused return value of `foo` that must be used
--> $DIR/must_use-unit.rs:13:5
|
LL | foo();
- | ^^^^^^
+ | ^^^^^
|
note: the lint level is defined here
--> $DIR/must_use-unit.rs:2:9
@@ -14,7 +14,7 @@ error: unused return value of `bar` that must be used
--> $DIR/must_use-unit.rs:15:5
|
LL | bar();
- | ^^^^^^
+ | ^^^^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/lint/unused/unused-async.rs b/src/test/ui/lint/unused/unused-async.rs
index 7d17af115..4be93aa15 100644
--- a/src/test/ui/lint/unused/unused-async.rs
+++ b/src/test/ui/lint/unused/unused-async.rs
@@ -1,24 +1,43 @@
// edition:2018
-// run-pass
-#![allow(dead_code)]
+#![deny(unused_must_use)]
+
#[must_use]
-//~^ WARNING `must_use`
-async fn test() -> i32 {
+async fn foo() -> i32 {
1
}
+#[must_use]
+fn bar() -> impl std::future::Future<Output=i32> {
+ async {
+ 42
+ }
+}
+
+async fn baz() -> i32 {
+ 0
+}
struct Wowee {}
impl Wowee {
#[must_use]
- //~^ WARNING `must_use`
async fn test_method() -> i32 {
1
}
}
+async fn test() {
+ foo(); //~ ERROR unused return value of `foo` that must be used
+ //~^ ERROR unused implementer of `Future` that must be used
+ foo().await; //~ ERROR unused output of future returned by `foo` that must be used
+ bar(); //~ ERROR unused return value of `bar` that must be used
+ //~^ ERROR unused implementer of `Future` that must be used
+ bar().await; //~ ERROR unused output of future returned by `bar` that must be used
+ baz(); //~ ERROR unused implementer of `Future` that must be used
+ baz().await; // ok
+}
+
/* FIXME(guswynn) update this test when async-fn-in-traits works
trait Doer {
#[must_use]
diff --git a/src/test/ui/lint/unused/unused-async.stderr b/src/test/ui/lint/unused/unused-async.stderr
index 6bbc9e2bf..4bcb26dc1 100644
--- a/src/test/ui/lint/unused/unused-async.stderr
+++ b/src/test/ui/lint/unused/unused-async.stderr
@@ -1,26 +1,55 @@
-warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
- --> $DIR/unused-async.rs:5:1
- |
-LL | #[must_use]
- | ^^^^^^^^^^^
-LL |
-LL | / async fn test() -> i32 {
-LL | | 1
-LL | | }
- | |_- this attribute does nothing, the `Future`s returned by async functions are already `must_use`
- |
- = note: `#[warn(unused_attributes)]` on by default
-
-warning: `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
- --> $DIR/unused-async.rs:15:5
- |
-LL | #[must_use]
- | ^^^^^^^^^^^
-LL |
-LL | / async fn test_method() -> i32 {
-LL | | 1
-LL | | }
- | |_____- this attribute does nothing, the `Future`s returned by async functions are already `must_use`
-
-warning: 2 warnings emitted
+error: unused implementer of `Future` that must be used
+ --> $DIR/unused-async.rs:31:5
+ |
+LL | foo();
+ | ^^^^^
+ |
+ = note: futures do nothing unless you `.await` or poll them
+note: the lint level is defined here
+ --> $DIR/unused-async.rs:2:9
+ |
+LL | #![deny(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+
+error: unused return value of `foo` that must be used
+ --> $DIR/unused-async.rs:31:5
+ |
+LL | foo();
+ | ^^^^^
+
+error: unused output of future returned by `foo` that must be used
+ --> $DIR/unused-async.rs:33:5
+ |
+LL | foo().await;
+ | ^^^^^^^^^^^
+
+error: unused implementer of `Future` that must be used
+ --> $DIR/unused-async.rs:34:5
+ |
+LL | bar();
+ | ^^^^^
+ |
+ = note: futures do nothing unless you `.await` or poll them
+
+error: unused return value of `bar` that must be used
+ --> $DIR/unused-async.rs:34:5
+ |
+LL | bar();
+ | ^^^^^
+
+error: unused output of future returned by `bar` that must be used
+ --> $DIR/unused-async.rs:36:5
+ |
+LL | bar().await;
+ | ^^^^^^^^^^^
+
+error: unused implementer of `Future` that must be used
+ --> $DIR/unused-async.rs:37:5
+ |
+LL | baz();
+ | ^^^^^
+ |
+ = note: futures do nothing unless you `.await` or poll them
+
+error: aborting due to 7 previous errors
diff --git a/src/test/ui/lint/unused/unused-closure.stderr b/src/test/ui/lint/unused/unused-closure.stderr
index 4362abd20..c3a82402e 100644
--- a/src/test/ui/lint/unused/unused-closure.stderr
+++ b/src/test/ui/lint/unused/unused-closure.stderr
@@ -4,7 +4,7 @@ error: unused closure that must be used
LL | / || {
LL | | println!("Hello!");
LL | | };
- | |______^
+ | |_____^
|
= note: closures are lazy and do nothing unless called
note: the lint level is defined here
@@ -17,7 +17,7 @@ error: unused implementer of `Future` that must be used
--> $DIR/unused-closure.rs:13:5
|
LL | async {};
- | ^^^^^^^^^
+ | ^^^^^^^^
|
= note: futures do nothing unless you `.await` or poll them
@@ -25,7 +25,7 @@ error: unused closure that must be used
--> $DIR/unused-closure.rs:14:5
|
LL | || async {};
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^
|
= note: closures are lazy and do nothing unless called
@@ -33,7 +33,7 @@ error: unused closure that must be used
--> $DIR/unused-closure.rs:15:5
|
LL | async || {};
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^
|
= note: closures are lazy and do nothing unless called
@@ -41,7 +41,7 @@ error: unused array of boxed arrays of closures that must be used
--> $DIR/unused-closure.rs:18:5
|
LL | [Box::new([|| {}; 10]); 1];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: closures are lazy and do nothing unless called
@@ -49,7 +49,7 @@ error: unused closure that must be used
--> $DIR/unused-closure.rs:20:5
|
LL | vec![|| "a"].pop().unwrap();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: closures are lazy and do nothing unless called
@@ -57,7 +57,7 @@ error: unused closure that must be used
--> $DIR/unused-closure.rs:23:9
|
LL | || true;
- | ^^^^^^^^
+ | ^^^^^^^
|
= note: closures are lazy and do nothing unless called
diff --git a/src/test/ui/lint/unused/unused-result.stderr b/src/test/ui/lint/unused/unused-result.stderr
index 087e06341..4e1ba1fd9 100644
--- a/src/test/ui/lint/unused/unused-result.stderr
+++ b/src/test/ui/lint/unused/unused-result.stderr
@@ -2,7 +2,7 @@ error: unused `MustUse` that must be used
--> $DIR/unused-result.rs:21:5
|
LL | foo::<MustUse>();
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/unused-result.rs:2:25
@@ -14,7 +14,7 @@ error: unused `MustUseMsg` that must be used
--> $DIR/unused-result.rs:22:5
|
LL | foo::<MustUseMsg>();
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^
|
= note: some message
@@ -34,13 +34,13 @@ error: unused `MustUse` that must be used
--> $DIR/unused-result.rs:35:5
|
LL | foo::<MustUse>();
- | ^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: unused `MustUseMsg` that must be used
--> $DIR/unused-result.rs:36:5
|
LL | foo::<MustUseMsg>();
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^
|
= note: some message
diff --git a/src/test/ui/lint/unused/unused-supertrait.stderr b/src/test/ui/lint/unused/unused-supertrait.stderr
index d2f8c0078..cb45add9c 100644
--- a/src/test/ui/lint/unused/unused-supertrait.stderr
+++ b/src/test/ui/lint/unused/unused-supertrait.stderr
@@ -2,7 +2,7 @@ error: unused implementer of `Iterator` that must be used
--> $DIR/unused-supertrait.rs:9:5
|
LL | it();
- | ^^^^^
+ | ^^^^
|
= note: iterators are lazy and do nothing unless consumed
note: the lint level is defined here
diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.stderr b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
index ce959ddbc..0f699429e 100644
--- a/src/test/ui/lint/unused/unused_attributes-must_use.stderr
+++ b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
@@ -139,7 +139,7 @@ error: unused `X` that must be used
--> $DIR/unused_attributes-must_use.rs:103:5
|
LL | X;
- | ^^
+ | ^
|
note: the lint level is defined here
--> $DIR/unused_attributes-must_use.rs:2:28
@@ -151,37 +151,37 @@ error: unused `Y` that must be used
--> $DIR/unused_attributes-must_use.rs:104:5
|
LL | Y::Z;
- | ^^^^^
+ | ^^^^
error: unused `U` that must be used
--> $DIR/unused_attributes-must_use.rs:105:5
|
LL | U { unit: () };
- | ^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^
error: unused return value of `U::method` that must be used
--> $DIR/unused_attributes-must_use.rs:106:5
|
LL | U::method();
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^
error: unused return value of `foo` that must be used
--> $DIR/unused_attributes-must_use.rs:107:5
|
LL | foo();
- | ^^^^^^
+ | ^^^^^
error: unused return value of `foreign_foo` that must be used
--> $DIR/unused_attributes-must_use.rs:110:9
|
LL | foreign_foo();
- | ^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^
error: unused return value of `Use::get_four` that must be used
--> $DIR/unused_attributes-must_use.rs:118:5
|
LL | ().get_four();
- | ^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^
error: aborting due to 28 previous errors
diff --git a/src/test/ui/liveness/liveness-move-call-arg.stderr b/src/test/ui/liveness/liveness-move-call-arg.stderr
index 7c0e916ed..d14cd6cb4 100644
--- a/src/test/ui/liveness/liveness-move-call-arg.stderr
+++ b/src/test/ui/liveness/liveness-move-call-arg.stderr
@@ -3,9 +3,23 @@ error[E0382]: use of moved value: `x`
|
LL | let x: Box<isize> = Box::new(25);
| - move occurs because `x` has type `Box<isize>`, which does not implement the `Copy` trait
-...
+LL |
+LL | loop {
+ | ---- inside of this loop
LL | take(x);
| ^ value moved here, in previous iteration of loop
+ |
+note: consider changing this parameter type in function `take` to borrow instead if owning the value isn't necessary
+ --> $DIR/liveness-move-call-arg.rs:1:13
+ |
+LL | fn take(_x: Box<isize>) {}
+ | ---- ^^^^^^^^^^ this parameter takes ownership of the value
+ | |
+ | in this function
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | take(x.clone());
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-move-in-loop.stderr b/src/test/ui/liveness/liveness-move-in-loop.stderr
index 832d4f8fa..a060914f1 100644
--- a/src/test/ui/liveness/liveness-move-in-loop.stderr
+++ b/src/test/ui/liveness/liveness-move-in-loop.stderr
@@ -4,8 +4,22 @@ error[E0382]: use of moved value: `y`
LL | let y: Box<isize> = 42.into();
| - move occurs because `y` has type `Box<isize>`, which does not implement the `Copy` trait
...
+LL | loop {
+ | ---- inside of this loop
+LL | println!("{}", y);
+LL | loop {
+ | ---- inside of this loop
+LL | loop {
+ | ---- inside of this loop
+LL | loop {
+ | ---- inside of this loop
LL | x = y;
| ^ value moved here, in previous iteration of loop
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | x = y.clone();
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-move-in-while.stderr b/src/test/ui/liveness/liveness-move-in-while.stderr
index b04a05fe4..4dff7447d 100644
--- a/src/test/ui/liveness/liveness-move-in-while.stderr
+++ b/src/test/ui/liveness/liveness-move-in-while.stderr
@@ -24,12 +24,22 @@ error[E0382]: borrow of moved value: `y`
LL | let y: Box<isize> = 42.into();
| - move occurs because `y` has type `Box<isize>`, which does not implement the `Copy` trait
...
+LL | loop {
+ | ---- inside of this loop
LL | println!("{}", y);
| ^ value borrowed here after move
LL | while true { while true { while true { x = y; x.clone(); } } }
- | - value moved here, in previous iteration of loop
+ | ---------- ---------- ---------- - value moved here, in previous iteration of loop
+ | | | |
+ | | | inside of this loop
+ | | inside of this loop
+ | inside of this loop
|
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | while true { while true { while true { x = y.clone(); x.clone(); } } }
+ | ++++++++
error: aborting due to previous error; 3 warnings emitted
diff --git a/src/test/ui/liveness/liveness-use-after-move.stderr b/src/test/ui/liveness/liveness-use-after-move.stderr
index 218b93c8e..3accba197 100644
--- a/src/test/ui/liveness/liveness-use-after-move.stderr
+++ b/src/test/ui/liveness/liveness-use-after-move.stderr
@@ -10,6 +10,10 @@ LL | println!("{}", *x);
| ^^ value borrowed here after move
|
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let y = x.clone();
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-use-after-send.stderr b/src/test/ui/liveness/liveness-use-after-send.stderr
index 8edc0463f..65d55ca8f 100644
--- a/src/test/ui/liveness/liveness-use-after-send.stderr
+++ b/src/test/ui/liveness/liveness-use-after-send.stderr
@@ -8,7 +8,16 @@ LL | send(ch, message);
LL | println!("{}", message);
| ^^^^^^^ value borrowed here after move
|
+note: consider changing this parameter type in function `send` to borrow instead if owning the value isn't necessary
+ --> $DIR/liveness-use-after-send.rs:3:54
+ |
+LL | fn send<T:Send + std::fmt::Debug>(ch: Chan<T>, data: T) {
+ | ---- in this function ^ this parameter takes ownership of the value
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | send(ch, message.clone());
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/lto/auxiliary/thinlto-dylib.rs b/src/test/ui/lto/auxiliary/thinlto-dylib.rs
new file mode 100644
index 000000000..9d17c35da
--- /dev/null
+++ b/src/test/ui/lto/auxiliary/thinlto-dylib.rs
@@ -0,0 +1,23 @@
+// Auxiliary crate for test issue-105637: the LTOed dylib which had duplicate symbols from libstd,
+// breaking the panic hook feature.
+//
+// This simulates the `rustc_driver` crate, and the main crate simulates rustc's main binary hooking
+// into this driver.
+
+// compile-flags: -Zdylib-lto -C lto=thin
+
+use std::panic;
+
+pub fn main() {
+ // Install the hook we want to see executed
+ panic::set_hook(Box::new(|_| {
+ eprintln!("LTOed auxiliary crate panic hook");
+ }));
+
+ // Trigger the panic hook with an ICE
+ run_compiler();
+}
+
+fn run_compiler() {
+ panic!("ICEing");
+}
diff --git a/src/test/ui/lto/issue-105637.rs b/src/test/ui/lto/issue-105637.rs
new file mode 100644
index 000000000..0d9f0bec0
--- /dev/null
+++ b/src/test/ui/lto/issue-105637.rs
@@ -0,0 +1,28 @@
+// Regression test for issue #105637: `-Zdylib-lto` with LTO duplicated symbols from other dylibs,
+// in this case from libstd.
+//
+// That manifested as both `rustc_driver` and rustc's "main" (`compiler/rustc`) having their own
+// `std::panicking::HOOK` static, and the hook in rustc's main (the default stdlib's) being executed
+// when rustc ICEs, instead of the overriden hook from `rustc_driver` (which also displays the query
+// stack and information on how to open a GH issue for the encountered ICE).
+//
+// In this test, we reproduce this setup by installing a panic hook in both the main and an LTOed
+// dylib: the last hook set should be the one being executed, the dylib's.
+
+// aux-build: thinlto-dylib.rs
+// run-fail
+// check-run-results
+
+extern crate thinlto_dylib;
+
+use std::panic;
+
+fn main() {
+ // We don't want to see this panic hook executed
+ std::panic::set_hook(Box::new(|_| {
+ eprintln!("main crate panic hook");
+ }));
+
+ // Have the LTOed dylib install its own hook and panic, we want to see its hook executed.
+ thinlto_dylib::main();
+}
diff --git a/src/test/ui/lto/issue-105637.run.stderr b/src/test/ui/lto/issue-105637.run.stderr
new file mode 100644
index 000000000..43388e776
--- /dev/null
+++ b/src/test/ui/lto/issue-105637.run.stderr
@@ -0,0 +1 @@
+LTOed auxiliary crate panic hook
diff --git a/src/test/ui/macros/assert-trailing-junk.with-generic-asset.stderr b/src/test/ui/macros/assert-trailing-junk.with-generic-asset.stderr
index 09dd16a0b..1e73320e4 100644
--- a/src/test/ui/macros/assert-trailing-junk.with-generic-asset.stderr
+++ b/src/test/ui/macros/assert-trailing-junk.with-generic-asset.stderr
@@ -17,6 +17,8 @@ LL | assert!(true, "whatever" blah);
| -^^^^ no rules expected this token in macro call
| |
| help: missing comma here
+ |
+ = note: while trying to match sequence start
error: unexpected string literal
--> $DIR/assert-trailing-junk.rs:18:18
@@ -33,6 +35,8 @@ LL | assert!(true "whatever" blah);
| -^^^^ no rules expected this token in macro call
| |
| help: missing comma here
+ |
+ = note: while trying to match sequence start
error: macro requires an expression as an argument
--> $DIR/assert-trailing-junk.rs:22:5
diff --git a/src/test/ui/macros/assert-trailing-junk.without-generic-asset.stderr b/src/test/ui/macros/assert-trailing-junk.without-generic-asset.stderr
index 09dd16a0b..1e73320e4 100644
--- a/src/test/ui/macros/assert-trailing-junk.without-generic-asset.stderr
+++ b/src/test/ui/macros/assert-trailing-junk.without-generic-asset.stderr
@@ -17,6 +17,8 @@ LL | assert!(true, "whatever" blah);
| -^^^^ no rules expected this token in macro call
| |
| help: missing comma here
+ |
+ = note: while trying to match sequence start
error: unexpected string literal
--> $DIR/assert-trailing-junk.rs:18:18
@@ -33,6 +35,8 @@ LL | assert!(true "whatever" blah);
| -^^^^ no rules expected this token in macro call
| |
| help: missing comma here
+ |
+ = note: while trying to match sequence start
error: macro requires an expression as an argument
--> $DIR/assert-trailing-junk.rs:22:5
diff --git a/src/test/ui/attr-from-macro.rs b/src/test/ui/macros/attr-from-macro.rs
index bb3a5c94d..bb3a5c94d 100644
--- a/src/test/ui/attr-from-macro.rs
+++ b/src/test/ui/macros/attr-from-macro.rs
diff --git a/src/test/ui/auxiliary/attr-from-macro.rs b/src/test/ui/macros/auxiliary/attr-from-macro.rs
index 9b388675c..9b388675c 100644
--- a/src/test/ui/auxiliary/attr-from-macro.rs
+++ b/src/test/ui/macros/auxiliary/attr-from-macro.rs
diff --git a/src/test/ui/macros/issue-103529.rs b/src/test/ui/macros/issue-103529.rs
new file mode 100644
index 000000000..fa05baed7
--- /dev/null
+++ b/src/test/ui/macros/issue-103529.rs
@@ -0,0 +1,13 @@
+macro_rules! m {
+ ($s:stmt) => {}
+}
+
+m! { mut x }
+//~^ ERROR expected expression, found keyword `mut`
+//~| ERROR expected a statement
+m! { auto x }
+//~^ ERROR invalid variable declaration
+m! { var x }
+//~^ ERROR invalid variable declaration
+
+fn main() {}
diff --git a/src/test/ui/macros/issue-103529.stderr b/src/test/ui/macros/issue-103529.stderr
new file mode 100644
index 000000000..61e322afc
--- /dev/null
+++ b/src/test/ui/macros/issue-103529.stderr
@@ -0,0 +1,39 @@
+error: expected expression, found keyword `mut`
+ --> $DIR/issue-103529.rs:5:6
+ |
+LL | m! { mut x }
+ | ^^^ expected expression
+
+error: expected a statement
+ --> $DIR/issue-103529.rs:5:10
+ |
+LL | ($s:stmt) => {}
+ | ------- while parsing argument for this `stmt` macro fragment
+...
+LL | m! { mut x }
+ | ^
+
+error: invalid variable declaration
+ --> $DIR/issue-103529.rs:8:6
+ |
+LL | m! { auto x }
+ | ^^^^
+ |
+help: write `let` instead of `auto` to introduce a new variable
+ |
+LL | m! { let x }
+ | ~~~
+
+error: invalid variable declaration
+ --> $DIR/issue-103529.rs:10:6
+ |
+LL | m! { var x }
+ | ^^^
+ |
+help: write `let` instead of `var` to introduce a new variable
+ |
+LL | m! { let x }
+ | ~~~
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.rs b/src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.rs
new file mode 100644
index 000000000..24150376e
--- /dev/null
+++ b/src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.rs
@@ -0,0 +1,8 @@
+#![feature(concat_bytes)]
+
+fn main() {
+ concat_bytes!(7Y);
+ //~^ ERROR invalid suffix `Y` for number literal
+ concat_bytes!(888888888888888888888888888888888888888);
+ //~^ ERROR integer literal is too large
+}
diff --git a/src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.stderr b/src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.stderr
new file mode 100644
index 000000000..8d70faa49
--- /dev/null
+++ b/src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.stderr
@@ -0,0 +1,16 @@
+error: invalid suffix `Y` for number literal
+ --> $DIR/issue-104769-concat_bytes-invalid-literal.rs:4:19
+ |
+LL | concat_bytes!(7Y);
+ | ^^ invalid suffix `Y`
+ |
+ = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
+error: integer literal is too large
+ --> $DIR/issue-104769-concat_bytes-invalid-literal.rs:6:19
+ |
+LL | concat_bytes!(888888888888888888888888888888888888888);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/macros/issue-105011.rs b/src/test/ui/macros/issue-105011.rs
new file mode 100644
index 000000000..da12c3814
--- /dev/null
+++ b/src/test/ui/macros/issue-105011.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!(""y); //~ ERROR suffixes on string literals are invalid
+}
diff --git a/src/test/ui/macros/issue-105011.stderr b/src/test/ui/macros/issue-105011.stderr
new file mode 100644
index 000000000..e898af7fa
--- /dev/null
+++ b/src/test/ui/macros/issue-105011.stderr
@@ -0,0 +1,8 @@
+error: suffixes on string literals are invalid
+ --> $DIR/issue-105011.rs:2:14
+ |
+LL | println!(""y);
+ | ^^^ invalid suffix `y`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/macros/issue-38715.rs b/src/test/ui/macros/issue-38715.rs
index 9a9a501ca..85ed97663 100644
--- a/src/test/ui/macros/issue-38715.rs
+++ b/src/test/ui/macros/issue-38715.rs
@@ -1,7 +1,17 @@
#[macro_export]
-macro_rules! foo { ($i:ident) => {} }
+macro_rules! foo { () => {} }
#[macro_export]
macro_rules! foo { () => {} } //~ ERROR the name `foo` is defined multiple times
+mod inner1 {
+ #[macro_export]
+ macro_rules! bar { () => {} }
+}
+
+mod inner2 {
+ #[macro_export]
+ macro_rules! bar { () => {} } //~ ERROR the name `bar` is defined multiple times
+}
+
fn main() {}
diff --git a/src/test/ui/macros/issue-38715.stderr b/src/test/ui/macros/issue-38715.stderr
index c87d9f736..828a7f459 100644
--- a/src/test/ui/macros/issue-38715.stderr
+++ b/src/test/ui/macros/issue-38715.stderr
@@ -1,7 +1,7 @@
error[E0428]: the name `foo` is defined multiple times
--> $DIR/issue-38715.rs:5:1
|
-LL | macro_rules! foo { ($i:ident) => {} }
+LL | macro_rules! foo { () => {} }
| ---------------- previous definition of the macro `foo` here
...
LL | macro_rules! foo { () => {} }
@@ -9,6 +9,17 @@ LL | macro_rules! foo { () => {} }
|
= note: `foo` must be defined only once in the macro namespace of this module
-error: aborting due to previous error
+error[E0428]: the name `bar` is defined multiple times
+ --> $DIR/issue-38715.rs:14:5
+ |
+LL | macro_rules! bar { () => {} }
+ | ---------------- previous definition of the macro `bar` here
+...
+LL | macro_rules! bar { () => {} }
+ | ^^^^^^^^^^^^^^^^ `bar` redefined here
+ |
+ = note: `bar` must be defined only once in the macro namespace of this module
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0428`.
diff --git a/src/test/ui/macros/issue-68060.rs b/src/test/ui/macros/issue-68060.rs
index aa8f578ad..fb40cd538 100644
--- a/src/test/ui/macros/issue-68060.rs
+++ b/src/test/ui/macros/issue-68060.rs
@@ -3,7 +3,11 @@ fn main() {
.map(
#[target_feature(enable = "")]
//~^ ERROR: attribute should be applied to a function
+ //~| ERROR: feature named `` is not valid
+ //~| NOTE: `` is not valid for this target
#[track_caller]
+ //~^ ERROR: `#[track_caller]` on closures is currently unstable
+ //~| NOTE: see issue #87417
|_| (),
//~^ NOTE: not a function
)
diff --git a/src/test/ui/macros/issue-68060.stderr b/src/test/ui/macros/issue-68060.stderr
index b13e418e6..52e6ed92e 100644
--- a/src/test/ui/macros/issue-68060.stderr
+++ b/src/test/ui/macros/issue-68060.stderr
@@ -7,5 +7,21 @@ LL | #[target_feature(enable = "")]
LL | |_| (),
| ------ not a function definition
-error: aborting due to previous error
+error: the feature named `` is not valid for this target
+ --> $DIR/issue-68060.rs:4:30
+ |
+LL | #[target_feature(enable = "")]
+ | ^^^^^^^^^^^ `` is not valid for this target
+
+error[E0658]: `#[track_caller]` on closures is currently unstable
+ --> $DIR/issue-68060.rs:8:13
+ |
+LL | #[track_caller]
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: see issue #87417 <https://github.com/rust-lang/rust/issues/87417> for more information
+ = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2015.stderr b/src/test/ui/macros/macro-at-most-once-rep-2015.stderr
index 9a3df858e..7c45b85bc 100644
--- a/src/test/ui/macros/macro-at-most-once-rep-2015.stderr
+++ b/src/test/ui/macros/macro-at-most-once-rep-2015.stderr
@@ -12,6 +12,8 @@ LL | macro_rules! foo {
...
LL | foo!(a?);
| ^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence end
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2015.rs:26:11
@@ -21,6 +23,8 @@ LL | macro_rules! foo {
...
LL | foo!(a?a);
| ^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence end
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2015.rs:27:11
@@ -30,6 +34,8 @@ LL | macro_rules! foo {
...
LL | foo!(a?a?a);
| ^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence end
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2015.rs:29:5
@@ -39,6 +45,12 @@ LL | macro_rules! barplus {
...
LL | barplus!();
| ^^^^^^^^^^ missing tokens in macro arguments
+ |
+note: while trying to match `+`
+ --> $DIR/macro-at-most-once-rep-2015.rs:15:11
+ |
+LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
+ | ^
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2015.rs:30:15
@@ -48,6 +60,12 @@ LL | macro_rules! barplus {
...
LL | barplus!(a);
| ^ missing tokens in macro arguments
+ |
+note: while trying to match `+`
+ --> $DIR/macro-at-most-once-rep-2015.rs:15:11
+ |
+LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
+ | ^
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2015.rs:31:15
@@ -57,6 +75,12 @@ LL | macro_rules! barplus {
...
LL | barplus!(a?);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match `+`
+ --> $DIR/macro-at-most-once-rep-2015.rs:15:11
+ |
+LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
+ | ^
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2015.rs:32:15
@@ -66,6 +90,12 @@ LL | macro_rules! barplus {
...
LL | barplus!(a?a);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match `+`
+ --> $DIR/macro-at-most-once-rep-2015.rs:15:11
+ |
+LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
+ | ^
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2015.rs:36:5
@@ -75,6 +105,12 @@ LL | macro_rules! barstar {
...
LL | barstar!();
| ^^^^^^^^^^ missing tokens in macro arguments
+ |
+note: while trying to match `*`
+ --> $DIR/macro-at-most-once-rep-2015.rs:19:11
+ |
+LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
+ | ^
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2015.rs:37:15
@@ -84,6 +120,12 @@ LL | macro_rules! barstar {
...
LL | barstar!(a);
| ^ missing tokens in macro arguments
+ |
+note: while trying to match `*`
+ --> $DIR/macro-at-most-once-rep-2015.rs:19:11
+ |
+LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
+ | ^
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2015.rs:38:15
@@ -93,6 +135,12 @@ LL | macro_rules! barstar {
...
LL | barstar!(a?);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match `*`
+ --> $DIR/macro-at-most-once-rep-2015.rs:19:11
+ |
+LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
+ | ^
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2015.rs:39:15
@@ -102,6 +150,12 @@ LL | macro_rules! barstar {
...
LL | barstar!(a?a);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match `*`
+ --> $DIR/macro-at-most-once-rep-2015.rs:19:11
+ |
+LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
+ | ^
error: aborting due to 12 previous errors
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr
index 013fabe13..696520b28 100644
--- a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr
+++ b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr
@@ -12,6 +12,8 @@ LL | macro_rules! foo {
...
LL | foo!(a?);
| ^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence end
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:26:11
@@ -21,6 +23,8 @@ LL | macro_rules! foo {
...
LL | foo!(a?a);
| ^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence end
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:27:11
@@ -30,6 +34,8 @@ LL | macro_rules! foo {
...
LL | foo!(a?a?a);
| ^ no rules expected this token in macro call
+ |
+ = note: while trying to match sequence end
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2018.rs:29:5
@@ -39,6 +45,12 @@ LL | macro_rules! barplus {
...
LL | barplus!();
| ^^^^^^^^^^ missing tokens in macro arguments
+ |
+note: while trying to match `+`
+ --> $DIR/macro-at-most-once-rep-2018.rs:15:11
+ |
+LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
+ | ^
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2018.rs:30:15
@@ -48,6 +60,12 @@ LL | macro_rules! barplus {
...
LL | barplus!(a);
| ^ missing tokens in macro arguments
+ |
+note: while trying to match `+`
+ --> $DIR/macro-at-most-once-rep-2018.rs:15:11
+ |
+LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
+ | ^
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:31:15
@@ -57,6 +75,12 @@ LL | macro_rules! barplus {
...
LL | barplus!(a?);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match `+`
+ --> $DIR/macro-at-most-once-rep-2018.rs:15:11
+ |
+LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
+ | ^
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:32:15
@@ -66,6 +90,12 @@ LL | macro_rules! barplus {
...
LL | barplus!(a?a);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match `+`
+ --> $DIR/macro-at-most-once-rep-2018.rs:15:11
+ |
+LL | ($(a)?+) => {}; // ok. matches "a+" and "+"
+ | ^
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2018.rs:36:5
@@ -75,6 +105,12 @@ LL | macro_rules! barstar {
...
LL | barstar!();
| ^^^^^^^^^^ missing tokens in macro arguments
+ |
+note: while trying to match `*`
+ --> $DIR/macro-at-most-once-rep-2018.rs:19:11
+ |
+LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
+ | ^
error: unexpected end of macro invocation
--> $DIR/macro-at-most-once-rep-2018.rs:37:15
@@ -84,6 +120,12 @@ LL | macro_rules! barstar {
...
LL | barstar!(a);
| ^ missing tokens in macro arguments
+ |
+note: while trying to match `*`
+ --> $DIR/macro-at-most-once-rep-2018.rs:19:11
+ |
+LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
+ | ^
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:38:15
@@ -93,6 +135,12 @@ LL | macro_rules! barstar {
...
LL | barstar!(a?);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match `*`
+ --> $DIR/macro-at-most-once-rep-2018.rs:19:11
+ |
+LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
+ | ^
error: no rules expected the token `?`
--> $DIR/macro-at-most-once-rep-2018.rs:39:15
@@ -102,6 +150,12 @@ LL | macro_rules! barstar {
...
LL | barstar!(a?a);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match `*`
+ --> $DIR/macro-at-most-once-rep-2018.rs:19:11
+ |
+LL | ($(a)?*) => {}; // ok. matches "a*" and "*"
+ | ^
error: aborting due to 12 previous errors
diff --git a/src/test/ui/macros/macro-non-lifetime.stderr b/src/test/ui/macros/macro-non-lifetime.stderr
index 6234735df..e1ed87f94 100644
--- a/src/test/ui/macros/macro-non-lifetime.stderr
+++ b/src/test/ui/macros/macro-non-lifetime.stderr
@@ -6,6 +6,12 @@ LL | macro_rules! m { ($x:lifetime) => { } }
...
LL | m!(a);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$x:lifetime`
+ --> $DIR/macro-non-lifetime.rs:3:19
+ |
+LL | macro_rules! m { ($x:lifetime) => { } }
+ | ^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr
index 6da92bdea..81877a29e 100644
--- a/src/test/ui/macros/missing-comma.stderr
+++ b/src/test/ui/macros/missing-comma.stderr
@@ -14,6 +14,12 @@ LL | foo!(a b);
| -^ no rules expected this token in macro call
| |
| help: missing comma here
+ |
+note: while trying to match meta-variable `$a:ident`
+ --> $DIR/missing-comma.rs:2:6
+ |
+LL | ($a:ident) => ();
+ | ^^^^^^^^
error: no rules expected the token `e`
--> $DIR/missing-comma.rs:23:21
@@ -25,6 +31,12 @@ LL | foo!(a, b, c, d e);
| -^ no rules expected this token in macro call
| |
| help: missing comma here
+ |
+note: while trying to match meta-variable `$d:ident`
+ --> $DIR/missing-comma.rs:5:36
+ |
+LL | ($a:ident, $b:ident, $c:ident, $d:ident) => ();
+ | ^^^^^^^^
error: no rules expected the token `d`
--> $DIR/missing-comma.rs:25:18
@@ -36,6 +48,12 @@ LL | foo!(a, b, c d, e);
| -^ no rules expected this token in macro call
| |
| help: missing comma here
+ |
+note: while trying to match meta-variable `$c:ident`
+ --> $DIR/missing-comma.rs:4:26
+ |
+LL | ($a:ident, $b:ident, $c:ident) => ();
+ | ^^^^^^^^
error: no rules expected the token `d`
--> $DIR/missing-comma.rs:27:18
@@ -45,6 +63,12 @@ LL | macro_rules! foo {
...
LL | foo!(a, b, c d e);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$c:ident`
+ --> $DIR/missing-comma.rs:4:26
+ |
+LL | ($a:ident, $b:ident, $c:ident) => ();
+ | ^^^^^^^^
error: unexpected end of macro invocation
--> $DIR/missing-comma.rs:29:23
@@ -54,6 +78,12 @@ LL | macro_rules! bar {
...
LL | bar!(Level::Error, );
| ^ missing tokens in macro arguments
+ |
+note: while trying to match meta-variable `$arg:tt`
+ --> $DIR/missing-comma.rs:10:19
+ |
+LL | ($lvl:expr, $($arg:tt)+) => {}
+ | ^^^^^^^
error: no rules expected the token `,`
--> $DIR/missing-comma.rs:32:38
@@ -63,6 +93,12 @@ LL | macro_rules! check {
...
LL | check!(<str as Debug>::fmt, "fmt",);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$expected:expr`
+ --> $DIR/missing-comma.rs:14:14
+ |
+LL | ($ty:ty, $expected:expr) => {};
+ | ^^^^^^^^^^^^^^
error: aborting due to 7 previous errors
diff --git a/src/test/ui/macros/nonterminal-matching.stderr b/src/test/ui/macros/nonterminal-matching.stderr
index 585f23553..5bbd54390 100644
--- a/src/test/ui/macros/nonterminal-matching.stderr
+++ b/src/test/ui/macros/nonterminal-matching.stderr
@@ -10,6 +10,14 @@ LL | n!(a $nt_item b);
LL | complex_nonterminal!(enum E {});
| ------------------------------- in this macro invocation
|
+note: while trying to match `enum E {}`
+ --> $DIR/nonterminal-matching.rs:15:15
+ |
+LL | macro n(a $nt_item b) {
+ | ^^^^^^^^
+...
+LL | complex_nonterminal!(enum E {});
+ | ------------------------------- in this macro invocation
= note: this error originates in the macro `complex_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
diff --git a/src/test/ui/macros/recovery-allowed.rs b/src/test/ui/macros/recovery-allowed.rs
new file mode 100644
index 000000000..ebf65f1cc
--- /dev/null
+++ b/src/test/ui/macros/recovery-allowed.rs
@@ -0,0 +1,8 @@
+macro_rules! please_recover {
+ ($a:expr) => {};
+}
+
+please_recover! { not 1 }
+//~^ ERROR unexpected `1` after identifier
+
+fn main() {}
diff --git a/src/test/ui/macros/recovery-allowed.stderr b/src/test/ui/macros/recovery-allowed.stderr
new file mode 100644
index 000000000..ec036e8b1
--- /dev/null
+++ b/src/test/ui/macros/recovery-allowed.stderr
@@ -0,0 +1,10 @@
+error: unexpected `1` after identifier
+ --> $DIR/recovery-allowed.rs:5:23
+ |
+LL | please_recover! { not 1 }
+ | ----^
+ | |
+ | help: use `!` to perform bitwise not
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/macros/recovery-forbidden.rs b/src/test/ui/macros/recovery-forbidden.rs
new file mode 100644
index 000000000..5dd261933
--- /dev/null
+++ b/src/test/ui/macros/recovery-forbidden.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+macro_rules! dont_recover_here {
+ ($e:expr) => {
+ compile_error!("Must not recover to single !1 expr");
+ };
+
+ (not $a:literal) => {};
+}
+
+dont_recover_here! { not 1 }
+
+fn main() {}
diff --git a/src/test/ui/macros/syntax-error-recovery.stderr b/src/test/ui/macros/syntax-error-recovery.stderr
index c153b3b91..c42ee9b29 100644
--- a/src/test/ui/macros/syntax-error-recovery.stderr
+++ b/src/test/ui/macros/syntax-error-recovery.stderr
@@ -7,6 +7,7 @@ LL | $token $($inner)? = $value,
LL | values!(STRING(1) as (String) => cfg(test),);
| -------------------------------------------- in this macro invocation
|
+ = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
= note: this error originates in the macro `values` (in Nightly builds, run with -Z macro-backtrace for more info)
error: macro expansion ignores token `(String)` and any following
diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr
index d6fc69402..21e47da07 100644
--- a/src/test/ui/macros/trace_faulty_macros.stderr
+++ b/src/test/ui/macros/trace_faulty_macros.stderr
@@ -10,6 +10,7 @@ LL | my_faulty_macro!(bcd);
LL | my_faulty_macro!();
| ------------------ in this macro invocation
|
+ = note: while trying to match end of macro
= note: this error originates in the macro `my_faulty_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
note: trace_macro
diff --git a/src/test/ui/issues/issue-12552.rs b/src/test/ui/match/issue-12552.rs
index b7f71dd1c..b7f71dd1c 100644
--- a/src/test/ui/issues/issue-12552.rs
+++ b/src/test/ui/match/issue-12552.rs
diff --git a/src/test/ui/issues/issue-12552.stderr b/src/test/ui/match/issue-12552.stderr
index 4b027eba2..4b027eba2 100644
--- a/src/test/ui/issues/issue-12552.stderr
+++ b/src/test/ui/match/issue-12552.stderr
diff --git a/src/test/ui/maximal_mir_to_hir_coverage.rs b/src/test/ui/maximal_mir_to_hir_coverage.rs
new file mode 100644
index 000000000..5ca54633f
--- /dev/null
+++ b/src/test/ui/maximal_mir_to_hir_coverage.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Zmaximal-hir-to-mir-coverage
+// run-pass
+
+// Just making sure this flag is accepted and doesn't crash the compiler
+
+fn main() {
+ let x = 1;
+ let y = x + 1;
+ println!("{y}");
+}
diff --git a/src/test/ui/methods/method-call-lifetime-args-fail.stderr b/src/test/ui/methods/method-call-lifetime-args-fail.stderr
index 835edb4b0..249b48ab1 100644
--- a/src/test/ui/methods/method-call-lifetime-args-fail.stderr
+++ b/src/test/ui/methods/method-call-lifetime-args-fail.stderr
@@ -13,8 +13,8 @@ LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
| ^^^^^ -- --
help: add missing lifetime argument
|
-LL | S.early::<'static, 'b>();
- | ++++
+LL | S.early::<'static, 'static>();
+ | +++++++++
error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied
--> $DIR/method-call-lifetime-args-fail.rs:18:7
@@ -213,8 +213,8 @@ LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
| ^^^^^ -- --
help: add missing lifetime argument
|
-LL | S::early::<'static, 'b>(S);
- | ++++
+LL | S::early::<'static, 'static>(S);
+ | +++++++++
error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied
--> $DIR/method-call-lifetime-args-fail.rs:65:8
diff --git a/src/test/ui/methods/method-path-in-pattern.stderr b/src/test/ui/methods/method-path-in-pattern.stderr
index 1d1bdb6b0..63c7abe0e 100644
--- a/src/test/ui/methods/method-path-in-pattern.stderr
+++ b/src/test/ui/methods/method-path-in-pattern.stderr
@@ -2,37 +2,37 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f
--> $DIR/method-path-in-pattern.rs:15:9
|
LL | Foo::bar => {}
- | ^^^^^^^^
+ | ^^^^^^^^ not a unit struct, unit variant or constant
error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar`
--> $DIR/method-path-in-pattern.rs:19:9
|
LL | <Foo>::bar => {}
- | ^^^^^^^^^^
+ | ^^^^^^^^^^ not a unit struct, unit variant or constant
error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::trait_bar`
--> $DIR/method-path-in-pattern.rs:23:9
|
LL | <Foo>::trait_bar => {}
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar`
--> $DIR/method-path-in-pattern.rs:26:12
|
LL | if let Foo::bar = 0u32 {}
- | ^^^^^^^^
+ | ^^^^^^^^ not a unit struct, unit variant or constant
error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar`
--> $DIR/method-path-in-pattern.rs:28:12
|
LL | if let <Foo>::bar = 0u32 {}
- | ^^^^^^^^^^
+ | ^^^^^^^^^^ not a unit struct, unit variant or constant
error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::trait_bar`
--> $DIR/method-path-in-pattern.rs:30:12
|
LL | if let Foo::trait_bar = 0u32 {}
- | ^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
error: aborting due to 6 previous errors
diff --git a/src/test/ui/mir/important-higher-ranked-regions.rs b/src/test/ui/mir/important-higher-ranked-regions.rs
new file mode 100644
index 000000000..cadfb3b66
--- /dev/null
+++ b/src/test/ui/mir/important-higher-ranked-regions.rs
@@ -0,0 +1,26 @@
+// check-pass
+// compile-flags: -Zvalidate-mir
+
+// This test checks that bivariant parameters are handled correctly
+// in the mir.
+#![allow(coherence_leak_check)]
+trait Trait {
+ type Assoc;
+}
+
+struct Foo<T, U>(T)
+where
+ T: Trait<Assoc = U>;
+
+impl Trait for for<'a> fn(&'a ()) {
+ type Assoc = u32;
+}
+impl Trait for fn(&'static ()) {
+ type Assoc = String;
+}
+
+fn foo(x: Foo<for<'a> fn(&'a ()), u32>) -> Foo<fn(&'static ()), String> {
+ x
+}
+
+fn main() {}
diff --git a/src/test/ui/mir/mir_ascription_coercion.rs b/src/test/ui/mir/mir_ascription_coercion.rs
index 0ebd20e97..9e04d6019 100644
--- a/src/test/ui/mir/mir_ascription_coercion.rs
+++ b/src/test/ui/mir/mir_ascription_coercion.rs
@@ -6,5 +6,5 @@
fn main() {
let x = [1, 2, 3];
// The RHS should coerce to &[i32]
- let _y : &[i32] = &x : &[i32; 3];
+ let _y : &[i32] = type_ascribe!(&x, &[i32; 3]);
}
diff --git a/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs b/src/test/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs
index cd6c5bf27..cd6c5bf27 100644
--- a/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs
+++ b/src/test/ui/mir/validate/issue-95978-validator-lifetime-comparison.rs
diff --git a/src/test/ui/mir/validate/needs-reveal-all.rs b/src/test/ui/mir/validate/needs-reveal-all.rs
new file mode 100644
index 000000000..3852daf24
--- /dev/null
+++ b/src/test/ui/mir/validate/needs-reveal-all.rs
@@ -0,0 +1,52 @@
+// Regression test for #105009. the issue here was that even after the `RevealAll` pass,
+// `validate` still used `Reveal::UserFacing`. This meant that it now ends up comparing
+// opaque types with their revealed version, resulting in an ICE.
+//
+// We're using these flags to run the `RevealAll` pass while making it less likely to
+// accidentally removing the assignment from `Foo<fn_ptr>` to `Foo<fn_def>`.
+
+// compile-flags: -Zinline_mir=yes -Zmir-opt-level=0 -Zvalidate-mir
+// run-pass
+
+use std::hint::black_box;
+
+trait Func {
+ type Ret: Id;
+}
+
+trait Id {
+ type Assoc;
+}
+impl Id for u32 {
+ type Assoc = u32;
+}
+impl Id for i32 {
+ type Assoc = i32;
+}
+
+impl<F: FnOnce() -> R, R: Id> Func for F {
+ type Ret = R;
+}
+
+fn bar() -> impl Copy + Id {
+ 0u32
+}
+
+struct Foo<T: Func> {
+ _func: T,
+ value: Option<<<T as Func>::Ret as Id>::Assoc>,
+}
+
+fn main() {
+ let mut fn_def = black_box(Foo {
+ _func: bar,
+ value: None,
+ });
+ let fn_ptr = black_box(Foo {
+ _func: bar as fn() -> _,
+ value: None,
+ });
+
+ fn_def.value = fn_ptr.value;
+ black_box(fn_def);
+}
diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr
index 3de652d87..3585587ed 100644
--- a/src/test/ui/mismatched_types/binops.stderr
+++ b/src/test/ui/mismatched_types/binops.stderr
@@ -24,15 +24,10 @@ LL | 2 as usize - Some(1);
|
= help: the trait `Sub<Option<{integer}>>` is not implemented for `usize`
= help: the following other types implement trait `Sub<Rhs>`:
- <&'a f32 as Sub<f32>>
- <&'a f64 as Sub<f64>>
- <&'a i128 as Sub<i128>>
- <&'a i16 as Sub<i16>>
- <&'a i32 as Sub<i32>>
- <&'a i64 as Sub<i64>>
- <&'a i8 as Sub<i8>>
- <&'a isize as Sub<isize>>
- and 48 others
+ <&'a usize as Sub<usize>>
+ <&usize as Sub<&usize>>
+ <usize as Sub<&usize>>
+ <usize as Sub>
error[E0277]: cannot multiply `{integer}` by `()`
--> $DIR/binops.rs:4:7
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.rs b/src/test/ui/mismatched_types/overloaded-calls-bad.rs
index 902a6ec81..232cd2ba8 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.rs
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.rs
@@ -20,14 +20,23 @@ impl FnOnce<(isize,)> for S {
}
}
+struct F;
+
+impl FnOnce<(i32,)> for F {
+ type Output = ();
+
+ extern "rust-call" fn call_once(self, args: (i32,)) -> Self::Output {}
+}
+
fn main() {
- let mut s = S {
- x: 3,
- y: 3,
- };
- let ans = s("what"); //~ ERROR mismatched types
+ let mut s = S { x: 3, y: 3 };
+ let ans = s("what");
+ //~^ ERROR mismatched types
let ans = s();
//~^ ERROR this function takes 1 argument but 0 arguments were supplied
let ans = s("burma", "shave");
//~^ ERROR this function takes 1 argument but 2 arguments were supplied
+
+ F("");
+ //~^ ERROR mismatched types
}
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
index fb3597aa8..3a895acbd 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/overloaded-calls-bad.rs:28:17
+ --> $DIR/overloaded-calls-bad.rs:33:17
|
LL | let ans = s("what");
| - ^^^^^^ expected `isize`, found `&str`
@@ -13,7 +13,7 @@ LL | impl FnMut<(isize,)> for S {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0057]: this function takes 1 argument but 0 arguments were supplied
- --> $DIR/overloaded-calls-bad.rs:29:15
+ --> $DIR/overloaded-calls-bad.rs:35:15
|
LL | let ans = s();
| ^-- an argument of type `isize` is missing
@@ -29,7 +29,7 @@ LL | let ans = s(/* isize */);
| ~~~~~~~~~~~~~
error[E0057]: this function takes 1 argument but 2 arguments were supplied
- --> $DIR/overloaded-calls-bad.rs:31:15
+ --> $DIR/overloaded-calls-bad.rs:37:15
|
LL | let ans = s("burma", "shave");
| ^ ------- ------- argument of type `&'static str` unexpected
@@ -46,7 +46,21 @@ help: remove the extra argument
LL | let ans = s(/* isize */);
| ~~~~~~~~~~~~~
-error: aborting due to 3 previous errors
+error[E0308]: mismatched types
+ --> $DIR/overloaded-calls-bad.rs:40:7
+ |
+LL | F("");
+ | - ^^ expected `i32`, found `&str`
+ | |
+ | arguments to this struct are incorrect
+ |
+note: implementation defined here
+ --> $DIR/overloaded-calls-bad.rs:25:1
+ |
+LL | impl FnOnce<(i32,)> for F {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
Some errors have detailed explanations: E0057, E0308.
For more information about an error, try `rustc --explain E0057`.
diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
index 8dbe3472e..307104e47 100644
--- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
+++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
@@ -1,8 +1,8 @@
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures,tuple_trait)]
use std::ops::FnMut;
-fn to_fn_mut<A, F: FnMut<A>>(f: F) -> F { f }
+fn to_fn_mut<A:std::marker::Tuple, F:FnMut<A>>(f: F) -> F { f }
fn call_it<F: FnMut(isize, isize) -> isize>(y: isize, mut f: F) -> isize {
//~^ NOTE required by this bound in `call_it`
diff --git a/src/test/ui/moves/borrow-closures-instead-of-move.stderr b/src/test/ui/moves/borrow-closures-instead-of-move.stderr
index 3146b6959..9a84ddef7 100644
--- a/src/test/ui/moves/borrow-closures-instead-of-move.stderr
+++ b/src/test/ui/moves/borrow-closures-instead-of-move.stderr
@@ -4,9 +4,17 @@ error[E0382]: use of moved value: `f`
LL | fn takes_fn(f: impl Fn()) {
| - move occurs because `f` has type `impl Fn()`, which does not implement the `Copy` trait
LL | loop {
+ | ---- inside of this loop
LL | takes_fnonce(f);
| ^ value moved here, in previous iteration of loop
|
+note: consider changing this parameter type in function `takes_fnonce` to borrow instead if owning the value isn't necessary
+ --> $DIR/borrow-closures-instead-of-move.rs:34:20
+ |
+LL | fn takes_fnonce(_: impl FnOnce()) {}
+ | ------------ ^^^^^^^^^^^^^ this parameter takes ownership of the value
+ | |
+ | in this function
help: consider borrowing `f`
|
LL | takes_fnonce(&f);
@@ -24,6 +32,13 @@ LL | takes_fnonce(m);
LL | takes_fnonce(m);
| ^ value used here after move
|
+note: consider changing this parameter type in function `takes_fnonce` to borrow instead if owning the value isn't necessary
+ --> $DIR/borrow-closures-instead-of-move.rs:34:20
+ |
+LL | fn takes_fnonce(_: impl FnOnce()) {}
+ | ------------ ^^^^^^^^^^^^^ this parameter takes ownership of the value
+ | |
+ | in this function
help: consider mutably borrowing `m`
|
LL | takes_fnonce(&mut m);
diff --git a/src/test/ui/moves/issue-46099-move-in-macro.stderr b/src/test/ui/moves/issue-46099-move-in-macro.stderr
index baa87e3e9..94bc9e6f4 100644
--- a/src/test/ui/moves/issue-46099-move-in-macro.stderr
+++ b/src/test/ui/moves/issue-46099-move-in-macro.stderr
@@ -5,6 +5,11 @@ LL | let b = Box::new(true);
| - move occurs because `b` has type `Box<bool>`, which does not implement the `Copy` trait
LL | test!({b});
| ^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | test!({b.clone()});
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/moves/issue-72649-uninit-in-loop.rs b/src/test/ui/moves/issue-72649-uninit-in-loop.rs
index d76b69ecd..56c225bab 100644
--- a/src/test/ui/moves/issue-72649-uninit-in-loop.rs
+++ b/src/test/ui/moves/issue-72649-uninit-in-loop.rs
@@ -25,7 +25,7 @@ fn moved_here_1() {
fn moved_here_2() {
let value = NonCopy{};
//~^ NOTE move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
- loop {
+ loop { //~ NOTE inside of this loop
let _used = value;
//~^ NOTE value moved here
loop {
@@ -38,7 +38,7 @@ fn moved_here_2() {
fn moved_loop_1() {
let value = NonCopy{};
//~^ NOTE move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
- loop {
+ loop { //~ NOTE inside of this loop
let _used = value; //~ ERROR use of moved value: `value`
//~^ NOTE value moved here, in previous iteration of loop
}
@@ -49,7 +49,7 @@ fn moved_loop_2() {
//~^ NOTE move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
let _used = value;
value = NonCopy{};
- loop {
+ loop { //~ NOTE inside of this loop
let _used2 = value; //~ ERROR use of moved value: `value`
//~^ NOTE value moved here, in previous iteration of loop
}
diff --git a/src/test/ui/moves/issue-72649-uninit-in-loop.stderr b/src/test/ui/moves/issue-72649-uninit-in-loop.stderr
index 974994223..7e119fe8c 100644
--- a/src/test/ui/moves/issue-72649-uninit-in-loop.stderr
+++ b/src/test/ui/moves/issue-72649-uninit-in-loop.stderr
@@ -15,7 +15,9 @@ error[E0382]: use of moved value: `value`
|
LL | let value = NonCopy{};
| ----- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
-...
+LL |
+LL | loop {
+ | ---- inside of this loop
LL | let _used = value;
| ----- value moved here
...
@@ -27,7 +29,9 @@ error[E0382]: use of moved value: `value`
|
LL | let value = NonCopy{};
| ----- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
-...
+LL |
+LL | loop {
+ | ---- inside of this loop
LL | let _used = value;
| ^^^^^ value moved here, in previous iteration of loop
@@ -37,6 +41,8 @@ error[E0382]: use of moved value: `value`
LL | let mut value = NonCopy{};
| --------- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait
...
+LL | loop {
+ | ---- inside of this loop
LL | let _used2 = value;
| ^^^^^ value moved here, in previous iteration of loop
diff --git a/src/test/ui/moves/move-fn-self-receiver.stderr b/src/test/ui/moves/move-fn-self-receiver.stderr
index 3a686121a..c13dc5882 100644
--- a/src/test/ui/moves/move-fn-self-receiver.stderr
+++ b/src/test/ui/moves/move-fn-self-receiver.stderr
@@ -96,6 +96,10 @@ note: this function takes ownership of the receiver `self`, which moves `rc_foo`
|
LL | fn use_rc_self(self: Rc<Self>) {}
| ^^^^
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | rc_foo.clone().use_rc_self();
+ | ++++++++
error[E0382]: use of moved value: `foo_add`
--> $DIR/move-fn-self-receiver.rs:59:5
@@ -137,6 +141,11 @@ LL | for _val in explicit_into_iter.into_iter() {}
| ----------- `explicit_into_iter` moved due to this method call
LL | explicit_into_iter;
| ^^^^^^^^^^^^^^^^^^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | for _val in explicit_into_iter.clone().into_iter() {}
+ | ++++++++
error[E0382]: use of moved value: `container`
--> $DIR/move-fn-self-receiver.rs:71:5
@@ -160,6 +169,7 @@ error[E0382]: use of moved value: `foo2`
LL | let foo2 = Foo;
| ---- move occurs because `foo2` has type `Foo`, which does not implement the `Copy` trait
LL | loop {
+ | ---- inside of this loop
LL | foo2.use_self();
| ^^^^ ---------- `foo2` moved due to this method call, in previous iteration of loop
diff --git a/src/test/ui/moves/move-guard-same-consts.stderr b/src/test/ui/moves/move-guard-same-consts.stderr
index 2048fefef..86e5f6524 100644
--- a/src/test/ui/moves/move-guard-same-consts.stderr
+++ b/src/test/ui/moves/move-guard-same-consts.stderr
@@ -8,6 +8,18 @@ LL | (1, 2) if take(x) => (),
| - value moved here
LL | (1, 2) if take(x) => (),
| ^ value used here after move
+ |
+note: consider changing this parameter type in function `take` to borrow instead if owning the value isn't necessary
+ --> $DIR/move-guard-same-consts.rs:25:15
+ |
+LL | fn take<T>(_: T) -> bool { false }
+ | ---- ^ this parameter takes ownership of the value
+ | |
+ | in this function
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | (1, 2) if take(x.clone()) => (),
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/moves/move-in-guard-1.stderr b/src/test/ui/moves/move-in-guard-1.stderr
index 5e9aa66b9..f04cb34d7 100644
--- a/src/test/ui/moves/move-in-guard-1.stderr
+++ b/src/test/ui/moves/move-in-guard-1.stderr
@@ -8,6 +8,18 @@ LL | (1, _) if take(x) => (),
| - value moved here
LL | (_, 2) if take(x) => (),
| ^ value used here after move
+ |
+note: consider changing this parameter type in function `take` to borrow instead if owning the value isn't necessary
+ --> $DIR/move-in-guard-1.rs:15:15
+ |
+LL | fn take<T>(_: T) -> bool { false }
+ | ---- ^ this parameter takes ownership of the value
+ | |
+ | in this function
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | (1, _) if take(x.clone()) => (),
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/moves/move-in-guard-2.stderr b/src/test/ui/moves/move-in-guard-2.stderr
index 8d636c11b..26047861f 100644
--- a/src/test/ui/moves/move-in-guard-2.stderr
+++ b/src/test/ui/moves/move-in-guard-2.stderr
@@ -6,6 +6,18 @@ LL | let x: Box<_> = Box::new(1);
...
LL | (_, 2) if take(x) => (),
| ^ value used here after move
+ |
+note: consider changing this parameter type in function `take` to borrow instead if owning the value isn't necessary
+ --> $DIR/move-in-guard-2.rs:13:15
+ |
+LL | fn take<T>(_: T) -> bool { false }
+ | ---- ^ this parameter takes ownership of the value
+ | |
+ | in this function
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | (_, 2) if take(x.clone()) => (),
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/moves/moves-based-on-type-access-to-field.stderr b/src/test/ui/moves/moves-based-on-type-access-to-field.stderr
index 3cc8ca291..a49ee31b4 100644
--- a/src/test/ui/moves/moves-based-on-type-access-to-field.stderr
+++ b/src/test/ui/moves/moves-based-on-type-access-to-field.stderr
@@ -13,6 +13,10 @@ note: this function takes ownership of the receiver `self`, which moves `x`
|
LL | fn into_iter(self) -> Self::IntoIter;
| ^^^^
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | consume(x.clone().into_iter().next().unwrap());
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/moves/moves-based-on-type-cyclic-types-issue-4821.stderr b/src/test/ui/moves/moves-based-on-type-cyclic-types-issue-4821.stderr
index a315bbaab..db4382b58 100644
--- a/src/test/ui/moves/moves-based-on-type-cyclic-types-issue-4821.stderr
+++ b/src/test/ui/moves/moves-based-on-type-cyclic-types-issue-4821.stderr
@@ -8,7 +8,7 @@ LL | consume(node) + r
| ^^^^ value used here after partial move
|
= note: partial move occurs because value has type `Box<List>`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `node.next.0`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | Some(ref right) => consume(right),
| +++
diff --git a/src/test/ui/moves/moves-based-on-type-distribute-copy-over-paren.stderr b/src/test/ui/moves/moves-based-on-type-distribute-copy-over-paren.stderr
index ee7971691..0930df148 100644
--- a/src/test/ui/moves/moves-based-on-type-distribute-copy-over-paren.stderr
+++ b/src/test/ui/moves/moves-based-on-type-distribute-copy-over-paren.stderr
@@ -9,6 +9,11 @@ LL | let _y = Foo { f:x };
LL |
LL | touch(&x);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _y = Foo { f:x.clone() };
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/moves-based-on-type-distribute-copy-over-paren.rs:21:11
@@ -21,6 +26,11 @@ LL | let _y = Foo { f:(((x))) };
LL |
LL | touch(&x);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _y = Foo { f:(((x))).clone() };
+ | ++++++++
error: aborting due to 2 previous errors
diff --git a/src/test/ui/moves/moves-based-on-type-exprs.stderr b/src/test/ui/moves/moves-based-on-type-exprs.stderr
index 9bcec3674..838b1282c 100644
--- a/src/test/ui/moves/moves-based-on-type-exprs.stderr
+++ b/src/test/ui/moves/moves-based-on-type-exprs.stderr
@@ -7,6 +7,11 @@ LL | let _y = Foo { f:x };
| - value moved here
LL | touch(&x);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _y = Foo { f:x.clone() };
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/moves-based-on-type-exprs.rs:18:11
@@ -17,6 +22,11 @@ LL | let _y = (x, 3);
| - value moved here
LL | touch(&x);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _y = (x.clone(), 3);
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/moves-based-on-type-exprs.rs:35:11
@@ -29,6 +39,11 @@ LL | x
...
LL | touch(&x);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | x.clone()
+ | ++++++++
error[E0382]: borrow of moved value: `y`
--> $DIR/moves-based-on-type-exprs.rs:36:11
@@ -41,6 +56,11 @@ LL | y
...
LL | touch(&y);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | y.clone()
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/moves-based-on-type-exprs.rs:46:11
@@ -53,6 +73,11 @@ LL | true => x,
...
LL | touch(&x);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | true => x.clone(),
+ | ++++++++
error[E0382]: borrow of moved value: `y`
--> $DIR/moves-based-on-type-exprs.rs:47:11
@@ -65,6 +90,11 @@ LL | false => y
...
LL | touch(&y);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | false => y.clone()
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/moves-based-on-type-exprs.rs:58:11
@@ -77,6 +107,18 @@ LL | _ if guard(x) => 10,
...
LL | touch(&x);
| ^^ value borrowed here after move
+ |
+note: consider changing this parameter type in function `guard` to borrow instead if owning the value isn't necessary
+ --> $DIR/moves-based-on-type-exprs.rs:6:14
+ |
+LL | fn guard(_s: String) -> bool {panic!()}
+ | ----- ^^^^^^ this parameter takes ownership of the value
+ | |
+ | in this function
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | _ if guard(x.clone()) => 10,
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/moves-based-on-type-exprs.rs:65:11
@@ -87,6 +129,11 @@ LL | let _y = [x];
| - value moved here
LL | touch(&x);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _y = [x.clone()];
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/moves-based-on-type-exprs.rs:71:11
@@ -97,6 +144,11 @@ LL | let _y = vec![x];
| - value moved here
LL | touch(&x);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _y = vec![x.clone()];
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/moves-based-on-type-exprs.rs:77:11
@@ -113,6 +165,10 @@ note: this function takes ownership of the receiver `self`, which moves `x`
|
LL | fn into_iter(self) -> Self::IntoIter;
| ^^^^
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _y = x.clone().into_iter().next().unwrap();
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/moves-based-on-type-exprs.rs:83:11
@@ -129,6 +185,10 @@ note: this function takes ownership of the receiver `self`, which moves `x`
|
LL | fn into_iter(self) -> Self::IntoIter;
| ^^^^
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _y = [x.clone().into_iter().next().unwrap(); 1];
+ | ++++++++
error: aborting due to 11 previous errors
diff --git a/src/test/ui/moves/moves-based-on-type-match-bindings.stderr b/src/test/ui/moves/moves-based-on-type-match-bindings.stderr
index ad1a2db8b..225935532 100644
--- a/src/test/ui/moves/moves-based-on-type-match-bindings.stderr
+++ b/src/test/ui/moves/moves-based-on-type-match-bindings.stderr
@@ -8,6 +8,10 @@ LL | touch(&x);
| ^^ value borrowed here after partial move
|
= note: partial move occurs because `x.f` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | Foo {ref f} => {}
+ | +++
error: aborting due to previous error
diff --git a/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs b/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs
index 76b7aab54..490d91ac1 100644
--- a/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs
+++ b/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs
@@ -1,6 +1,6 @@
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, tuple_trait)]
-fn to_fn<A,F:Fn<A>>(f: F) -> F { f }
+fn to_fn<A:std::marker::Tuple,F:Fn<A>>(f: F) -> F { f }
fn test(_x: Box<usize>) {}
diff --git a/src/test/ui/moves/moves-based-on-type-tuple.stderr b/src/test/ui/moves/moves-based-on-type-tuple.stderr
index eef8ce61f..0bcce3012 100644
--- a/src/test/ui/moves/moves-based-on-type-tuple.stderr
+++ b/src/test/ui/moves/moves-based-on-type-tuple.stderr
@@ -8,6 +8,11 @@ LL | Box::new((x, x))
| - ^ value used here after move
| |
| value moved here
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | Box::new((x.clone(), x))
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/moves/use_of_moved_value_clone_suggestions.stderr b/src/test/ui/moves/use_of_moved_value_clone_suggestions.stderr
index c25981e6f..22e7951db 100644
--- a/src/test/ui/moves/use_of_moved_value_clone_suggestions.stderr
+++ b/src/test/ui/moves/use_of_moved_value_clone_suggestions.stderr
@@ -7,6 +7,11 @@ LL | (t, t)
| - ^ value used here after move
| |
| value moved here
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | (t.clone(), t)
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/namespace/namespace-mix.rs b/src/test/ui/namespace/namespace-mix.rs
index b0f7e3c62..c5b30f148 100644
--- a/src/test/ui/namespace/namespace-mix.rs
+++ b/src/test/ui/namespace/namespace-mix.rs
@@ -97,13 +97,13 @@ mod m8 {
fn f78() {
check(m7::V{}); //~ ERROR c::Item
- check(m7::V); //~ ERROR expected value, found struct variant `m7::V`
+ check(m7::V); //~ ERROR expected value, found type alias `m7::V`
check(m8::V{}); //~ ERROR c::E
check(m8::V); //~ ERROR c::Item
}
fn xf78() {
check(xm7::V{}); //~ ERROR c::Item
- check(xm7::V); //~ ERROR expected value, found struct variant `xm7::V`
+ check(xm7::V); //~ ERROR expected value, found type alias `xm7::V`
check(xm8::V{}); //~ ERROR c::E
check(xm8::V); //~ ERROR c::Item
}
diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr
index c07914df7..cb72d4a1c 100644
--- a/src/test/ui/namespace/namespace-mix.stderr
+++ b/src/test/ui/namespace/namespace-mix.stderr
@@ -52,21 +52,16 @@ LL - check(xm1::S);
LL + check(S);
|
-error[E0423]: expected value, found struct variant `m7::V`
+error[E0423]: expected value, found type alias `m7::V`
--> $DIR/namespace-mix.rs:100:11
|
-LL | V {},
- | ---- `m7::V` defined here
LL | TV(),
| ---- similarly named tuple variant `TV` defined here
...
LL | check(m7::V);
| ^^^^^
|
-help: use struct literal syntax instead
- |
-LL | check(m7::V {});
- | ~~~~~~~~
+ = note: can't use a type alias as a constructor
help: a tuple variant with a similar name exists
|
LL | check(m7::TV);
@@ -83,23 +78,18 @@ LL - check(m7::V);
LL + check(V);
|
-error[E0423]: expected value, found struct variant `xm7::V`
+error[E0423]: expected value, found type alias `xm7::V`
--> $DIR/namespace-mix.rs:106:11
|
LL | check(xm7::V);
| ^^^^^^
|
- ::: $DIR/auxiliary/namespace-mix.rs:6:9
+ ::: $DIR/auxiliary/namespace-mix.rs:7:9
|
-LL | V {},
- | - `xm7::V` defined here
LL | TV(),
| -- similarly named tuple variant `TV` defined here
|
-help: use struct literal syntax instead
- |
-LL | check(xm7::V { /* fields */ });
- | ~~~~~~~~~~~~~~~~~~~~~~~
+ = note: can't use a type alias as a constructor
help: a tuple variant with a similar name exists
|
LL | check(xm7::TV);
diff --git a/src/test/ui/never_type/exhaustive_patterns.rs b/src/test/ui/never_type/exhaustive_patterns.rs
new file mode 100644
index 000000000..2e23fa182
--- /dev/null
+++ b/src/test/ui/never_type/exhaustive_patterns.rs
@@ -0,0 +1,21 @@
+// check-fail
+// known-bug: #104034
+
+#![feature(exhaustive_patterns, never_type)]
+
+mod inner {
+ pub struct Wrapper<T>(T);
+}
+
+enum Either<A, B> {
+ A(A),
+ B(inner::Wrapper<B>),
+}
+
+fn foo() -> Either<(), !> {
+ Either::A(())
+}
+
+fn main() {
+ let Either::A(()) = foo();
+}
diff --git a/src/test/ui/never_type/exhaustive_patterns.stderr b/src/test/ui/never_type/exhaustive_patterns.stderr
new file mode 100644
index 000000000..e41baf862
--- /dev/null
+++ b/src/test/ui/never_type/exhaustive_patterns.stderr
@@ -0,0 +1,25 @@
+error[E0005]: refutable pattern in local binding: `Either::B(_)` not covered
+ --> $DIR/exhaustive_patterns.rs:20:9
+ |
+LL | let Either::A(()) = foo();
+ | ^^^^^^^^^^^^^ pattern `Either::B(_)` not covered
+ |
+ = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+ = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `Either<(), !>` defined here
+ --> $DIR/exhaustive_patterns.rs:12:5
+ |
+LL | enum Either<A, B> {
+ | ------
+LL | A(A),
+LL | B(inner::Wrapper<B>),
+ | ^ not covered
+ = note: the matched value is of type `Either<(), !>`
+help: you might want to use `if let` to ignore the variant that isn't matched
+ |
+LL | if let Either::A(()) = foo() { todo!() }
+ | ++ ~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0005`.
diff --git a/src/test/ui/never_type/issue-13352.stderr b/src/test/ui/never_type/issue-13352.stderr
index fed780e68..2d22da0b4 100644
--- a/src/test/ui/never_type/issue-13352.stderr
+++ b/src/test/ui/never_type/issue-13352.stderr
@@ -6,15 +6,10 @@ LL | 2_usize + (loop {});
|
= help: the trait `Add<()>` is not implemented for `usize`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&'a usize as Add<usize>>
+ <&usize as Add<&usize>>
+ <usize as Add<&usize>>
+ <usize as Add>
error: aborting due to previous error
diff --git a/src/test/ui/nll/borrowed-temporary-error.stderr b/src/test/ui/nll/borrowed-temporary-error.stderr
index 2c6bd9264..89781d96f 100644
--- a/src/test/ui/nll/borrowed-temporary-error.stderr
+++ b/src/test/ui/nll/borrowed-temporary-error.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/borrowed-temporary-error.rs:8:10
|
LL | &(v,)
- | ^^^^ creates a temporary which is freed while still in use
+ | ^^^^ creates a temporary value which is freed while still in use
LL |
LL | });
| - temporary value is freed at the end of this statement
diff --git a/src/test/ui/nll/closure-access-spans.stderr b/src/test/ui/nll/closure-access-spans.stderr
index e9d7ca953..0a09353b8 100644
--- a/src/test/ui/nll/closure-access-spans.stderr
+++ b/src/test/ui/nll/closure-access-spans.stderr
@@ -67,6 +67,11 @@ LL | || x.len();
| ^^ - borrow occurs due to use in closure
| |
| value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let r = x.clone();
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/closure-access-spans.rs:40:5
@@ -79,6 +84,11 @@ LL | || x = String::new();
| ^^ - borrow occurs due to use in closure
| |
| value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let r = x.clone();
+ | ++++++++
error[E0382]: borrow of moved value: `x`
--> $DIR/closure-access-spans.rs:45:5
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index d2d26b23d..363ddfaff 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -6,7 +6,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y);
|
= note: defining type: test::{closure#0} with closure substs [
i16,
- for<'a, 'b, 'c> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('c) }) i32)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None)), Region(BrAnon(2, None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(2, None) }) i32)),
(),
]
diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr
index 6355d3295..f67c312b9 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr
@@ -6,7 +6,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y);
|
= note: defining type: test::{closure#0} with closure substs [
i16,
- for<'a, 'b> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) i32)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) i32)),
(),
]
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index 5f9724ce3..7da6ce58b 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -6,7 +6,7 @@ LL | |_outlives1, _outlives2, _outlives3, x, y| {
|
= note: defining type: supply::{closure#0} with closure substs [
i16,
- for<'a, 'b> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None))> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>)),
(),
]
= note: late-bound region is '_#4r
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
index ec728ebd5..993687605 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -6,7 +6,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
|
= note: defining type: supply::{closure#0} with closure substs [
i16,
- for<'a, 'b, 'c, 'd, 'e, 'f> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('c) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('d) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('e) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrNamed('f) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('d) }) u32>)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None)), Region(BrAnon(2, None)), Region(BrAnon(3, None)), Region(BrAnon(4, None)), Region(BrAnon(5, None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(2, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(3, None) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(4, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(5, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(3, None) }) u32>)),
(),
]
= note: late-bound region is '_#3r
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index 012933797..7991abeb7 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -6,7 +6,7 @@ LL | foo(cell, |cell_a, cell_x| {
|
= note: defining type: case1::{closure#0} with closure substs [
i32,
- for<'a> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) u32>)),
+ for<Region(BrAnon(0, None))> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) u32>)),
(),
]
@@ -36,7 +36,7 @@ LL | foo(cell, |cell_a, cell_x| {
|
= note: defining type: case2::{closure#0} with closure substs [
i32,
- for<'a> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) u32>)),
+ for<Region(BrAnon(0, None))> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) u32>)),
(),
]
= note: number of external vids: 2
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index ce85b20b3..43dfc3bb9 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -6,7 +6,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
= note: defining type: supply::{closure#0} with closure substs [
i16,
- for<'a, 'b, 'c, 'd, 'e> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('c) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('d) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('e) }) u32>)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None)), Region(BrAnon(2, None)), Region(BrAnon(3, None)), Region(BrAnon(4, None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(2, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(3, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(4, None) }) u32>)),
(),
]
= note: late-bound region is '_#2r
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index 20c7967b7..96c734226 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -6,7 +6,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
|
= note: defining type: supply::{closure#0} with closure substs [
i16,
- for<'a, 'b, 'c, 'd, 'e, 'f> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('c) }) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('d) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('e) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrNamed('f) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('d) }) u32>)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None)), Region(BrAnon(2, None)), Region(BrAnon(3, None)), Region(BrAnon(4, None)), Region(BrAnon(5, None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(2, None) }) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(3, None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(4, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(5, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(3, None) }) u32>)),
(),
]
= note: late-bound region is '_#3r
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
index f7db5ab1f..03dbd686e 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -6,7 +6,7 @@ LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
|
= note: defining type: test::{closure#0} with closure substs [
i16,
- for<'a, 'b> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None))> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>)),
(),
]
= note: late-bound region is '_#3r
diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
index 3488edc75..d716d3de2 100644
--- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
@@ -6,7 +6,7 @@ LL | |_outlives1, _outlives2, x, y| {
|
= note: defining type: supply::{closure#0} with closure substs [
i16,
- for<'a, 'b> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None))> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>)),
(),
]
= note: late-bound region is '_#3r
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index 0dc2d0de9..b924873fc 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -6,7 +6,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
= note: defining type: supply::{closure#0} with closure substs [
i16,
- for<'a, 'b, 'c, 'd, 'e> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('c) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('d) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('e) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None)), Region(BrAnon(2, None)), Region(BrAnon(3, None)), Region(BrAnon(4, None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(2, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(3, None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(4, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>)),
(),
]
= note: late-bound region is '_#2r
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 4c9e026ea..9b25efd0b 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -6,7 +6,7 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
|
= note: defining type: supply::{closure#0} with closure substs [
i16,
- for<'a, 'b, 'c, 'd, 'e, 'f> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('c) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('d) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('e) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrNamed('f) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('d) }) u32>)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None)), Region(BrAnon(2, None)), Region(BrAnon(3, None)), Region(BrAnon(4, None)), Region(BrAnon(5, None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(2, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(3, None) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(4, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(5, None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(3, None) }) u32>)),
(),
]
= note: late-bound region is '_#3r
diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
index 3bdb54339..cda781d8e 100644
--- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
@@ -30,8 +30,6 @@ where
T: Trait<'a>,
{
establish_relationships(value, |value| {
- //~^ ERROR the parameter type `T` may not live long enough
-
// This function call requires that
//
// (a) T: Trait<'a>
@@ -43,6 +41,7 @@ where
// The latter does not hold.
require(value);
+ //~^ ERROR the parameter type `T` may not live long enough
});
}
diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
index 750b08bbe..038a5e11f 100644
--- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
@@ -23,17 +23,10 @@ LL | | T: Trait<'a>,
= note: defining type: supply::<'_#1r, T>
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/propagate-from-trait-match.rs:32:36
+ --> $DIR/propagate-from-trait-match.rs:43:9
|
-LL | establish_relationships(value, |value| {
- | ____________________________________^
-LL | |
-LL | |
-LL | | // This function call requires that
-... |
-LL | | require(value);
-LL | | });
- | |_____^ ...so that the type `T` will meet its required lifetime bounds
+LL | require(value);
+ | ^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index 68429142e..6db72b886 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -6,7 +6,7 @@ LL | expect_sig(|a, b| b); // ought to return `a`
|
= note: defining type: test::{closure#0} with closure substs [
i16,
- for<'a, 'b> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) i32)) -> &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) i32,
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) i32)) -> &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) i32,
(),
]
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr
index 947c9e29b..97ed414b1 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr
+++ b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr
@@ -37,6 +37,11 @@ LL | let mut t: T = (0, Box::new(0)); drop(t);
| move occurs because `t` has type `(u32, Box<u32>)`, which does not implement the `Copy` trait
LL | t.0 = 10; t.1 = Box::new(20);
| ^^^^^^^^ value partially assigned here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let mut t: T = (0, Box::new(0)); drop(t.clone());
+ | ++++++++
error[E0381]: partially assigned binding `s` isn't fully initialized
--> $DIR/issue-21232-partial-init-and-use.rs:123:5
@@ -77,6 +82,11 @@ LL | let mut t: T = (0, Box::new(0)); drop(t);
| move occurs because `t` has type `(u32, Box<u32>)`, which does not implement the `Copy` trait
LL | t.0 = 10;
| ^^^^^^^^ value partially assigned here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let mut t: T = (0, Box::new(0)); drop(t.clone());
+ | ++++++++
error[E0381]: partially assigned binding `s` isn't fully initialized
--> $DIR/issue-21232-partial-init-and-use.rs:149:5
@@ -208,6 +218,11 @@ LL | c2 => {
| -- value moved here
LL | c.0 = 2;
| ^^^^^^^ value partially assigned here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref c2 => {
+ | +++
error[E0382]: assign to part of moved value: `c`
--> $DIR/issue-21232-partial-init-and-use.rs:255:13
@@ -219,6 +234,11 @@ LL | c2 => {
| -- value moved here
LL | (c.1).0 = 2;
| ^^^^^^^^^^^ value partially assigned here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref c2 => {
+ | +++
error[E0382]: assign to part of moved value: `c.1`
--> $DIR/issue-21232-partial-init-and-use.rs:263:13
@@ -229,6 +249,10 @@ LL | ((c.1).1).0 = 3;
| ^^^^^^^^^^^^^^^ value partially assigned here after move
|
= note: move occurs because `c.1` has type `(i32, (i32, String))`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref c2 => {
+ | +++
error: aborting due to 23 previous errors
diff --git a/src/test/ui/nll/issue-48623-generator.stderr b/src/test/ui/nll/issue-48623-generator.stderr
index 1b35165db..bfdfca210 100644
--- a/src/test/ui/nll/issue-48623-generator.stderr
+++ b/src/test/ui/nll/issue-48623-generator.stderr
@@ -2,7 +2,7 @@ warning: unused generator that must be used
--> $DIR/issue-48623-generator.rs:15:5
|
LL | move || { d; yield; &mut *r };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: generators are lazy and do nothing unless resumed
= note: `#[warn(unused_must_use)]` on by default
diff --git a/src/test/ui/nll/issue-51512.stderr b/src/test/ui/nll/issue-51512.stderr
index e591ca082..072e96788 100644
--- a/src/test/ui/nll/issue-51512.stderr
+++ b/src/test/ui/nll/issue-51512.stderr
@@ -7,6 +7,11 @@ LL | let r = range;
| ----- value moved here
LL | let x = range.start;
| ^^^^^^^^^^^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let r = range.clone();
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/nll/issue-53807.stderr b/src/test/ui/nll/issue-53807.stderr
index 574a11434..d8f58b591 100644
--- a/src/test/ui/nll/issue-53807.stderr
+++ b/src/test/ui/nll/issue-53807.stderr
@@ -5,7 +5,7 @@ LL | if let Some(thing) = maybe {
| ^^^^^ value moved here, in previous iteration of loop
|
= note: move occurs because value has type `Vec<bool>`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `maybe.0`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | if let Some(ref thing) = maybe {
| +++
diff --git a/src/test/ui/issues/issue-54943.rs b/src/test/ui/nll/issue-54943.rs
index 85722300b..85722300b 100644
--- a/src/test/ui/issues/issue-54943.rs
+++ b/src/test/ui/nll/issue-54943.rs
diff --git a/src/test/ui/issues/issue-54943.stderr b/src/test/ui/nll/issue-54943.stderr
index 59be0f983..59be0f983 100644
--- a/src/test/ui/issues/issue-54943.stderr
+++ b/src/test/ui/nll/issue-54943.stderr
diff --git a/src/test/ui/nll/issue-57265-return-type-wf-check.stderr b/src/test/ui/nll/issue-57265-return-type-wf-check.stderr
index 20add62b9..bb45575fa 100644
--- a/src/test/ui/nll/issue-57265-return-type-wf-check.stderr
+++ b/src/test/ui/nll/issue-57265-return-type-wf-check.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let (_, z) = foo(&"hello".to_string());
| -----^^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement
| | |
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| argument requires that borrow lasts for `'static`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-57843.rs b/src/test/ui/nll/issue-57843.rs
index 11629690e..11629690e 100644
--- a/src/test/ui/issues/issue-57843.rs
+++ b/src/test/ui/nll/issue-57843.rs
diff --git a/src/test/ui/issues/issue-57843.stderr b/src/test/ui/nll/issue-57843.stderr
index 2ab49ec61..2ab49ec61 100644
--- a/src/test/ui/issues/issue-57843.stderr
+++ b/src/test/ui/nll/issue-57843.stderr
diff --git a/src/test/ui/nll/issue-98589-closures-relate-named-regions.stderr b/src/test/ui/nll/issue-98589-closures-relate-named-regions.stderr
index 6def5602e..d8b26f0b0 100644
--- a/src/test/ui/nll/issue-98589-closures-relate-named-regions.stderr
+++ b/src/test/ui/nll/issue-98589-closures-relate-named-regions.stderr
@@ -35,10 +35,10 @@ LL | || { None::<&'a &'b ()>; };
= help: consider adding the following bound: `'b: 'a`
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/issue-98589-closures-relate-named-regions.rs:26:5
+ --> $DIR/issue-98589-closures-relate-named-regions.rs:26:10
|
LL | || { None::<&'a T>; };
- | ^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ | ^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
@@ -46,10 +46,10 @@ LL | fn test_early_type<'a: 'a, T: 'a>() {
| ++++
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/issue-98589-closures-relate-named-regions.rs:32:5
+ --> $DIR/issue-98589-closures-relate-named-regions.rs:32:10
|
LL | || { None::<&'a T>; };
- | ^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ | ^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
diff --git a/src/test/ui/nll/issue-98693.rs b/src/test/ui/nll/issue-98693.rs
index 18e6ec630..7a325e2e9 100644
--- a/src/test/ui/nll/issue-98693.rs
+++ b/src/test/ui/nll/issue-98693.rs
@@ -13,8 +13,8 @@ where
fn test<T>() {
|| {
- //~^ ERROR the parameter type `T` may not live long enough
assert_static::<T>();
+ //~^ ERROR the parameter type `T` may not live long enough
};
}
diff --git a/src/test/ui/nll/issue-98693.stderr b/src/test/ui/nll/issue-98693.stderr
index 31689620c..15ca38aa2 100644
--- a/src/test/ui/nll/issue-98693.stderr
+++ b/src/test/ui/nll/issue-98693.stderr
@@ -1,11 +1,8 @@
error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/issue-98693.rs:15:5
+ --> $DIR/issue-98693.rs:16:9
|
-LL | / || {
-LL | |
-LL | | assert_static::<T>();
-LL | | };
- | |_____^ ...so that the type `T` will meet its required lifetime bounds
+LL | assert_static::<T>();
+ | ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr
index 2d48a9142..f72ed3af7 100644
--- a/src/test/ui/nll/match-cfg-fake-edges.stderr
+++ b/src/test/ui/nll/match-cfg-fake-edges.stderr
@@ -26,6 +26,11 @@ LL | false if { drop(x); true } => 1,
LL | true => {
LL | x;
| ^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | false if { drop(x.clone()); true } => 1,
+ | ++++++++
error: aborting due to 2 previous errors
diff --git a/src/test/ui/nll/ref-suggestion.stderr b/src/test/ui/nll/ref-suggestion.stderr
index a973c583a..b1f5117cb 100644
--- a/src/test/ui/nll/ref-suggestion.stderr
+++ b/src/test/ui/nll/ref-suggestion.stderr
@@ -7,6 +7,11 @@ LL | let y = x;
| - value moved here
LL | x;
| ^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let y = x.clone();
+ | ++++++++
error[E0382]: use of moved value: `x`
--> $DIR/ref-suggestion.rs:8:5
@@ -17,6 +22,11 @@ LL | let mut y = x;
| - value moved here
LL | x;
| ^ value used here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let mut y = x.clone();
+ | ++++++++
error[E0382]: use of partially moved value: `x`
--> $DIR/ref-suggestion.rs:16:5
@@ -28,7 +38,7 @@ LL | x;
| ^ value used here after partial move
|
= note: partial move occurs because value has type `Vec<i32>`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `x.0.0`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | (Some(ref y), ()) => {},
| +++
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
index 737cb3584..7b9ed171d 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
+++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
@@ -1,4 +1,4 @@
-error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[1afc]::foo::{opaque#0}), [ReStatic, T, ReEarlyBound(0, 'a)])` captures lifetime that does not appear in bounds
+error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[1afc]::foo::{opaque#0}), [ReEarlyBound(0, 'a), T, ReEarlyBound(0, 'a)])` captures lifetime that does not appear in bounds
--> $DIR/impl-trait-captures.rs:11:5
|
LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
index 3b9b2956c..d949e29b2 100644
--- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
@@ -1,8 +1,8 @@
error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/projection-implied-bounds.rs:30:18
+ --> $DIR/projection-implied-bounds.rs:30:36
|
LL | twice(value, |value_ref, item| invoke2(value_ref, item));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
index ee1f7b64b..4933b9348 100644
--- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
@@ -23,10 +23,10 @@ LL | | T: Iterator,
= note: defining type: no_region::<'_#1r, T>
error[E0309]: the associated type `<T as Iterator>::Item` may not live long enough
- --> $DIR/projection-no-regions-closure.rs:25:23
+ --> $DIR/projection-no-regions-closure.rs:25:31
|
LL | with_signature(x, |mut y| Box::new(y.next()))
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Iterator>::Item: 'a`...
= note: ...so that the type `<T as Iterator>::Item` will meet its required lifetime bounds
@@ -80,10 +80,10 @@ LL | | T: 'b + Iterator,
= note: defining type: wrong_region::<'_#1r, '_#2r, T>
error[E0309]: the associated type `<T as Iterator>::Item` may not live long enough
- --> $DIR/projection-no-regions-closure.rs:42:23
+ --> $DIR/projection-no-regions-closure.rs:42:31
|
LL | with_signature(x, |mut y| Box::new(y.next()))
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Iterator>::Item: 'a`...
= note: ...so that the type `<T as Iterator>::Item` will meet its required lifetime bounds
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
index 4e57dfad7..dbda04c42 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
@@ -25,10 +25,10 @@ LL | | T: Anything<'b>,
= note: defining type: no_relationships_late::<'_#1r, T>
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/projection-one-region-closure.rs:45:29
+ --> $DIR/projection-one-region-closure.rs:45:39
|
LL | with_signature(cell, t, |cell, t| require(cell, t));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
@@ -75,10 +75,10 @@ LL | | 'a: 'a,
= note: defining type: no_relationships_early::<'_#1r, '_#2r, T>
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/projection-one-region-closure.rs:56:29
+ --> $DIR/projection-one-region-closure.rs:56:39
|
LL | with_signature(cell, t, |cell, t| require(cell, t));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
index 0195a693e..90f049142 100644
--- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
@@ -24,10 +24,10 @@ LL | | T: Anything<'b, 'c>,
= note: defining type: no_relationships_late::<'_#1r, '_#2r, T>
error[E0309]: the associated type `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType` may not live long enough
- --> $DIR/projection-two-region-trait-bound-closure.rs:38:29
+ --> $DIR/projection-two-region-trait-bound-closure.rs:38:39
|
LL | with_signature(cell, t, |cell, t| require(cell, t));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType: 'a`...
= note: ...so that the type `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType` will meet its required lifetime bounds
@@ -58,10 +58,10 @@ LL | | 'a: 'a,
= note: defining type: no_relationships_early::<'_#1r, '_#2r, '_#3r, T>
error[E0309]: the associated type `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType` may not live long enough
- --> $DIR/projection-two-region-trait-bound-closure.rs:48:29
+ --> $DIR/projection-two-region-trait-bound-closure.rs:48:39
|
LL | with_signature(cell, t, |cell, t| require(cell, t));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: 'a`...
= note: ...so that the type `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType` will meet its required lifetime bounds
@@ -167,7 +167,7 @@ LL | | T: Anything<'b, 'b>,
= note: defining type: two_regions::<'_#1r, T>
error: lifetime may not live long enough
- --> $DIR/projection-two-region-trait-bound-closure.rs:87:29
+ --> $DIR/projection-two-region-trait-bound-closure.rs:87:5
|
LL | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| -- -- lifetime `'b` defined here
@@ -175,9 +175,12 @@ LL | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
| lifetime `'a` defined here
...
LL | with_signature(cell, t, |cell, t| require(cell, t));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ closure body requires that `'b` must outlive `'a`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
+ = note: requirement occurs because of the type `Cell<&'_#8r ()>`, which makes the generic argument `&'_#8r ()` invariant
+ = note: the struct `Cell<T>` is invariant over the parameter `T`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
note: external requirements
--> $DIR/projection-two-region-trait-bound-closure.rs:97:29
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index 61c7d2550..a442cf12d 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -6,7 +6,7 @@ LL | twice(cell, value, |a, b| invoke(a, b));
|
= note: defining type: generic::<T>::{closure#0} with closure substs [
i16,
- for<'a, 'b> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) T)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None))> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) T)),
(),
]
= note: number of external vids: 2
@@ -28,7 +28,7 @@ LL | twice(cell, value, |a, b| invoke(a, b));
|
= note: defining type: generic_fail::<T>::{closure#0} with closure substs [
i16,
- for<'a, 'b> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('a) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('b) }) T)),
+ for<Region(BrAnon(0, None)), Region(BrAnon(1, None))> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(0, None) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(1, None) }) T)),
(),
]
= note: late-bound region is '_#2r
@@ -44,10 +44,10 @@ LL | fn generic_fail<'a, T>(cell: Cell<&'a ()>, value: T) {
= note: defining type: generic_fail::<T>
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/ty-param-closure-approximate-lower-bound.rs:29:24
+ --> $DIR/ty-param-closure-approximate-lower-bound.rs:29:31
|
LL | twice(cell, value, |a, b| invoke(a, b));
- | ^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ | ^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
index 50d9e3aab..35979c8bf 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
@@ -23,10 +23,10 @@ LL | | T: Debug,
= note: defining type: no_region::<'_#1r, T>
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/ty-param-closure-outlives-from-return-type.rs:26:23
+ --> $DIR/ty-param-closure-outlives-from-return-type.rs:26:27
|
LL | with_signature(x, |y| y)
- | ^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ | ^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs
index d7702def3..b80287610 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs
@@ -25,13 +25,12 @@ where
#[rustc_regions]
fn no_region<'a, T>(a: Cell<&'a ()>, b: T) {
with_signature(a, b, |x, y| {
- //~^ ERROR the parameter type `T` may not live long enough
- //
// See `correct_region`, which explains the point of this
// test. The only difference is that, in the case of this
// function, there is no where clause *anywhere*, and hence we
// get an error (but reported by the closure creator).
require(&x, &y)
+ //~^ ERROR the parameter type `T` may not live long enough
})
}
@@ -62,9 +61,9 @@ where
T: 'b,
{
with_signature(a, b, |x, y| {
- //~^ ERROR the parameter type `T` may not live long enough
// See `correct_region`
require(&x, &y)
+ //~^ ERROR the parameter type `T` may not live long enough
})
}
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
index 14c55e32a..4c97db58c 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
@@ -22,17 +22,10 @@ LL | fn no_region<'a, T>(a: Cell<&'a ()>, b: T) {
= note: defining type: no_region::<T>
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/ty-param-closure-outlives-from-where-clause.rs:27:26
+ --> $DIR/ty-param-closure-outlives-from-where-clause.rs:32:9
|
-LL | with_signature(a, b, |x, y| {
- | __________________________^
-LL | |
-LL | | //
-LL | | // See `correct_region`, which explains the point of this
-... |
-LL | | require(&x, &y)
-LL | | })
- | |_____^ ...so that the type `T` will meet its required lifetime bounds
+LL | require(&x, &y)
+ | ^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
@@ -40,7 +33,7 @@ LL | fn no_region<'a, T: 'a>(a: Cell<&'a ()>, b: T) {
| ++++
note: external requirements
- --> $DIR/ty-param-closure-outlives-from-where-clause.rs:43:26
+ --> $DIR/ty-param-closure-outlives-from-where-clause.rs:42:26
|
LL | with_signature(a, b, |x, y| {
| ^^^^^^
@@ -54,7 +47,7 @@ LL | with_signature(a, b, |x, y| {
= note: where T: '_#2r
note: no external requirements
- --> $DIR/ty-param-closure-outlives-from-where-clause.rs:39:1
+ --> $DIR/ty-param-closure-outlives-from-where-clause.rs:38:1
|
LL | / fn correct_region<'a, T>(a: Cell<&'a ()>, b: T)
LL | | where
@@ -64,7 +57,7 @@ LL | | T: 'a,
= note: defining type: correct_region::<'_#1r, T>
note: external requirements
- --> $DIR/ty-param-closure-outlives-from-where-clause.rs:64:26
+ --> $DIR/ty-param-closure-outlives-from-where-clause.rs:63:26
|
LL | with_signature(a, b, |x, y| {
| ^^^^^^
@@ -79,7 +72,7 @@ LL | with_signature(a, b, |x, y| {
= note: where T: '_#2r
note: no external requirements
- --> $DIR/ty-param-closure-outlives-from-where-clause.rs:60:1
+ --> $DIR/ty-param-closure-outlives-from-where-clause.rs:59:1
|
LL | / fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
LL | | where
@@ -89,15 +82,10 @@ LL | | T: 'b,
= note: defining type: wrong_region::<'_#1r, T>
error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/ty-param-closure-outlives-from-where-clause.rs:64:26
+ --> $DIR/ty-param-closure-outlives-from-where-clause.rs:65:9
|
-LL | with_signature(a, b, |x, y| {
- | __________________________^
-LL | |
-LL | | // See `correct_region`
-LL | | require(&x, &y)
-LL | | })
- | |_____^ ...so that the type `T` will meet its required lifetime bounds
+LL | require(&x, &y)
+ | ^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
@@ -105,7 +93,7 @@ LL | T: 'b + 'a,
| ++++
note: external requirements
- --> $DIR/ty-param-closure-outlives-from-where-clause.rs:77:26
+ --> $DIR/ty-param-closure-outlives-from-where-clause.rs:76:26
|
LL | with_signature(a, b, |x, y| {
| ^^^^^^
@@ -119,7 +107,7 @@ LL | with_signature(a, b, |x, y| {
= note: where T: '_#3r
note: no external requirements
- --> $DIR/ty-param-closure-outlives-from-where-clause.rs:72:1
+ --> $DIR/ty-param-closure-outlives-from-where-clause.rs:71:1
|
LL | / fn outlives_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
LL | | where
diff --git a/src/test/ui/nll/user-annotations/ascribed-type-wf.rs b/src/test/ui/nll/user-annotations/ascribed-type-wf.rs
new file mode 100644
index 000000000..14460dea5
--- /dev/null
+++ b/src/test/ui/nll/user-annotations/ascribed-type-wf.rs
@@ -0,0 +1,16 @@
+// check-pass
+// known-bug: #101350
+
+trait Trait {
+ type Ty;
+}
+
+impl Trait for &'static () {
+ type Ty = ();
+}
+
+fn extend<'a>() {
+ None::<<&'a () as Trait>::Ty>;
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs b/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs
index 9b3ec702c..95c655654 100644
--- a/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs
+++ b/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs
@@ -8,17 +8,17 @@ type PairCoupledTypes<T> = (T, T);
type PairCoupledRegions<'a, T> = (&'a T, &'a T);
fn uncoupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
- let ((y, _z),) = ((s, _x),): (PairUncoupled<_>,);
+ let ((y, _z),) = type_ascribe!(((s, _x),), (PairUncoupled<_>,));
y // OK
}
fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
- let ((y, _z),) = ((s, _x),): (PairCoupledTypes<_>,);
+ let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledTypes<_>,));
y //~ ERROR lifetime may not live long enough
}
fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
- let ((y, _z),) = ((s, _x),): (PairCoupledRegions<_>,);
+ let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledRegions<_>,));
y //~ ERROR lifetime may not live long enough
}
diff --git a/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr b/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr
index c99f53c5a..8601691e8 100644
--- a/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr
+++ b/src/test/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.stderr
@@ -3,7 +3,7 @@ error: lifetime may not live long enough
|
LL | fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
| -- lifetime `'a` defined here
-LL | let ((y, _z),) = ((s, _x),): (PairCoupledTypes<_>,);
+LL | let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledTypes<_>,));
LL | y
| ^ returning this value requires that `'a` must outlive `'static`
@@ -12,7 +12,7 @@ error: lifetime may not live long enough
|
LL | fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
| -- lifetime `'a` defined here
-LL | let ((y, _z),) = ((s, _x),): (PairCoupledRegions<_>,);
+LL | let ((y, _z),) = type_ascribe!(((s, _x),), (PairCoupledRegions<_>,));
LL | y
| ^ returning this value requires that `'a` must outlive `'static`
diff --git a/src/test/ui/nll/user-annotations/patterns.stderr b/src/test/ui/nll/user-annotations/patterns.stderr
index 60d6e6db3..de6f8f80f 100644
--- a/src/test/ui/nll/user-annotations/patterns.stderr
+++ b/src/test/ui/nll/user-annotations/patterns.stderr
@@ -76,7 +76,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let _: Vec<&'static String> = vec![&String::new()];
| -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| | |
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| type annotation requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
@@ -85,7 +85,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let (_, a): (Vec<&'static String>, _) = (vec![&String::new()], 44);
| ------------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| | |
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| type annotation requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
@@ -94,7 +94,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44);
| ------------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| | |
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| type annotation requires that borrow lasts for `'static`
error[E0597]: `x` does not live long enough
diff --git a/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.rs b/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.rs
index 101b5cfab..88d646dee 100644
--- a/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.rs
+++ b/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.rs
@@ -3,5 +3,5 @@
fn main() {
let x = 22_u32;
- let y: &u32 = &x: &'static u32; //~ ERROR E0597
+ let y: &u32 = type_ascribe!(&x, &'static u32); //~ ERROR E0597
}
diff --git a/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.stderr b/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.stderr
index 133bbef52..ccbf3c1d9 100644
--- a/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.stderr
+++ b/src/test/ui/nll/user-annotations/type_ascription_static_lifetime.stderr
@@ -1,10 +1,10 @@
error[E0597]: `x` does not live long enough
- --> $DIR/type_ascription_static_lifetime.rs:6:19
+ --> $DIR/type_ascription_static_lifetime.rs:6:33
|
-LL | let y: &u32 = &x: &'static u32;
- | ^^--------------
- | |
- | borrowed value does not live long enough
+LL | let y: &u32 = type_ascribe!(&x, &'static u32);
+ | --------------^^---------------
+ | | |
+ | | borrowed value does not live long enough
| type annotation requires that `x` is borrowed for `'static`
LL | }
| - `x` dropped here while still borrowed
diff --git a/src/test/ui/numbers-arithmetic/not-suggest-float-literal.stderr b/src/test/ui/numbers-arithmetic/not-suggest-float-literal.stderr
index 6aa1ad8dd..8f0eef237 100644
--- a/src/test/ui/numbers-arithmetic/not-suggest-float-literal.stderr
+++ b/src/test/ui/numbers-arithmetic/not-suggest-float-literal.stderr
@@ -6,15 +6,10 @@ LL | x + 100.0
|
= help: the trait `Add<{float}>` is not implemented for `u8`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&'a u8 as Add<u8>>
+ <&u8 as Add<&u8>>
+ <u8 as Add<&u8>>
+ <u8 as Add>
error[E0277]: cannot add `&str` to `f64`
--> $DIR/not-suggest-float-literal.rs:6:7
@@ -24,15 +19,10 @@ LL | x + "foo"
|
= help: the trait `Add<&str>` is not implemented for `f64`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
<&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&f64 as Add<&f64>>
+ <f64 as Add<&f64>>
+ <f64 as Add>
error[E0277]: cannot add `{integer}` to `f64`
--> $DIR/not-suggest-float-literal.rs:11:7
@@ -42,15 +32,10 @@ LL | x + y
|
= help: the trait `Add<{integer}>` is not implemented for `f64`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
<&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&f64 as Add<&f64>>
+ <f64 as Add<&f64>>
+ <f64 as Add>
error[E0277]: cannot subtract `{float}` from `u8`
--> $DIR/not-suggest-float-literal.rs:15:7
@@ -60,15 +45,10 @@ LL | x - 100.0
|
= help: the trait `Sub<{float}>` is not implemented for `u8`
= help: the following other types implement trait `Sub<Rhs>`:
- <&'a f32 as Sub<f32>>
- <&'a f64 as Sub<f64>>
- <&'a i128 as Sub<i128>>
- <&'a i16 as Sub<i16>>
- <&'a i32 as Sub<i32>>
- <&'a i64 as Sub<i64>>
- <&'a i8 as Sub<i8>>
- <&'a isize as Sub<isize>>
- and 48 others
+ <&'a u8 as Sub<u8>>
+ <&u8 as Sub<&u8>>
+ <u8 as Sub<&u8>>
+ <u8 as Sub>
error[E0277]: cannot subtract `&str` from `f64`
--> $DIR/not-suggest-float-literal.rs:19:7
@@ -78,15 +58,10 @@ LL | x - "foo"
|
= help: the trait `Sub<&str>` is not implemented for `f64`
= help: the following other types implement trait `Sub<Rhs>`:
- <&'a f32 as Sub<f32>>
<&'a f64 as Sub<f64>>
- <&'a i128 as Sub<i128>>
- <&'a i16 as Sub<i16>>
- <&'a i32 as Sub<i32>>
- <&'a i64 as Sub<i64>>
- <&'a i8 as Sub<i8>>
- <&'a isize as Sub<isize>>
- and 48 others
+ <&f64 as Sub<&f64>>
+ <f64 as Sub<&f64>>
+ <f64 as Sub>
error[E0277]: cannot subtract `{integer}` from `f64`
--> $DIR/not-suggest-float-literal.rs:24:7
@@ -96,15 +71,10 @@ LL | x - y
|
= help: the trait `Sub<{integer}>` is not implemented for `f64`
= help: the following other types implement trait `Sub<Rhs>`:
- <&'a f32 as Sub<f32>>
<&'a f64 as Sub<f64>>
- <&'a i128 as Sub<i128>>
- <&'a i16 as Sub<i16>>
- <&'a i32 as Sub<i32>>
- <&'a i64 as Sub<i64>>
- <&'a i8 as Sub<i8>>
- <&'a isize as Sub<isize>>
- and 48 others
+ <&f64 as Sub<&f64>>
+ <f64 as Sub<&f64>>
+ <f64 as Sub>
error[E0277]: cannot multiply `u8` by `{float}`
--> $DIR/not-suggest-float-literal.rs:28:7
@@ -114,15 +84,10 @@ LL | x * 100.0
|
= help: the trait `Mul<{float}>` is not implemented for `u8`
= help: the following other types implement trait `Mul<Rhs>`:
- <&'a f32 as Mul<f32>>
- <&'a f64 as Mul<f64>>
- <&'a i128 as Mul<i128>>
- <&'a i16 as Mul<i16>>
- <&'a i32 as Mul<i32>>
- <&'a i64 as Mul<i64>>
- <&'a i8 as Mul<i8>>
- <&'a isize as Mul<isize>>
- and 49 others
+ <&'a u8 as Mul<u8>>
+ <&u8 as Mul<&u8>>
+ <u8 as Mul<&u8>>
+ <u8 as Mul>
error[E0277]: cannot multiply `f64` by `&str`
--> $DIR/not-suggest-float-literal.rs:32:7
@@ -132,15 +97,10 @@ LL | x * "foo"
|
= help: the trait `Mul<&str>` is not implemented for `f64`
= help: the following other types implement trait `Mul<Rhs>`:
- <&'a f32 as Mul<f32>>
<&'a f64 as Mul<f64>>
- <&'a i128 as Mul<i128>>
- <&'a i16 as Mul<i16>>
- <&'a i32 as Mul<i32>>
- <&'a i64 as Mul<i64>>
- <&'a i8 as Mul<i8>>
- <&'a isize as Mul<isize>>
- and 49 others
+ <&f64 as Mul<&f64>>
+ <f64 as Mul<&f64>>
+ <f64 as Mul>
error[E0277]: cannot multiply `f64` by `{integer}`
--> $DIR/not-suggest-float-literal.rs:37:7
@@ -150,15 +110,10 @@ LL | x * y
|
= help: the trait `Mul<{integer}>` is not implemented for `f64`
= help: the following other types implement trait `Mul<Rhs>`:
- <&'a f32 as Mul<f32>>
<&'a f64 as Mul<f64>>
- <&'a i128 as Mul<i128>>
- <&'a i16 as Mul<i16>>
- <&'a i32 as Mul<i32>>
- <&'a i64 as Mul<i64>>
- <&'a i8 as Mul<i8>>
- <&'a isize as Mul<isize>>
- and 49 others
+ <&f64 as Mul<&f64>>
+ <f64 as Mul<&f64>>
+ <f64 as Mul>
error[E0277]: cannot divide `u8` by `{float}`
--> $DIR/not-suggest-float-literal.rs:41:7
@@ -168,15 +123,11 @@ LL | x / 100.0
|
= help: the trait `Div<{float}>` is not implemented for `u8`
= help: the following other types implement trait `Div<Rhs>`:
- <&'a f32 as Div<f32>>
- <&'a f64 as Div<f64>>
- <&'a i128 as Div<i128>>
- <&'a i16 as Div<i16>>
- <&'a i32 as Div<i32>>
- <&'a i64 as Div<i64>>
- <&'a i8 as Div<i8>>
- <&'a isize as Div<isize>>
- and 54 others
+ <&'a u8 as Div<u8>>
+ <&u8 as Div<&u8>>
+ <u8 as Div<&u8>>
+ <u8 as Div<NonZeroU8>>
+ <u8 as Div>
error[E0277]: cannot divide `f64` by `&str`
--> $DIR/not-suggest-float-literal.rs:45:7
@@ -186,15 +137,10 @@ LL | x / "foo"
|
= help: the trait `Div<&str>` is not implemented for `f64`
= help: the following other types implement trait `Div<Rhs>`:
- <&'a f32 as Div<f32>>
<&'a f64 as Div<f64>>
- <&'a i128 as Div<i128>>
- <&'a i16 as Div<i16>>
- <&'a i32 as Div<i32>>
- <&'a i64 as Div<i64>>
- <&'a i8 as Div<i8>>
- <&'a isize as Div<isize>>
- and 54 others
+ <&f64 as Div<&f64>>
+ <f64 as Div<&f64>>
+ <f64 as Div>
error[E0277]: cannot divide `f64` by `{integer}`
--> $DIR/not-suggest-float-literal.rs:50:7
@@ -204,15 +150,10 @@ LL | x / y
|
= help: the trait `Div<{integer}>` is not implemented for `f64`
= help: the following other types implement trait `Div<Rhs>`:
- <&'a f32 as Div<f32>>
<&'a f64 as Div<f64>>
- <&'a i128 as Div<i128>>
- <&'a i16 as Div<i16>>
- <&'a i32 as Div<i32>>
- <&'a i64 as Div<i64>>
- <&'a i8 as Div<i8>>
- <&'a isize as Div<isize>>
- and 54 others
+ <&f64 as Div<&f64>>
+ <f64 as Div<&f64>>
+ <f64 as Div>
error: aborting due to 12 previous errors
diff --git a/src/test/ui/numbers-arithmetic/suggest-float-literal.stderr b/src/test/ui/numbers-arithmetic/suggest-float-literal.stderr
index 988379e58..03779d356 100644
--- a/src/test/ui/numbers-arithmetic/suggest-float-literal.stderr
+++ b/src/test/ui/numbers-arithmetic/suggest-float-literal.stderr
@@ -7,14 +7,9 @@ LL | x + 100
= help: the trait `Add<{integer}>` is not implemented for `f32`
= help: the following other types implement trait `Add<Rhs>`:
<&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&f32 as Add<&f32>>
+ <f32 as Add<&f32>>
+ <f32 as Add>
help: consider using a floating-point literal by writing it with `.0`
|
LL | x + 100.0
@@ -28,15 +23,10 @@ LL | x + 100
|
= help: the trait `Add<{integer}>` is not implemented for `f64`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
<&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&f64 as Add<&f64>>
+ <f64 as Add<&f64>>
+ <f64 as Add>
help: consider using a floating-point literal by writing it with `.0`
|
LL | x + 100.0
@@ -51,14 +41,9 @@ LL | x - 100
= help: the trait `Sub<{integer}>` is not implemented for `f32`
= help: the following other types implement trait `Sub<Rhs>`:
<&'a f32 as Sub<f32>>
- <&'a f64 as Sub<f64>>
- <&'a i128 as Sub<i128>>
- <&'a i16 as Sub<i16>>
- <&'a i32 as Sub<i32>>
- <&'a i64 as Sub<i64>>
- <&'a i8 as Sub<i8>>
- <&'a isize as Sub<isize>>
- and 48 others
+ <&f32 as Sub<&f32>>
+ <f32 as Sub<&f32>>
+ <f32 as Sub>
help: consider using a floating-point literal by writing it with `.0`
|
LL | x - 100.0
@@ -72,15 +57,10 @@ LL | x - 100
|
= help: the trait `Sub<{integer}>` is not implemented for `f64`
= help: the following other types implement trait `Sub<Rhs>`:
- <&'a f32 as Sub<f32>>
<&'a f64 as Sub<f64>>
- <&'a i128 as Sub<i128>>
- <&'a i16 as Sub<i16>>
- <&'a i32 as Sub<i32>>
- <&'a i64 as Sub<i64>>
- <&'a i8 as Sub<i8>>
- <&'a isize as Sub<isize>>
- and 48 others
+ <&f64 as Sub<&f64>>
+ <f64 as Sub<&f64>>
+ <f64 as Sub>
help: consider using a floating-point literal by writing it with `.0`
|
LL | x - 100.0
@@ -95,14 +75,9 @@ LL | x * 100
= help: the trait `Mul<{integer}>` is not implemented for `f32`
= help: the following other types implement trait `Mul<Rhs>`:
<&'a f32 as Mul<f32>>
- <&'a f64 as Mul<f64>>
- <&'a i128 as Mul<i128>>
- <&'a i16 as Mul<i16>>
- <&'a i32 as Mul<i32>>
- <&'a i64 as Mul<i64>>
- <&'a i8 as Mul<i8>>
- <&'a isize as Mul<isize>>
- and 49 others
+ <&f32 as Mul<&f32>>
+ <f32 as Mul<&f32>>
+ <f32 as Mul>
help: consider using a floating-point literal by writing it with `.0`
|
LL | x * 100.0
@@ -116,15 +91,10 @@ LL | x * 100
|
= help: the trait `Mul<{integer}>` is not implemented for `f64`
= help: the following other types implement trait `Mul<Rhs>`:
- <&'a f32 as Mul<f32>>
<&'a f64 as Mul<f64>>
- <&'a i128 as Mul<i128>>
- <&'a i16 as Mul<i16>>
- <&'a i32 as Mul<i32>>
- <&'a i64 as Mul<i64>>
- <&'a i8 as Mul<i8>>
- <&'a isize as Mul<isize>>
- and 49 others
+ <&f64 as Mul<&f64>>
+ <f64 as Mul<&f64>>
+ <f64 as Mul>
help: consider using a floating-point literal by writing it with `.0`
|
LL | x * 100.0
@@ -139,14 +109,9 @@ LL | x / 100
= help: the trait `Div<{integer}>` is not implemented for `f32`
= help: the following other types implement trait `Div<Rhs>`:
<&'a f32 as Div<f32>>
- <&'a f64 as Div<f64>>
- <&'a i128 as Div<i128>>
- <&'a i16 as Div<i16>>
- <&'a i32 as Div<i32>>
- <&'a i64 as Div<i64>>
- <&'a i8 as Div<i8>>
- <&'a isize as Div<isize>>
- and 54 others
+ <&f32 as Div<&f32>>
+ <f32 as Div<&f32>>
+ <f32 as Div>
help: consider using a floating-point literal by writing it with `.0`
|
LL | x / 100.0
@@ -160,15 +125,10 @@ LL | x / 100
|
= help: the trait `Div<{integer}>` is not implemented for `f64`
= help: the following other types implement trait `Div<Rhs>`:
- <&'a f32 as Div<f32>>
<&'a f64 as Div<f64>>
- <&'a i128 as Div<i128>>
- <&'a i16 as Div<i16>>
- <&'a i32 as Div<i32>>
- <&'a i64 as Div<i64>>
- <&'a i8 as Div<i8>>
- <&'a isize as Div<isize>>
- and 54 others
+ <&f64 as Div<&f64>>
+ <f64 as Div<&f64>>
+ <f64 as Div>
help: consider using a floating-point literal by writing it with `.0`
|
LL | x / 100.0
diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr
index c1aaad31e..f05b0cd65 100644
--- a/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr
+++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr
@@ -3,10 +3,10 @@ error[E0311]: the parameter type `Self` may not live long enough
= help: consider adding an explicit lifetime bound `Self: 'a`...
= note: ...so that the type `Self` will meet its required lifetime bounds...
note: ...that is required by this bound
- --> $DIR/object-safety-supertrait-mentions-GAT.rs:9:39
+ --> $DIR/object-safety-supertrait-mentions-GAT.rs:6:15
|
-LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> {
- | ^^^^^^^^^^^
+LL | Self: 'a;
+ | ^^
error: associated item referring to unboxed trait object for its own trait
--> $DIR/object-safety-supertrait-mentions-GAT.rs:10:20
diff --git a/src/test/ui/on-unimplemented/issue-104140.rs b/src/test/ui/on-unimplemented/issue-104140.rs
new file mode 100644
index 000000000..ade3f7270
--- /dev/null
+++ b/src/test/ui/on-unimplemented/issue-104140.rs
@@ -0,0 +1,8 @@
+#![feature(rustc_attrs)]
+
+trait Foo {}
+
+#[rustc_on_unimplemented] //~ ERROR malformed `rustc_on_unimplemented` attribute input
+impl Foo for u32 {}
+
+fn main() {}
diff --git a/src/test/ui/on-unimplemented/issue-104140.stderr b/src/test/ui/on-unimplemented/issue-104140.stderr
new file mode 100644
index 000000000..ddb1f50f0
--- /dev/null
+++ b/src/test/ui/on-unimplemented/issue-104140.stderr
@@ -0,0 +1,15 @@
+error: malformed `rustc_on_unimplemented` attribute input
+ --> $DIR/issue-104140.rs:5:1
+ |
+LL | #[rustc_on_unimplemented]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: the following are the possible correct uses
+ |
+LL | #[rustc_on_unimplemented = "message"]
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")]
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr
index 001c68a97..acc2099bb 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail-2018.stderr
@@ -6,6 +6,12 @@ LL | macro_rules! accept_pat {
...
LL | accept_pat!(p | q);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$p:pat`
+ --> $DIR/or-patterns-syntactic-fail-2018.rs:9:6
+ |
+LL | ($p:pat) => {};
+ | ^^^^^^
error: no rules expected the token `|`
--> $DIR/or-patterns-syntactic-fail-2018.rs:13:13
@@ -15,6 +21,12 @@ LL | macro_rules! accept_pat {
...
LL | accept_pat!(|p| q);
| ^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$p:pat`
+ --> $DIR/or-patterns-syntactic-fail-2018.rs:9:6
+ |
+LL | ($p:pat) => {};
+ | ^^^^^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
index dda5c0bb5..92750bec8 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
@@ -21,27 +21,27 @@ accept_pat!([p | q]);
#[cfg(FALSE)]
fn or_patterns() {
// Top level of `let`:
- let (A | B);
+ let (| A | B);
let (A | B);
let (A | B): u8;
let (A | B) = 0;
let (A | B): u8 = 0;
// Top level of `for`:
- for A | B in 0 {}
+ for | A | B in 0 {}
for A | B in 0 {}
// Top level of `while`:
- while let A | B = 0 {}
+ while let | A | B = 0 {}
while let A | B = 0 {}
// Top level of `if`:
- if let A | B = 0 {}
+ if let | A | B = 0 {}
if let A | B = 0 {}
// Top level of `match` arms:
match 0 {
- A | B => {}
+ | A | B => {}
A | B => {}
}
diff --git a/src/test/ui/overloaded/overloaded-calls-nontuple.rs b/src/test/ui/overloaded/overloaded-calls-nontuple.rs
index 07d44ff82..32a3b93e0 100644
--- a/src/test/ui/overloaded/overloaded-calls-nontuple.rs
+++ b/src/test/ui/overloaded/overloaded-calls-nontuple.rs
@@ -8,22 +8,23 @@ struct S {
}
impl FnMut<isize> for S {
+ //~^ ERROR type parameter to bare `FnMut` trait must be a tuple
extern "rust-call" fn call_mut(&mut self, z: isize) -> isize {
+ //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
self.x + self.y + z
}
- //~^^^ ERROR functions with the "rust-call" ABI must take a single non-self argument
}
impl FnOnce<isize> for S {
+ //~^ ERROR type parameter to bare `FnOnce` trait must be a tuple
type Output = isize;
- extern "rust-call" fn call_once(mut self, z: isize) -> isize { self.call_mut(z) }
- //~^ ERROR functions with the "rust-call" ABI must take a single non-self argument
+ extern "rust-call" fn call_once(mut self, z: isize) -> isize {
+ //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
+ self.call_mut(z)
+ }
}
fn main() {
- let mut s = S {
- x: 1,
- y: 2,
- };
- drop(s(3)) //~ ERROR cannot use call notation
+ let mut s = S { x: 1, y: 2 };
+ drop(s(3))
}
diff --git a/src/test/ui/overloaded/overloaded-calls-nontuple.stderr b/src/test/ui/overloaded/overloaded-calls-nontuple.stderr
index 8f299bc94..794535aeb 100644
--- a/src/test/ui/overloaded/overloaded-calls-nontuple.stderr
+++ b/src/test/ui/overloaded/overloaded-calls-nontuple.stderr
@@ -1,21 +1,40 @@
-error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple
- --> $DIR/overloaded-calls-nontuple.rs:11:5
+error[E0059]: type parameter to bare `FnMut` trait must be a tuple
+ --> $DIR/overloaded-calls-nontuple.rs:10:6
|
-LL | extern "rust-call" fn call_mut(&mut self, z: isize) -> isize {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl FnMut<isize> for S {
+ | ^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize`
+ |
+note: required by a bound in `FnMut`
+ --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+ |
+LL | pub trait FnMut<Args: Tuple>: FnOnce<Args> {
+ | ^^^^^ required by this bound in `FnMut`
+
+error[E0059]: type parameter to bare `FnOnce` trait must be a tuple
+ --> $DIR/overloaded-calls-nontuple.rs:18:6
+ |
+LL | impl FnOnce<isize> for S {
+ | ^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize`
+ |
+note: required by a bound in `FnOnce`
+ --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+ |
+LL | pub trait FnOnce<Args: Tuple> {
+ | ^^^^^ required by this bound in `FnOnce`
-error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple
- --> $DIR/overloaded-calls-nontuple.rs:19:5
+error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
+ --> $DIR/overloaded-calls-nontuple.rs:12:5
|
-LL | extern "rust-call" fn call_once(mut self, z: isize) -> isize { self.call_mut(z) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | extern "rust-call" fn call_mut(&mut self, z: isize) -> isize {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize`
-error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit
- --> $DIR/overloaded-calls-nontuple.rs:28:10
+error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
+ --> $DIR/overloaded-calls-nontuple.rs:21:5
|
-LL | drop(s(3))
- | ^^^^
+LL | extern "rust-call" fn call_once(mut self, z: isize) -> isize {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize`
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
-For more information about this error, try `rustc --explain E0059`.
+Some errors have detailed explanations: E0059, E0277.
+For more information about an error, try `rustc --explain E0059`.
diff --git a/src/test/ui/panic-handler/panic-handler-std.stderr b/src/test/ui/panic-handler/panic-handler-std.stderr
index e4069b196..7c7feffe7 100644
--- a/src/test/ui/panic-handler/panic-handler-std.stderr
+++ b/src/test/ui/panic-handler/panic-handler-std.stderr
@@ -8,12 +8,6 @@ LL | fn panic(info: PanicInfo) -> ! {
= note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
= note: second definition in the local crate (`panic_handler_std`)
-error: argument should be `&PanicInfo`
- --> $DIR/panic-handler-std.rs:8:16
- |
-LL | fn panic(info: PanicInfo) -> ! {
- | ^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0152`.
diff --git a/src/test/ui/parser/bad-lit-suffixes.rs b/src/test/ui/parser/bad-lit-suffixes.rs
index 9724533c4..8cb9ef7e0 100644
--- a/src/test/ui/parser/bad-lit-suffixes.rs
+++ b/src/test/ui/parser/bad-lit-suffixes.rs
@@ -1,3 +1,5 @@
+#![feature(rustc_attrs)]
+
extern
"C"suffix //~ ERROR suffixes on string literals are invalid
fn foo() {}
@@ -24,3 +26,19 @@ fn main() {
1.0suffix; //~ ERROR invalid suffix `suffix` for float literal
1.0e10suffix; //~ ERROR invalid suffix `suffix` for float literal
}
+
+#[rustc_dummy = "string"suffix]
+//~^ ERROR unexpected expression: `"string"suffix`
+fn f() {}
+
+#[must_use = "string"suffix]
+//~^ ERROR unexpected expression: `"string"suffix`
+fn g() {}
+
+#[link(name = "string"suffix)]
+//~^ ERROR suffixes on string literals are invalid
+extern "C" {}
+
+#[rustc_layout_scalar_valid_range_start(0suffix)]
+//~^ ERROR invalid suffix `suffix` for number literal
+struct S;
diff --git a/src/test/ui/parser/bad-lit-suffixes.stderr b/src/test/ui/parser/bad-lit-suffixes.stderr
index f74eef324..756f99ab1 100644
--- a/src/test/ui/parser/bad-lit-suffixes.stderr
+++ b/src/test/ui/parser/bad-lit-suffixes.stderr
@@ -1,53 +1,79 @@
error: suffixes on string literals are invalid
- --> $DIR/bad-lit-suffixes.rs:2:5
+ --> $DIR/bad-lit-suffixes.rs:4:5
|
LL | "C"suffix
| ^^^^^^^^^ invalid suffix `suffix`
error: suffixes on string literals are invalid
- --> $DIR/bad-lit-suffixes.rs:6:5
+ --> $DIR/bad-lit-suffixes.rs:8:5
|
LL | "C"suffix
| ^^^^^^^^^ invalid suffix `suffix`
+error: unexpected expression: `"string"suffix`
+ --> $DIR/bad-lit-suffixes.rs:30:17
+ |
+LL | #[rustc_dummy = "string"suffix]
+ | ^^^^^^^^^^^^^^
+
+error: unexpected expression: `"string"suffix`
+ --> $DIR/bad-lit-suffixes.rs:34:14
+ |
+LL | #[must_use = "string"suffix]
+ | ^^^^^^^^^^^^^^
+
+error: suffixes on string literals are invalid
+ --> $DIR/bad-lit-suffixes.rs:38:15
+ |
+LL | #[link(name = "string"suffix)]
+ | ^^^^^^^^^^^^^^ invalid suffix `suffix`
+
+error: invalid suffix `suffix` for number literal
+ --> $DIR/bad-lit-suffixes.rs:42:41
+ |
+LL | #[rustc_layout_scalar_valid_range_start(0suffix)]
+ | ^^^^^^^ invalid suffix `suffix`
+ |
+ = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
+
error: suffixes on string literals are invalid
- --> $DIR/bad-lit-suffixes.rs:10:5
+ --> $DIR/bad-lit-suffixes.rs:12:5
|
LL | ""suffix;
| ^^^^^^^^ invalid suffix `suffix`
error: suffixes on byte string literals are invalid
- --> $DIR/bad-lit-suffixes.rs:11:5
+ --> $DIR/bad-lit-suffixes.rs:13:5
|
LL | b""suffix;
| ^^^^^^^^^ invalid suffix `suffix`
error: suffixes on string literals are invalid
- --> $DIR/bad-lit-suffixes.rs:12:5
+ --> $DIR/bad-lit-suffixes.rs:14:5
|
LL | r#""#suffix;
| ^^^^^^^^^^^ invalid suffix `suffix`
error: suffixes on byte string literals are invalid
- --> $DIR/bad-lit-suffixes.rs:13:5
+ --> $DIR/bad-lit-suffixes.rs:15:5
|
LL | br#""#suffix;
| ^^^^^^^^^^^^ invalid suffix `suffix`
error: suffixes on char literals are invalid
- --> $DIR/bad-lit-suffixes.rs:14:5
+ --> $DIR/bad-lit-suffixes.rs:16:5
|
LL | 'a'suffix;
| ^^^^^^^^^ invalid suffix `suffix`
error: suffixes on byte literals are invalid
- --> $DIR/bad-lit-suffixes.rs:15:5
+ --> $DIR/bad-lit-suffixes.rs:17:5
|
LL | b'a'suffix;
| ^^^^^^^^^^ invalid suffix `suffix`
error: invalid width `1024` for integer literal
- --> $DIR/bad-lit-suffixes.rs:17:5
+ --> $DIR/bad-lit-suffixes.rs:19:5
|
LL | 1234u1024;
| ^^^^^^^^^
@@ -55,7 +81,7 @@ LL | 1234u1024;
= help: valid widths are 8, 16, 32, 64 and 128
error: invalid width `1024` for integer literal
- --> $DIR/bad-lit-suffixes.rs:18:5
+ --> $DIR/bad-lit-suffixes.rs:20:5
|
LL | 1234i1024;
| ^^^^^^^^^
@@ -63,7 +89,7 @@ LL | 1234i1024;
= help: valid widths are 8, 16, 32, 64 and 128
error: invalid width `1024` for float literal
- --> $DIR/bad-lit-suffixes.rs:19:5
+ --> $DIR/bad-lit-suffixes.rs:21:5
|
LL | 1234f1024;
| ^^^^^^^^^
@@ -71,7 +97,7 @@ LL | 1234f1024;
= help: valid widths are 32 and 64
error: invalid width `1024` for float literal
- --> $DIR/bad-lit-suffixes.rs:20:5
+ --> $DIR/bad-lit-suffixes.rs:22:5
|
LL | 1234.5f1024;
| ^^^^^^^^^^^
@@ -79,7 +105,7 @@ LL | 1234.5f1024;
= help: valid widths are 32 and 64
error: invalid suffix `suffix` for number literal
- --> $DIR/bad-lit-suffixes.rs:22:5
+ --> $DIR/bad-lit-suffixes.rs:24:5
|
LL | 1234suffix;
| ^^^^^^^^^^ invalid suffix `suffix`
@@ -87,7 +113,7 @@ LL | 1234suffix;
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
error: invalid suffix `suffix` for number literal
- --> $DIR/bad-lit-suffixes.rs:23:5
+ --> $DIR/bad-lit-suffixes.rs:25:5
|
LL | 0b101suffix;
| ^^^^^^^^^^^ invalid suffix `suffix`
@@ -95,7 +121,7 @@ LL | 0b101suffix;
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
error: invalid suffix `suffix` for float literal
- --> $DIR/bad-lit-suffixes.rs:24:5
+ --> $DIR/bad-lit-suffixes.rs:26:5
|
LL | 1.0suffix;
| ^^^^^^^^^ invalid suffix `suffix`
@@ -103,12 +129,12 @@ LL | 1.0suffix;
= help: valid suffixes are `f32` and `f64`
error: invalid suffix `suffix` for float literal
- --> $DIR/bad-lit-suffixes.rs:25:5
+ --> $DIR/bad-lit-suffixes.rs:27:5
|
LL | 1.0e10suffix;
| ^^^^^^^^^^^^ invalid suffix `suffix`
|
= help: valid suffixes are `f32` and `f64`
-error: aborting due to 16 previous errors
+error: aborting due to 20 previous errors
diff --git a/src/test/ui/parser/byte-literals.rs b/src/test/ui/parser/byte-literals.rs
index 05a510b24..896dc1a1a 100644
--- a/src/test/ui/parser/byte-literals.rs
+++ b/src/test/ui/parser/byte-literals.rs
@@ -7,6 +7,6 @@ pub fn main() {
b'\x0Z'; //~ ERROR invalid character in numeric character escape: `Z`
b' '; //~ ERROR byte constant must be escaped
b'''; //~ ERROR byte constant must be escaped
- b'é'; //~ ERROR non-ASCII character in byte constant
+ b'é'; //~ ERROR non-ASCII character in byte literal
b'a //~ ERROR unterminated byte constant [E0763]
}
diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr
index c3d000616..efa55ae05 100644
--- a/src/test/ui/parser/byte-literals.stderr
+++ b/src/test/ui/parser/byte-literals.stderr
@@ -32,11 +32,11 @@ error: byte constant must be escaped: `'`
LL | b''';
| ^ help: escape the character: `\'`
-error: non-ASCII character in byte constant
+error: non-ASCII character in byte literal
--> $DIR/byte-literals.rs:10:7
|
LL | b'é';
- | ^ byte constant must be ASCII
+ | ^ must be ASCII
|
help: if you meant to use the unicode code point for 'é', use a \xHH escape
|
diff --git a/src/test/ui/parser/byte-string-literals.rs b/src/test/ui/parser/byte-string-literals.rs
index b1f11024a..30a4f50c4 100644
--- a/src/test/ui/parser/byte-string-literals.rs
+++ b/src/test/ui/parser/byte-string-literals.rs
@@ -3,7 +3,7 @@ static FOO: &'static [u8] = b"\f"; //~ ERROR unknown byte escape
pub fn main() {
b"\f"; //~ ERROR unknown byte escape
b"\x0Z"; //~ ERROR invalid character in numeric character escape: `Z`
- b"é"; //~ ERROR non-ASCII character in byte constant
- br##"é"##; //~ ERROR raw byte string must be ASCII
+ b"é"; //~ ERROR non-ASCII character in byte string literal
+ br##"é"##; //~ ERROR non-ASCII character in raw byte string literal
b"a //~ ERROR unterminated double quote byte string
}
diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr
index 3b8b3692e..5b96cc3d1 100644
--- a/src/test/ui/parser/byte-string-literals.stderr
+++ b/src/test/ui/parser/byte-string-literals.stderr
@@ -20,18 +20,18 @@ error: invalid character in numeric character escape: `Z`
LL | b"\x0Z";
| ^ invalid character in numeric character escape
-error: non-ASCII character in byte constant
+error: non-ASCII character in byte string literal
--> $DIR/byte-string-literals.rs:6:7
|
LL | b"é";
- | ^ byte constant must be ASCII
+ | ^ must be ASCII
|
help: if you meant to use the unicode code point for 'é', use a \xHH escape
|
LL | b"\xE9";
| ~~~~
-error: raw byte string must be ASCII
+error: non-ASCII character in raw byte string literal
--> $DIR/byte-string-literals.rs:7:10
|
LL | br##"é"##;
diff --git a/src/test/ui/parser/expr-as-stmt.fixed b/src/test/ui/parser/expr-as-stmt.fixed
index 36709eea1..b06f62794 100644
--- a/src/test/ui/parser/expr-as-stmt.fixed
+++ b/src/test/ui/parser/expr-as-stmt.fixed
@@ -64,4 +64,16 @@ fn asteroids() -> impl FnOnce() -> bool {
{ foo(); } || { true } //~ ERROR E0308
}
+// https://github.com/rust-lang/rust/issues/105179
+fn r#match() -> i32 {
+ (match () { () => 1 }) + match () { () => 1 } //~ ERROR expected expression, found `+`
+ //~^ ERROR mismatched types
+}
+
+// https://github.com/rust-lang/rust/issues/102171
+fn r#unsafe() -> i32 {
+ (unsafe { 1 }) + unsafe { 1 } //~ ERROR expected expression, found `+`
+ //~^ ERROR mismatched types
+}
+
fn main() {}
diff --git a/src/test/ui/parser/expr-as-stmt.rs b/src/test/ui/parser/expr-as-stmt.rs
index 92bb972b2..b39d2b886 100644
--- a/src/test/ui/parser/expr-as-stmt.rs
+++ b/src/test/ui/parser/expr-as-stmt.rs
@@ -64,4 +64,16 @@ fn asteroids() -> impl FnOnce() -> bool {
{ foo() } || { true } //~ ERROR E0308
}
+// https://github.com/rust-lang/rust/issues/105179
+fn r#match() -> i32 {
+ match () { () => 1 } + match () { () => 1 } //~ ERROR expected expression, found `+`
+ //~^ ERROR mismatched types
+}
+
+// https://github.com/rust-lang/rust/issues/102171
+fn r#unsafe() -> i32 {
+ unsafe { 1 } + unsafe { 1 } //~ ERROR expected expression, found `+`
+ //~^ ERROR mismatched types
+}
+
fn main() {}
diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr
index 6da4ac340..18c8b0b7c 100644
--- a/src/test/ui/parser/expr-as-stmt.stderr
+++ b/src/test/ui/parser/expr-as-stmt.stderr
@@ -55,6 +55,28 @@ help: parentheses are required to parse this as an expression
LL | ({ true }) | { true }
| + +
+error: expected expression, found `+`
+ --> $DIR/expr-as-stmt.rs:69:26
+ |
+LL | match () { () => 1 } + match () { () => 1 }
+ | ^ expected expression
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL | (match () { () => 1 }) + match () { () => 1 }
+ | + +
+
+error: expected expression, found `+`
+ --> $DIR/expr-as-stmt.rs:75:18
+ |
+LL | unsafe { 1 } + unsafe { 1 }
+ | ^ expected expression
+ |
+help: parentheses are required to parse this as an expression
+ |
+LL | (unsafe { 1 }) + unsafe { 1 }
+ | + +
+
error[E0308]: mismatched types
--> $DIR/expr-as-stmt.rs:64:7
|
@@ -201,7 +223,26 @@ help: parentheses are required to parse this as an expression
LL | ({ true }) || { true }
| + +
-error: aborting due to 18 previous errors
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:69:5
+ |
+LL | match () { () => 1 } + match () { () => 1 }
+ | ^^^^^^^^^^^^^^^^^^^^- help: consider using a semicolon here
+ | |
+ | expected `()`, found integer
+
+error[E0308]: mismatched types
+ --> $DIR/expr-as-stmt.rs:75:14
+ |
+LL | unsafe { 1 } + unsafe { 1 }
+ | ^ expected `()`, found integer
+ |
+help: you might have meant to return this value
+ |
+LL | unsafe { return 1; } + unsafe { 1 }
+ | ++++++ +
+
+error: aborting due to 22 previous errors
Some errors have detailed explanations: E0308, E0600, E0614.
For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/issue-101477-enum.stderr b/src/test/ui/parser/issue-101477-enum.stderr
index bffc881bd..1edca391e 100644
--- a/src/test/ui/parser/issue-101477-enum.stderr
+++ b/src/test/ui/parser/issue-101477-enum.stderr
@@ -3,6 +3,8 @@ error: unexpected `==`
|
LL | B == 2
| ^^ help: try using `=` instead
+ |
+ = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
error: expected item, found `==`
--> $DIR/issue-101477-enum.rs:6:7
diff --git a/src/test/ui/parser/issue-102806.rs b/src/test/ui/parser/issue-102806.rs
new file mode 100644
index 000000000..ba297bdc9
--- /dev/null
+++ b/src/test/ui/parser/issue-102806.rs
@@ -0,0 +1,25 @@
+#![allow(dead_code)]
+
+#[derive(Default)]
+struct V3 {
+ x: f32,
+ y: f32,
+ z: f32,
+}
+
+fn pz(v: V3) {
+ let _ = V3 { z: 0.0, ...v};
+ //~^ ERROR expected `..`
+
+ let _ = V3 { z: 0.0, ...Default::default() };
+ //~^ ERROR expected `..`
+
+ let _ = V3 { z: 0.0, ... };
+ //~^ expected identifier
+ //~| ERROR missing fields `x` and `y` in initializer of `V3`
+
+ let V3 { z: val, ... } = v;
+ //~^ ERROR expected field pattern
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-102806.stderr b/src/test/ui/parser/issue-102806.stderr
new file mode 100644
index 000000000..6872b8bc0
--- /dev/null
+++ b/src/test/ui/parser/issue-102806.stderr
@@ -0,0 +1,45 @@
+error: expected `..`, found `...`
+ --> $DIR/issue-102806.rs:11:26
+ |
+LL | let _ = V3 { z: 0.0, ...v};
+ | ^^^
+ |
+help: use `..` to fill in the rest of the fields
+ |
+LL | let _ = V3 { z: 0.0, ..v};
+ | ~~
+
+error: expected `..`, found `...`
+ --> $DIR/issue-102806.rs:14:26
+ |
+LL | let _ = V3 { z: 0.0, ...Default::default() };
+ | ^^^
+ |
+help: use `..` to fill in the rest of the fields
+ |
+LL | let _ = V3 { z: 0.0, ..Default::default() };
+ | ~~
+
+error: expected identifier, found `...`
+ --> $DIR/issue-102806.rs:17:26
+ |
+LL | let _ = V3 { z: 0.0, ... };
+ | -- ^^^ expected identifier
+ | |
+ | while parsing this struct
+
+error: expected field pattern, found `...`
+ --> $DIR/issue-102806.rs:21:22
+ |
+LL | let V3 { z: val, ... } = v;
+ | ^^^ help: to omit remaining fields, use one fewer `.`: `..`
+
+error[E0063]: missing fields `x` and `y` in initializer of `V3`
+ --> $DIR/issue-102806.rs:17:13
+ |
+LL | let _ = V3 { z: 0.0, ... };
+ | ^^ missing `x` and `y`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0063`.
diff --git a/src/test/ui/parser/issue-103381.fixed b/src/test/ui/parser/issue-103381.fixed
new file mode 100644
index 000000000..6a9fb9910
--- /dev/null
+++ b/src/test/ui/parser/issue-103381.fixed
@@ -0,0 +1,59 @@
+// run-rustfix
+
+#![feature(let_chains)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![allow(irrefutable_let_patterns)]
+
+fn err_some(b: bool, x: Option<u32>) {
+ if b && let Some(x) = x {}
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_none(b: bool, x: Option<u32>) {
+ if b && let None = x {}
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_1() {
+ if true && true { true } else { false };
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_2() {
+ if true && false { true } else { false };
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn should_ok_1() {
+ if true && if let x = 1 { true } else { true } {}
+}
+
+fn should_ok_2() {
+ if true && if let 1 = 1 { true } else { true } {}
+}
+
+fn should_ok_3() {
+ if true && if true { true } else { false } {}
+}
+
+fn shoule_match_ok() {
+ #[cfg(feature = "full")]
+ {
+ let a = 1;
+ let b = 2;
+ if match a {
+ 1 if b == 1 => true,
+ _ => false,
+ } && if a > 1 { true } else { false }
+ {
+ true
+ }
+ }
+}
+
+fn should_ok_in_nested() {
+ if true && if true { true } else { false } { true } else { false };
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-103381.rs b/src/test/ui/parser/issue-103381.rs
new file mode 100644
index 000000000..bf79e1010
--- /dev/null
+++ b/src/test/ui/parser/issue-103381.rs
@@ -0,0 +1,59 @@
+// run-rustfix
+
+#![feature(let_chains)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![allow(irrefutable_let_patterns)]
+
+fn err_some(b: bool, x: Option<u32>) {
+ if b && if let Some(x) = x {}
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_none(b: bool, x: Option<u32>) {
+ if b && if let None = x {}
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_1() {
+ if true && if true { true } else { false };
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn err_bool_2() {
+ if true && if false { true } else { false };
+ //~^ ERROR unexpected `if` in the condition expression
+}
+
+fn should_ok_1() {
+ if true && if let x = 1 { true } else { true } {}
+}
+
+fn should_ok_2() {
+ if true && if let 1 = 1 { true } else { true } {}
+}
+
+fn should_ok_3() {
+ if true && if true { true } else { false } {}
+}
+
+fn shoule_match_ok() {
+ #[cfg(feature = "full")]
+ {
+ let a = 1;
+ let b = 2;
+ if match a {
+ 1 if b == 1 => true,
+ _ => false,
+ } && if a > 1 { true } else { false }
+ {
+ true
+ }
+ }
+}
+
+fn should_ok_in_nested() {
+ if true && if true { true } else { false } { true } else { false };
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-103381.stderr b/src/test/ui/parser/issue-103381.stderr
new file mode 100644
index 000000000..85fcc18e7
--- /dev/null
+++ b/src/test/ui/parser/issue-103381.stderr
@@ -0,0 +1,50 @@
+error: unexpected `if` in the condition expression
+ --> $DIR/issue-103381.rs:9:12
+ |
+LL | if b && if let Some(x) = x {}
+ | ^^^^
+ |
+help: remove the `if`
+ |
+LL - if b && if let Some(x) = x {}
+LL + if b && let Some(x) = x {}
+ |
+
+error: unexpected `if` in the condition expression
+ --> $DIR/issue-103381.rs:14:12
+ |
+LL | if b && if let None = x {}
+ | ^^^^
+ |
+help: remove the `if`
+ |
+LL - if b && if let None = x {}
+LL + if b && let None = x {}
+ |
+
+error: unexpected `if` in the condition expression
+ --> $DIR/issue-103381.rs:19:15
+ |
+LL | if true && if true { true } else { false };
+ | ^^^^
+ |
+help: remove the `if`
+ |
+LL - if true && if true { true } else { false };
+LL + if true && true { true } else { false };
+ |
+
+error: unexpected `if` in the condition expression
+ --> $DIR/issue-103381.rs:24:15
+ |
+LL | if true && if false { true } else { false };
+ | ^^^^
+ |
+help: remove the `if`
+ |
+LL - if true && if false { true } else { false };
+LL + if true && false { true } else { false };
+ |
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/issue-103451.rs b/src/test/ui/parser/issue-103451.rs
new file mode 100644
index 000000000..1fdb00148
--- /dev/null
+++ b/src/test/ui/parser/issue-103451.rs
@@ -0,0 +1,5 @@
+// error-pattern: this file contains an unclosed delimiter
+// error-pattern: expected value, found struct `R`
+struct R { }
+struct S {
+ x: [u8; R
diff --git a/src/test/ui/parser/issue-103451.stderr b/src/test/ui/parser/issue-103451.stderr
new file mode 100644
index 000000000..eb3c92fb4
--- /dev/null
+++ b/src/test/ui/parser/issue-103451.stderr
@@ -0,0 +1,32 @@
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-103451.rs:5:15
+ |
+LL | struct S {
+ | - unclosed delimiter
+LL | x: [u8; R
+ | - ^
+ | |
+ | unclosed delimiter
+
+error: this file contains an unclosed delimiter
+ --> $DIR/issue-103451.rs:5:15
+ |
+LL | struct S {
+ | - unclosed delimiter
+LL | x: [u8; R
+ | - ^
+ | |
+ | unclosed delimiter
+
+error[E0423]: expected value, found struct `R`
+ --> $DIR/issue-103451.rs:5:13
+ |
+LL | struct R { }
+ | ------------ `R` defined here
+LL | struct S {
+LL | x: [u8; R
+ | ^ help: use struct literal syntax instead: `R {}`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0423`.
diff --git a/src/test/ui/parser/issue-103748-ICE-wrong-braces.rs b/src/test/ui/parser/issue-103748-ICE-wrong-braces.rs
new file mode 100644
index 000000000..8012cb652
--- /dev/null
+++ b/src/test/ui/parser/issue-103748-ICE-wrong-braces.rs
@@ -0,0 +1,8 @@
+#![crate_type = "lib"]
+
+struct Apple((Apple, Option(Banana ? Citron)));
+//~^ ERROR invalid `?` in type
+//~| ERROR expected one of `)` or `,`, found `Citron`
+//~| ERROR cannot find type `Citron` in this scope [E0412]
+//~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214]
+//~| ERROR recursive type `Apple` has infinite size [E0072]
diff --git a/src/test/ui/parser/issue-103748-ICE-wrong-braces.stderr b/src/test/ui/parser/issue-103748-ICE-wrong-braces.stderr
new file mode 100644
index 000000000..b0d8b03ae
--- /dev/null
+++ b/src/test/ui/parser/issue-103748-ICE-wrong-braces.stderr
@@ -0,0 +1,51 @@
+error: invalid `?` in type
+ --> $DIR/issue-103748-ICE-wrong-braces.rs:3:36
+ |
+LL | struct Apple((Apple, Option(Banana ? Citron)));
+ | ^ `?` is only allowed on expressions, not types
+ |
+help: if you meant to express that the type might not contain a value, use the `Option` wrapper type
+ |
+LL | struct Apple((Apple, Option(Option<Banana > Citron)));
+ | +++++++ ~
+
+error: expected one of `)` or `,`, found `Citron`
+ --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
+ |
+LL | struct Apple((Apple, Option(Banana ? Citron)));
+ | -^^^^^^ expected one of `)` or `,`
+ | |
+ | help: missing `,`
+
+error[E0412]: cannot find type `Citron` in this scope
+ --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38
+ |
+LL | struct Apple((Apple, Option(Banana ? Citron)));
+ | ^^^^^^ not found in this scope
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+ --> $DIR/issue-103748-ICE-wrong-braces.rs:3:22
+ |
+LL | struct Apple((Apple, Option(Banana ? Citron)));
+ | ^^^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
+ |
+help: use angle brackets instead
+ |
+LL | struct Apple((Apple, Option<Banana ? Citron>));
+ | ~ ~
+
+error[E0072]: recursive type `Apple` has infinite size
+ --> $DIR/issue-103748-ICE-wrong-braces.rs:3:1
+ |
+LL | struct Apple((Apple, Option(Banana ? Citron)));
+ | ^^^^^^^^^^^^ ----- recursive without indirection
+ |
+help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
+ |
+LL | struct Apple((Box<Apple>, Option(Banana ? Citron)));
+ | ++++ +
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0072, E0214, E0412.
+For more information about an error, try `rustc --explain E0072`.
diff --git a/src/test/ui/parser/issue-103869.rs b/src/test/ui/parser/issue-103869.rs
new file mode 100644
index 000000000..28c442bdd
--- /dev/null
+++ b/src/test/ui/parser/issue-103869.rs
@@ -0,0 +1,9 @@
+enum VecOrMap{
+ vec: Vec<usize>,
+ //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `:`
+ //~| HELP: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
+ //~| ERROR expected item, found `:`
+ map: HashMap<String,usize>
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-103869.stderr b/src/test/ui/parser/issue-103869.stderr
new file mode 100644
index 000000000..0b8cd919a
--- /dev/null
+++ b/src/test/ui/parser/issue-103869.stderr
@@ -0,0 +1,16 @@
+error: expected one of `(`, `,`, `=`, `{`, or `}`, found `:`
+ --> $DIR/issue-103869.rs:2:8
+ |
+LL | vec: Vec<usize>,
+ | ^ expected one of `(`, `,`, `=`, `{`, or `}`
+ |
+ = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
+
+error: expected item, found `:`
+ --> $DIR/issue-103869.rs:2:8
+ |
+LL | vec: Vec<usize>,
+ | ^ expected item
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issue-104620.rs b/src/test/ui/parser/issue-104620.rs
new file mode 100644
index 000000000..f49476c44
--- /dev/null
+++ b/src/test/ui/parser/issue-104620.rs
@@ -0,0 +1,4 @@
+#![feature(rustc_attrs)]
+
+#![rustc_dummy=5z] //~ ERROR unexpected expression: `5z`
+fn main() {}
diff --git a/src/test/ui/parser/issue-104620.stderr b/src/test/ui/parser/issue-104620.stderr
new file mode 100644
index 000000000..d06a6b255
--- /dev/null
+++ b/src/test/ui/parser/issue-104620.stderr
@@ -0,0 +1,8 @@
+error: unexpected expression: `5z`
+ --> $DIR/issue-104620.rs:3:16
+ |
+LL | #![rustc_dummy=5z]
+ | ^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/issues/issue-104088.rs b/src/test/ui/parser/issues/issue-104088.rs
new file mode 100644
index 000000000..5f794fe2d
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-104088.rs
@@ -0,0 +1,26 @@
+fn test() {
+ if let 123 = 123 { println!("yes"); }
+}
+
+fn test_2() {
+ let 1x = 123;
+ //~^ ERROR expected identifier, found number literal
+}
+
+fn test_3() {
+ let 2x: i32 = 123;
+ //~^ ERROR expected identifier, found number literal
+}
+
+fn test_4() {
+ if let 2e1 = 123 {
+ //~^ ERROR mismatched types
+ }
+}
+
+fn test_5() {
+ let 23name = 123;
+ //~^ ERROR expected identifier, found number literal
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-104088.stderr b/src/test/ui/parser/issues/issue-104088.stderr
new file mode 100644
index 000000000..ff4b4bdb6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-104088.stderr
@@ -0,0 +1,29 @@
+error: expected identifier, found number literal
+ --> $DIR/issue-104088.rs:6:9
+ |
+LL | let 1x = 123;
+ | ^^ identifiers cannot start with a number
+
+error: expected identifier, found number literal
+ --> $DIR/issue-104088.rs:11:9
+ |
+LL | let 2x: i32 = 123;
+ | ^^ identifiers cannot start with a number
+
+error: expected identifier, found number literal
+ --> $DIR/issue-104088.rs:22:9
+ |
+LL | let 23name = 123;
+ | ^^^^^^ identifiers cannot start with a number
+
+error[E0308]: mismatched types
+ --> $DIR/issue-104088.rs:16:12
+ |
+LL | if let 2e1 = 123 {
+ | ^^^ --- this expression has type `{integer}`
+ | |
+ | expected integer, found floating-point number
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/item-kw-case-mismatch.fixed b/src/test/ui/parser/item-kw-case-mismatch.fixed
new file mode 100644
index 000000000..1794268f2
--- /dev/null
+++ b/src/test/ui/parser/item-kw-case-mismatch.fixed
@@ -0,0 +1,34 @@
+// run-rustfix
+// edition:2018
+#![allow(unused_imports)]
+
+fn main() {}
+
+use std::ptr::read; //~ ERROR keyword `use` is written in a wrong case
+use std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
+
+async fn _a() {}
+//~^ ERROR keyword `fn` is written in a wrong case
+
+fn _b() {}
+//~^ ERROR keyword `fn` is written in a wrong case
+
+async fn _c() {}
+//~^ ERROR keyword `async` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
+
+async fn _d() {}
+//~^ ERROR keyword `async` is written in a wrong case
+
+const unsafe fn _e() {}
+//~^ ERROR keyword `const` is written in a wrong case
+//~| ERROR keyword `unsafe` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
+
+unsafe extern fn _f() {}
+//~^ ERROR keyword `unsafe` is written in a wrong case
+//~| ERROR keyword `extern` is written in a wrong case
+
+extern "C" fn _g() {}
+//~^ ERROR keyword `extern` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
diff --git a/src/test/ui/parser/item-kw-case-mismatch.rs b/src/test/ui/parser/item-kw-case-mismatch.rs
new file mode 100644
index 000000000..ac8390efd
--- /dev/null
+++ b/src/test/ui/parser/item-kw-case-mismatch.rs
@@ -0,0 +1,34 @@
+// run-rustfix
+// edition:2018
+#![allow(unused_imports)]
+
+fn main() {}
+
+Use std::ptr::read; //~ ERROR keyword `use` is written in a wrong case
+USE std::ptr::write; //~ ERROR keyword `use` is written in a wrong case
+
+async Fn _a() {}
+//~^ ERROR keyword `fn` is written in a wrong case
+
+Fn _b() {}
+//~^ ERROR keyword `fn` is written in a wrong case
+
+aSYNC fN _c() {}
+//~^ ERROR keyword `async` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
+
+Async fn _d() {}
+//~^ ERROR keyword `async` is written in a wrong case
+
+CONST UNSAFE FN _e() {}
+//~^ ERROR keyword `const` is written in a wrong case
+//~| ERROR keyword `unsafe` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
+
+unSAFE EXTern fn _f() {}
+//~^ ERROR keyword `unsafe` is written in a wrong case
+//~| ERROR keyword `extern` is written in a wrong case
+
+EXTERN "C" FN _g() {}
+//~^ ERROR keyword `extern` is written in a wrong case
+//~| ERROR keyword `fn` is written in a wrong case
diff --git a/src/test/ui/parser/item-kw-case-mismatch.stderr b/src/test/ui/parser/item-kw-case-mismatch.stderr
new file mode 100644
index 000000000..e66dae825
--- /dev/null
+++ b/src/test/ui/parser/item-kw-case-mismatch.stderr
@@ -0,0 +1,86 @@
+error: keyword `use` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:7:1
+ |
+LL | Use std::ptr::read;
+ | ^^^ help: write it in the correct case (notice the capitalization): `use`
+
+error: keyword `use` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:8:1
+ |
+LL | USE std::ptr::write;
+ | ^^^ help: write it in the correct case: `use`
+
+error: keyword `fn` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:10:7
+ |
+LL | async Fn _a() {}
+ | ^^ help: write it in the correct case (notice the capitalization): `fn`
+
+error: keyword `fn` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:13:1
+ |
+LL | Fn _b() {}
+ | ^^ help: write it in the correct case (notice the capitalization): `fn`
+
+error: keyword `async` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:16:1
+ |
+LL | aSYNC fN _c() {}
+ | ^^^^^ help: write it in the correct case: `async`
+
+error: keyword `fn` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:16:7
+ |
+LL | aSYNC fN _c() {}
+ | ^^ help: write it in the correct case: `fn`
+
+error: keyword `async` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:20:1
+ |
+LL | Async fn _d() {}
+ | ^^^^^ help: write it in the correct case: `async`
+
+error: keyword `const` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:23:1
+ |
+LL | CONST UNSAFE FN _e() {}
+ | ^^^^^ help: write it in the correct case: `const`
+
+error: keyword `unsafe` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:23:7
+ |
+LL | CONST UNSAFE FN _e() {}
+ | ^^^^^^ help: write it in the correct case: `unsafe`
+
+error: keyword `fn` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:23:14
+ |
+LL | CONST UNSAFE FN _e() {}
+ | ^^ help: write it in the correct case: `fn`
+
+error: keyword `unsafe` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:28:1
+ |
+LL | unSAFE EXTern fn _f() {}
+ | ^^^^^^ help: write it in the correct case: `unsafe`
+
+error: keyword `extern` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:28:8
+ |
+LL | unSAFE EXTern fn _f() {}
+ | ^^^^^^ help: write it in the correct case: `extern`
+
+error: keyword `extern` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:32:1
+ |
+LL | EXTERN "C" FN _g() {}
+ | ^^^^^^ help: write it in the correct case: `extern`
+
+error: keyword `fn` is written in a wrong case
+ --> $DIR/item-kw-case-mismatch.rs:32:12
+ |
+LL | EXTERN "C" FN _g() {}
+ | ^^ help: write it in the correct case: `fn`
+
+error: aborting due to 14 previous errors
+
diff --git a/src/test/ui/parser/kw-in-trait-bounds.stderr b/src/test/ui/parser/kw-in-trait-bounds.stderr
index 28196c7ce..546ad84ee 100644
--- a/src/test/ui/parser/kw-in-trait-bounds.stderr
+++ b/src/test/ui/parser/kw-in-trait-bounds.stderr
@@ -94,8 +94,8 @@ LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
-LL | pub trait Fn<Args>: FnMut<Args> {
- | ------------------------------- similarly named trait `Fn` defined here
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | -------------------------------------- similarly named trait `Fn` defined here
error[E0405]: cannot find trait `r#fn` in this scope
--> $DIR/kw-in-trait-bounds.rs:17:4
@@ -105,8 +105,8 @@ LL | G: fn(),
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
-LL | pub trait Fn<Args>: FnMut<Args> {
- | ------------------------------- similarly named trait `Fn` defined here
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | -------------------------------------- similarly named trait `Fn` defined here
error[E0405]: cannot find trait `r#fn` in this scope
--> $DIR/kw-in-trait-bounds.rs:3:27
@@ -116,8 +116,8 @@ LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
-LL | pub trait Fn<Args>: FnMut<Args> {
- | ------------------------------- similarly named trait `Fn` defined here
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | -------------------------------------- similarly named trait `Fn` defined here
error[E0405]: cannot find trait `r#fn` in this scope
--> $DIR/kw-in-trait-bounds.rs:3:41
@@ -127,8 +127,8 @@ LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
-LL | pub trait Fn<Args>: FnMut<Args> {
- | ------------------------------- similarly named trait `Fn` defined here
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | -------------------------------------- similarly named trait `Fn` defined here
error[E0405]: cannot find trait `r#struct` in this scope
--> $DIR/kw-in-trait-bounds.rs:24:10
diff --git a/src/test/ui/parser/macro/issue-37113.stderr b/src/test/ui/parser/macro/issue-37113.stderr
index b1f8674fb..da9e743a0 100644
--- a/src/test/ui/parser/macro/issue-37113.stderr
+++ b/src/test/ui/parser/macro/issue-37113.stderr
@@ -9,6 +9,7 @@ LL | $( $t, )*
LL | test_macro!(String,);
| -------------------- in this macro invocation
|
+ = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
= note: this error originates in the macro `test_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
diff --git a/src/test/ui/parser/macro/macro-doc-comments-1.stderr b/src/test/ui/parser/macro/macro-doc-comments-1.stderr
index 0ebf3d52b..eaeb62d2c 100644
--- a/src/test/ui/parser/macro/macro-doc-comments-1.stderr
+++ b/src/test/ui/parser/macro/macro-doc-comments-1.stderr
@@ -9,6 +9,12 @@ LL | //! Inner
| |
| no rules expected this token in macro call
| inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
+ |
+note: while trying to match `[`
+ --> $DIR/macro-doc-comments-1.rs:2:7
+ |
+LL | (#[$outer:meta]) => ()
+ | ^
error: aborting due to previous error
diff --git a/src/test/ui/parser/macro/macro-doc-comments-2.stderr b/src/test/ui/parser/macro/macro-doc-comments-2.stderr
index 346d86586..1dcd95f6f 100644
--- a/src/test/ui/parser/macro/macro-doc-comments-2.stderr
+++ b/src/test/ui/parser/macro/macro-doc-comments-2.stderr
@@ -9,6 +9,12 @@ LL | /// Outer
| |
| no rules expected this token in macro call
| outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
+ |
+note: while trying to match `!`
+ --> $DIR/macro-doc-comments-2.rs:2:7
+ |
+LL | (#![$inner:meta]) => ()
+ | ^
error: aborting due to previous error
diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.rs b/src/test/ui/parser/raw/raw-byte-string-literals.rs
index 163c8ac66..1b859fee5 100644
--- a/src/test/ui/parser/raw/raw-byte-string-literals.rs
+++ b/src/test/ui/parser/raw/raw-byte-string-literals.rs
@@ -2,6 +2,6 @@
pub fn main() {
br"a "; //~ ERROR bare CR not allowed in raw string
- br"é"; //~ ERROR raw byte string must be ASCII
+ br"é"; //~ ERROR non-ASCII character in raw byte string literal
br##~"a"~##; //~ ERROR only `#` is allowed in raw string delimitation
}
diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.stderr b/src/test/ui/parser/raw/raw-byte-string-literals.stderr
index cfc877104..a2f27d1ed 100644
--- a/src/test/ui/parser/raw/raw-byte-string-literals.stderr
+++ b/src/test/ui/parser/raw/raw-byte-string-literals.stderr
@@ -4,7 +4,7 @@ error: bare CR not allowed in raw string
LL | br"a ";
| ^
-error: raw byte string must be ASCII
+error: non-ASCII character in raw byte string literal
--> $DIR/raw-byte-string-literals.rs:5:8
|
LL | br"é";
diff --git a/src/test/ui/parser/recover-fn-ptr-with-generics.rs b/src/test/ui/parser/recover-fn-ptr-with-generics.rs
new file mode 100644
index 000000000..31de418be
--- /dev/null
+++ b/src/test/ui/parser/recover-fn-ptr-with-generics.rs
@@ -0,0 +1,31 @@
+fn main() {
+ type Predicate = fn<'a>(&'a str) -> bool;
+ //~^ ERROR function pointer types may not have generic parameters
+
+ type Identity = fn<T>(T) -> T;
+ //~^ ERROR function pointer types may not have generic parameters
+ //~| ERROR cannot find type `T` in this scope
+ //~| ERROR cannot find type `T` in this scope
+
+ let _: fn<const N: usize, 'e, Q, 'f>();
+ //~^ ERROR function pointer types may not have generic parameters
+
+ let _: for<'outer> fn<'inner>();
+ //~^ ERROR function pointer types may not have generic parameters
+
+ let _: for<> fn<'r>();
+ //~^ ERROR function pointer types may not have generic parameters
+
+ type Hmm = fn<>();
+ //~^ ERROR function pointer types may not have generic parameters
+
+ let _: extern fn<'a: 'static>();
+ //~^ ERROR function pointer types may not have generic parameters
+ //~| ERROR lifetime bounds cannot be used in this context
+
+ let _: for<'any> extern "C" fn<'u>();
+ //~^ ERROR function pointer types may not have generic parameters
+
+ type QuiteBroken = fn<const>();
+ //~^ ERROR expected identifier, found `>`
+}
diff --git a/src/test/ui/parser/recover-fn-ptr-with-generics.stderr b/src/test/ui/parser/recover-fn-ptr-with-generics.stderr
new file mode 100644
index 000000000..1da9c1857
--- /dev/null
+++ b/src/test/ui/parser/recover-fn-ptr-with-generics.stderr
@@ -0,0 +1,111 @@
+error: function pointer types may not have generic parameters
+ --> $DIR/recover-fn-ptr-with-generics.rs:2:24
+ |
+LL | type Predicate = fn<'a>(&'a str) -> bool;
+ | ^^^^
+ |
+help: consider moving the lifetime parameter to a `for` parameter list
+ |
+LL - type Predicate = fn<'a>(&'a str) -> bool;
+LL + type Predicate = for<'a> fn(&'a str) -> bool;
+ |
+
+error: function pointer types may not have generic parameters
+ --> $DIR/recover-fn-ptr-with-generics.rs:5:23
+ |
+LL | type Identity = fn<T>(T) -> T;
+ | ^^^
+
+error: function pointer types may not have generic parameters
+ --> $DIR/recover-fn-ptr-with-generics.rs:10:14
+ |
+LL | let _: fn<const N: usize, 'e, Q, 'f>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: consider moving the lifetime parameters to a `for` parameter list
+ |
+LL - let _: fn<const N: usize, 'e, Q, 'f>();
+LL + let _: for<'e, 'f> fn();
+ |
+
+error: function pointer types may not have generic parameters
+ --> $DIR/recover-fn-ptr-with-generics.rs:13:26
+ |
+LL | let _: for<'outer> fn<'inner>();
+ | ^^^^^^^^
+ |
+help: consider moving the lifetime parameter to the `for` parameter list
+ |
+LL - let _: for<'outer> fn<'inner>();
+LL + let _: for<'outer, 'inner> fn();
+ |
+
+error: function pointer types may not have generic parameters
+ --> $DIR/recover-fn-ptr-with-generics.rs:16:20
+ |
+LL | let _: for<> fn<'r>();
+ | ^^^^
+ |
+help: consider moving the lifetime parameter to the `for` parameter list
+ |
+LL - let _: for<> fn<'r>();
+LL + let _: for<'r> fn();
+ |
+
+error: function pointer types may not have generic parameters
+ --> $DIR/recover-fn-ptr-with-generics.rs:19:18
+ |
+LL | type Hmm = fn<>();
+ | ^^
+
+error: function pointer types may not have generic parameters
+ --> $DIR/recover-fn-ptr-with-generics.rs:22:21
+ |
+LL | let _: extern fn<'a: 'static>();
+ | ^^^^^^^^^^^^^
+ |
+help: consider moving the lifetime parameter to a `for` parameter list
+ |
+LL - let _: extern fn<'a: 'static>();
+LL + let _: for<'a> extern fn();
+ |
+
+error: function pointer types may not have generic parameters
+ --> $DIR/recover-fn-ptr-with-generics.rs:26:35
+ |
+LL | let _: for<'any> extern "C" fn<'u>();
+ | ^^^^
+ |
+help: consider moving the lifetime parameter to the `for` parameter list
+ |
+LL - let _: for<'any> extern "C" fn<'u>();
+LL + let _: for<'any, 'u> extern "C" fn();
+ |
+
+error: expected identifier, found `>`
+ --> $DIR/recover-fn-ptr-with-generics.rs:29:32
+ |
+LL | type QuiteBroken = fn<const>();
+ | ^ expected identifier
+
+error: lifetime bounds cannot be used in this context
+ --> $DIR/recover-fn-ptr-with-generics.rs:22:26
+ |
+LL | let _: extern fn<'a: 'static>();
+ | ^^^^^^^
+
+error[E0412]: cannot find type `T` in this scope
+ --> $DIR/recover-fn-ptr-with-generics.rs:5:27
+ |
+LL | type Identity = fn<T>(T) -> T;
+ | ^ not found in this scope
+
+error[E0412]: cannot find type `T` in this scope
+ --> $DIR/recover-fn-ptr-with-generics.rs:5:33
+ |
+LL | type Identity = fn<T>(T) -> T;
+ | ^ not found in this scope
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr
index 483312c16..04968bbdf 100644
--- a/src/test/ui/parser/recover-from-bad-variant.stderr
+++ b/src/test/ui/parser/recover-from-bad-variant.stderr
@@ -14,14 +14,11 @@ LL - let x = Enum::Foo(a: 3, b: 4);
LL + let x = Enum::Foo(3, 4);
|
-error[E0532]: expected tuple struct or tuple variant, found struct variant `Enum::Foo`
+error[E0164]: expected tuple struct or tuple variant, found struct variant `Enum::Foo`
--> $DIR/recover-from-bad-variant.rs:10:9
|
-LL | Foo { a: usize, b: usize },
- | -------------------------- `Enum::Foo` defined here
-...
LL | Enum::Foo(a, b) => {}
- | ^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `Enum::Foo { a, b }`
+ | ^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
error[E0769]: tuple variant `Enum::Bar` written as struct variant
--> $DIR/recover-from-bad-variant.rs:12:9
@@ -36,5 +33,5 @@ LL | Enum::Bar(a, b) => {}
error: aborting due to 3 previous errors
-Some errors have detailed explanations: E0532, E0769.
-For more information about an error, try `rustc --explain E0532`.
+Some errors have detailed explanations: E0164, E0769.
+For more information about an error, try `rustc --explain E0164`.
diff --git a/src/test/ui/slowparse-bstring.rs b/src/test/ui/parser/slowparse-bstring.rs
index f3a6a6683..f3a6a6683 100644
--- a/src/test/ui/slowparse-bstring.rs
+++ b/src/test/ui/parser/slowparse-bstring.rs
diff --git a/src/test/ui/slowparse-string.rs b/src/test/ui/parser/slowparse-string.rs
index 6ebc61dae..6ebc61dae 100644
--- a/src/test/ui/slowparse-string.rs
+++ b/src/test/ui/parser/slowparse-string.rs
diff --git a/src/test/ui/parser/struct-literal-variant-in-if.stderr b/src/test/ui/parser/struct-literal-variant-in-if.stderr
index 4cffbe433..9f0c0074d 100644
--- a/src/test/ui/parser/struct-literal-variant-in-if.stderr
+++ b/src/test/ui/parser/struct-literal-variant-in-if.stderr
@@ -42,16 +42,11 @@ help: surround the struct literal with parentheses
LL | if x == (E::K { field: "" }) {}
| + +
-error[E0423]: expected value, found struct variant `E::V`
+error[E0533]: expected value, found struct variant `E::V`
--> $DIR/struct-literal-variant-in-if.rs:10:13
|
LL | if x == E::V { field } {}
| ^^^^ not a value
- |
-help: surround the struct literal with parentheses
- |
-LL | if x == (E::V { field }) {}
- | + +
error[E0308]: mismatched types
--> $DIR/struct-literal-variant-in-if.rs:10:20
@@ -72,5 +67,5 @@ LL | let y: usize = ();
error: aborting due to 7 previous errors
-Some errors have detailed explanations: E0308, E0423.
+Some errors have detailed explanations: E0308, E0533.
For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/underscore-suffix-for-string.rs b/src/test/ui/parser/underscore-suffix-for-string.rs
index 2e0ebe2cf..bd260752e 100644
--- a/src/test/ui/parser/underscore-suffix-for-string.rs
+++ b/src/test/ui/parser/underscore-suffix-for-string.rs
@@ -1,8 +1,17 @@
-// check-pass
+macro_rules! sink {
+ ($tt:tt) => {()}
+}
fn main() {
let _ = "Foo"_;
- //~^ WARNING underscore literal suffix is not allowed
- //~| WARNING this was previously accepted
- //~| NOTE issue #42326
+ //~^ ERROR underscore literal suffix is not allowed
+
+ // This is ok, because `__` is a valid identifier and the macro consumes it
+ // before proper parsing happens.
+ let _ = sink!("Foo"__);
+
+ // This is not ok, even as an input to a macro, because the `_` suffix is
+ // never allowed.
+ sink!("Foo"_);
+ //~^ ERROR underscore literal suffix is not allowed
}
diff --git a/src/test/ui/parser/underscore-suffix-for-string.stderr b/src/test/ui/parser/underscore-suffix-for-string.stderr
index 00c7657f1..2fe2c130e 100644
--- a/src/test/ui/parser/underscore-suffix-for-string.stderr
+++ b/src/test/ui/parser/underscore-suffix-for-string.stderr
@@ -1,11 +1,14 @@
-warning: underscore literal suffix is not allowed
- --> $DIR/underscore-suffix-for-string.rs:4:18
+error: underscore literal suffix is not allowed
+ --> $DIR/underscore-suffix-for-string.rs:6:18
|
LL | let _ = "Foo"_;
| ^
+
+error: underscore literal suffix is not allowed
+ --> $DIR/underscore-suffix-for-string.rs:15:16
|
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: see issue #42326 <https://github.com/rust-lang/rust/issues/42326> for more information
+LL | sink!("Foo"_);
+ | ^
-warning: 1 warning emitted
+error: aborting due to 2 previous errors
diff --git a/src/test/ui/parser/unicode-control-codepoints.rs b/src/test/ui/parser/unicode-control-codepoints.rs
index 5af0b585a..df099bb62 100644
--- a/src/test/ui/parser/unicode-control-codepoints.rs
+++ b/src/test/ui/parser/unicode-control-codepoints.rs
@@ -14,15 +14,15 @@ fn main() {
println!("{:?}", r##"/*‮ } â¦if isAdmin⩠⦠begin admins only "##);
//~^ ERROR unicode codepoint changing visible direction of text present in literal
println!("{:?}", b"/*‮ } â¦if isAdmin⩠⦠begin admins only ");
- //~^ ERROR non-ASCII character in byte constant
- //~| ERROR non-ASCII character in byte constant
- //~| ERROR non-ASCII character in byte constant
- //~| ERROR non-ASCII character in byte constant
+ //~^ ERROR non-ASCII character in byte string literal
+ //~| ERROR non-ASCII character in byte string literal
+ //~| ERROR non-ASCII character in byte string literal
+ //~| ERROR non-ASCII character in byte string literal
println!("{:?}", br##"/*‮ } â¦if isAdmin⩠⦠begin admins only "##);
- //~^ ERROR raw byte string must be ASCII
- //~| ERROR raw byte string must be ASCII
- //~| ERROR raw byte string must be ASCII
- //~| ERROR raw byte string must be ASCII
+ //~^ ERROR non-ASCII character in raw byte string literal
+ //~| ERROR non-ASCII character in raw byte string literal
+ //~| ERROR non-ASCII character in raw byte string literal
+ //~| ERROR non-ASCII character in raw byte string literal
println!("{:?}", '‮');
//~^ ERROR unicode codepoint changing visible direction of text present in literal
}
diff --git a/src/test/ui/parser/unicode-control-codepoints.stderr b/src/test/ui/parser/unicode-control-codepoints.stderr
index 44548c72f..fc071a941 100644
--- a/src/test/ui/parser/unicode-control-codepoints.stderr
+++ b/src/test/ui/parser/unicode-control-codepoints.stderr
@@ -14,69 +14,69 @@ LL | println!("{:?}", b"us\u{202B}e\u{202A}r");
|
= help: unicode escape sequences cannot be used as a byte or in a byte string
-error: non-ASCII character in byte constant
+error: non-ASCII character in byte string literal
--> $DIR/unicode-control-codepoints.rs:16:26
|
LL | println!("{:?}", b"/* } if isAdmin begin admins only ");
- | ^ byte constant must be ASCII but is '\u{202e}'
+ | ^ must be ASCII but is '\u{202e}'
|
help: if you meant to use the UTF-8 encoding of '\u{202e}', use \xHH escapes
|
LL | println!("{:?}", b"/*\xE2\x80\xAE } if isAdmin begin admins only ");
| ~~~~~~~~~~~~
-error: non-ASCII character in byte constant
+error: non-ASCII character in byte string literal
--> $DIR/unicode-control-codepoints.rs:16:30
|
LL | println!("{:?}", b"/* } if isAdmin begin admins only ");
- | ^ byte constant must be ASCII but is '\u{2066}'
+ | ^ must be ASCII but is '\u{2066}'
|
help: if you meant to use the UTF-8 encoding of '\u{2066}', use \xHH escapes
|
LL | println!("{:?}", b"/* } \xE2\x81\xA6if isAdmin begin admins only ");
| ~~~~~~~~~~~~
-error: non-ASCII character in byte constant
+error: non-ASCII character in byte string literal
--> $DIR/unicode-control-codepoints.rs:16:41
|
LL | println!("{:?}", b"/* } if isAdmin begin admins only ");
- | ^ byte constant must be ASCII but is '\u{2069}'
+ | ^ must be ASCII but is '\u{2069}'
|
help: if you meant to use the UTF-8 encoding of '\u{2069}', use \xHH escapes
|
LL | println!("{:?}", b"/* } if isAdmin\xE2\x81\xA9 begin admins only ");
| ~~~~~~~~~~~~
-error: non-ASCII character in byte constant
+error: non-ASCII character in byte string literal
--> $DIR/unicode-control-codepoints.rs:16:43
|
LL | println!("{:?}", b"/* } if isAdmin begin admins only ");
- | ^ byte constant must be ASCII but is '\u{2066}'
+ | ^ must be ASCII but is '\u{2066}'
|
help: if you meant to use the UTF-8 encoding of '\u{2066}', use \xHH escapes
|
LL | println!("{:?}", b"/* } if isAdmin \xE2\x81\xA6 begin admins only ");
| ~~~~~~~~~~~~
-error: raw byte string must be ASCII
+error: non-ASCII character in raw byte string literal
--> $DIR/unicode-control-codepoints.rs:21:29
|
LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##);
| ^ must be ASCII but is '\u{202e}'
-error: raw byte string must be ASCII
+error: non-ASCII character in raw byte string literal
--> $DIR/unicode-control-codepoints.rs:21:33
|
LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##);
| ^ must be ASCII but is '\u{2066}'
-error: raw byte string must be ASCII
+error: non-ASCII character in raw byte string literal
--> $DIR/unicode-control-codepoints.rs:21:44
|
LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##);
| ^ must be ASCII but is '\u{2069}'
-error: raw byte string must be ASCII
+error: non-ASCII character in raw byte string literal
--> $DIR/unicode-control-codepoints.rs:21:46
|
LL | println!("{:?}", br##"/* } if isAdmin begin admins only "##);
diff --git a/src/test/ui/parser/use-colon-as-mod-sep.rs b/src/test/ui/parser/use-colon-as-mod-sep.rs
new file mode 100644
index 000000000..e1e8756b0
--- /dev/null
+++ b/src/test/ui/parser/use-colon-as-mod-sep.rs
@@ -0,0 +1,11 @@
+// Recover from using a colon as a path separator.
+
+use std::process:Command;
+//~^ ERROR expected `::`, found `:`
+use std:fs::File;
+//~^ ERROR expected `::`, found `:`
+use std:collections:HashMap;
+//~^ ERROR expected `::`, found `:`
+//~| ERROR expected `::`, found `:`
+
+fn main() { }
diff --git a/src/test/ui/parser/use-colon-as-mod-sep.stderr b/src/test/ui/parser/use-colon-as-mod-sep.stderr
new file mode 100644
index 000000000..e825dfed1
--- /dev/null
+++ b/src/test/ui/parser/use-colon-as-mod-sep.stderr
@@ -0,0 +1,28 @@
+error: expected `::`, found `:`
+ --> $DIR/use-colon-as-mod-sep.rs:3:17
+ |
+LL | use std::process:Command;
+ | ^ help: use double colon
+ |
+ = note: import paths are delimited using `::`
+
+error: expected `::`, found `:`
+ --> $DIR/use-colon-as-mod-sep.rs:5:8
+ |
+LL | use std:fs::File;
+ | ^ help: use double colon
+
+error: expected `::`, found `:`
+ --> $DIR/use-colon-as-mod-sep.rs:7:8
+ |
+LL | use std:collections:HashMap;
+ | ^ help: use double colon
+
+error: expected `::`, found `:`
+ --> $DIR/use-colon-as-mod-sep.rs:7:20
+ |
+LL | use std:collections:HashMap;
+ | ^ help: use double colon
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
index fad84dda0..c8b45fd24 100644
--- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
+++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
@@ -16,6 +16,11 @@ LL | Some(_z @ ref _y) => {}
| | value borrowed here after move
| value moved into `_z` here
| move occurs because `_z` has type `X` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | Some(ref _z @ ref _y) => {}
+ | +++
error: cannot move out of value because it is borrowed
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:26:14
@@ -35,6 +40,11 @@ LL | Some(_z @ ref mut _y) => {}
| | value borrowed here after move
| value moved into `_z` here
| move occurs because `_z` has type `X` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | Some(ref _z @ ref mut _y) => {}
+ | +++
error[E0382]: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:14
@@ -45,7 +55,7 @@ LL | Some(ref _y @ _z) => {}
| value borrowed here after move
|
= note: move occurs because value has type `X`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `x.0`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | Some(ref _y @ ref _z) => {}
| +++
@@ -59,7 +69,7 @@ LL | Some(ref mut _y @ _z) => {}
| value borrowed here after move
|
= note: move occurs because value has type `X`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving `x.0`
+help: borrow this binding in the pattern to avoid moving the value
|
LL | Some(ref mut _y @ ref _z) => {}
| +++
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
index a227cc583..324897151 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
@@ -6,6 +6,11 @@ LL | let a @ b = U;
| | |
| | value moved here
| value used here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ ref b = U;
+ | +++ +++
error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:13:9
@@ -16,6 +21,10 @@ LL | let a @ (b, c) = (U, U);
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ (b, ref c) = (U, U);
+ | +++ +++
error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:15:9
@@ -26,6 +35,10 @@ LL | let a @ (b, c) = (u(), u());
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ (b, ref c) = (u(), u());
+ | +++ +++
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:18:16
@@ -36,6 +49,11 @@ LL | a @ Ok(b) | a @ Err(b) => {}
| - ^ value used here after move
| |
| value moved here
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref a @ Ok(b) | a @ Err(b) => {}
+ | +++
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:18:29
@@ -46,6 +64,11 @@ LL | a @ Ok(b) | a @ Err(b) => {}
| - ^ value used here after move
| |
| value moved here
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | a @ Ok(b) | ref a @ Err(b) => {}
+ | +++
error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:25:9
@@ -56,6 +79,10 @@ LL | xs @ [a, .., b] => {}
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref xs @ [a, .., ref b] => {}
+ | +++ +++
error[E0382]: use of partially moved value
--> $DIR/borrowck-move-and-move.rs:29:9
@@ -66,6 +93,10 @@ LL | xs @ [_, ys @ .., _] => {}
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref xs @ [_, ref ys @ .., _] => {}
+ | +++ +++
error[E0382]: use of moved value
--> $DIR/borrowck-move-and-move.rs:22:12
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
index 002c7609f..f27df32cc 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
@@ -79,6 +79,10 @@ LL | let ref a @ box b = Box::new(NC);
| value borrowed here after move
|
= note: move occurs because value has type `NC`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ box ref b = Box::new(NC);
+ | +++
error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:38:9
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr
index be4e81c61..d6474f1b4 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr
@@ -7,6 +7,11 @@ LL | let a @ ref b = U;
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ ref b = U;
+ | +++
error: aborting due to previous error
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
index a9e66de08..389e86e64 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
@@ -7,6 +7,11 @@ LL | let a @ ref b = U;
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ ref b = U;
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:9
@@ -18,6 +23,11 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ (mut b @ ref mut c, d @ ref e) = (U, U);
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:14
@@ -28,6 +38,11 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let a @ (ref mut b @ ref mut c, d @ ref e) = (U, U);
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:33
@@ -38,6 +53,11 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| | value borrowed here after move
| value moved into `d` here
| move occurs because `d` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let a @ (mut b @ ref mut c, ref d @ ref e) = (U, U);
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:29:9
@@ -49,6 +69,11 @@ LL | let a @ [ref mut b, ref c] = [U, U];
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ [ref mut b, ref c] = [U, U];
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:9
@@ -59,6 +84,11 @@ LL | let a @ ref b = u();
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ ref b = u();
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:9
@@ -70,6 +100,11 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:14
@@ -80,6 +115,11 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let a @ (ref mut b @ ref mut c, d @ ref e) = (u(), u());
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:33
@@ -90,6 +130,11 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| | value borrowed here after move
| value moved into `d` here
| move occurs because `d` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let a @ (mut b @ ref mut c, ref d @ ref e) = (u(), u());
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:9
@@ -101,6 +146,11 @@ LL | let a @ [ref mut b, ref c] = [u(), u()];
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ [ref mut b, ref c] = [u(), u()];
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:42:9
@@ -111,6 +161,11 @@ LL | a @ Some(ref b) => {}
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref a @ Some(ref b) => {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:9
@@ -122,6 +177,11 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref a @ Some((mut b @ ref mut c, d @ ref e)) => {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:19
@@ -132,6 +192,11 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | a @ Some((ref mut b @ ref mut c, d @ ref e)) => {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:38
@@ -142,6 +207,11 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| | value borrowed here after move
| value moved into `d` here
| move occurs because `d` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | a @ Some((mut b @ ref mut c, ref d @ ref e)) => {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:55:9
@@ -153,6 +223,11 @@ LL | mut a @ Some([ref b, ref mut c]) => {}
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref mut a @ Some([ref b, ref mut c]) => {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:9
@@ -163,6 +238,11 @@ LL | a @ Some(ref b) => {}
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref a @ Some(ref b) => {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:9
@@ -174,6 +254,11 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref a @ Some((mut b @ ref mut c, d @ ref e)) => {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:19
@@ -184,6 +269,11 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | a @ Some((ref mut b @ ref mut c, d @ ref e)) => {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:38
@@ -194,6 +284,11 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| | value borrowed here after move
| value moved into `d` here
| move occurs because `d` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | a @ Some((mut b @ ref mut c, ref d @ ref e)) => {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:9
@@ -205,6 +300,11 @@ LL | mut a @ Some([ref b, ref mut c]) => {}
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref mut a @ Some([ref b, ref mut c]) => {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11
@@ -215,6 +315,11 @@ LL | fn f1(a @ ref b: U) {}
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | fn f1(ref a @ ref b: U) {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11
@@ -226,6 +331,11 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | fn f2(ref mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:20
@@ -236,6 +346,11 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | fn f2(mut a @ (ref b @ ref c, mut d @ ref e): (U, U)) {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:31
@@ -246,6 +361,11 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
| | value borrowed here after move
| value moved into `d` here
| move occurs because `d` has type `U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | fn f2(mut a @ (b @ ref c, ref mut d @ ref e): (U, U)) {}
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:19:11
@@ -257,6 +377,11 @@ LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {}
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | fn f3(ref a @ [ref mut b, ref c]: [U; 2]) {}
+ | +++
error[E0382]: use of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:9
@@ -267,6 +392,10 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ (mut b @ ref mut c, ref d @ ref e) = (U, U);
+ | +++ +++
error[E0382]: use of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:9
@@ -277,6 +406,10 @@ LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
| value used here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ (mut b @ ref mut c, ref d @ ref e) = (u(), u());
+ | +++ +++
error[E0382]: use of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:38
@@ -285,6 +418,11 @@ LL | match Some((U, U)) {
| ------------ move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| - value moved here ^ value used here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref a @ Some((mut b @ ref mut c, d @ ref e)) => {}
+ | +++
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:55:30
@@ -305,6 +443,11 @@ LL | a @ Some(ref b) => {}
| - ^^^^^ value borrowed here after move
| |
| value moved here
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref a @ Some(ref b) => {}
+ | +++
error[E0382]: use of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:38
@@ -313,6 +456,11 @@ LL | match Some((u(), u())) {
| ---------------- move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait
LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {}
| - value moved here ^ value used here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | ref a @ Some((mut b @ ref mut c, d @ ref e)) => {}
+ | +++
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:30
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
index b2f22fe86..770bb8953 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
@@ -242,6 +242,10 @@ LL | let ref mut a @ [b, mut c] = [U, U];
| value borrowed here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref mut a @ [b, ref mut c] = [U, U];
+ | +++
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:33:9
@@ -251,6 +255,11 @@ LL | let ref a @ b = u();
| | |
| | value moved here
| value borrowed here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ ref b = u();
+ | +++
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:36:18
@@ -261,6 +270,10 @@ LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
| value borrowed here after move
|
= note: move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ (ref b @ ref mut c, ref d @ e) = (u(), u());
+ | +++
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:36:33
@@ -271,6 +284,10 @@ LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
| value borrowed here after move
|
= note: move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ (ref b @ mut c, ref d @ ref e) = (u(), u());
+ | +++
error[E0382]: borrow of partially moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:42:9
@@ -281,6 +298,10 @@ LL | let ref mut a @ [b, mut c] = [u(), u()];
| value borrowed here after partial move
|
= note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref mut a @ [b, ref mut c] = [u(), u()];
+ | +++
error[E0382]: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref.rs:69:23
@@ -291,7 +312,7 @@ LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| value borrowed here after move
|
= note: move occurs because value has type `U`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving the value
+help: borrow this binding in the pattern to avoid moving the value
|
LL | ref a @ Some((ref b @ ref mut c, ref d @ e)) => {}
| +++
@@ -305,7 +326,7 @@ LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {}
| value borrowed here after move
|
= note: move occurs because value has type `U`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving the value
+help: borrow this binding in the pattern to avoid moving the value
|
LL | ref a @ Some((ref b @ mut c, ref d @ ref e)) => {}
| +++
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
index 384a57b2e..ad4ce7952 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
@@ -97,6 +97,11 @@ LL | let a @ (ref mut b, ref mut c) = (U, U);
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ (ref mut b, ref mut c) = (U, U);
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:67:9
@@ -109,6 +114,11 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^--
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `&mut (U, [U; 2])` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ (b, [c, d]) = &mut val; // Same as ^--
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:70:9
@@ -119,6 +129,11 @@ LL | let a @ &mut ref mut b = &mut U;
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `&mut U` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ &mut ref mut b = &mut U;
+ | +++
error: borrow of moved value
--> $DIR/borrowck-pat-ref-mut-twice.rs:72:9
@@ -130,6 +145,11 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
| | value borrowed here after move
| value moved into `a` here
| move occurs because `a` has type `&mut (U, U)` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ &mut (ref mut b, ref mut c) = &mut (U, U);
+ | +++
error: cannot borrow value as mutable more than once at a time
--> $DIR/borrowck-pat-ref-mut-twice.rs:76:9
diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr
index cd3234952..e0e623fa5 100644
--- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr
+++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr
@@ -7,6 +7,10 @@ LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
| value used here after partial move
|
= note: partial move occurs because value has type `NC<C, C>`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref a @ NC(b, ref c @ NC(d, e)) = NC(C, NC(C, C));
+ | +++ +++
error: aborting due to previous error
diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
index 840a513d6..638bdd6db 100644
--- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
+++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
@@ -34,6 +34,11 @@ LL | Ok(ref a @ b) | Err(b @ ref a) => {
| | value borrowed here after move
| value moved into `b` here
| move occurs because `b` has type `NotCopy` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | Ok(ref a @ b) | Err(ref b @ ref a) => {
+ | +++
error: cannot move out of value because it is borrowed
--> $DIR/default-binding-modes-both-sides-independent.rs:42:9
@@ -52,6 +57,11 @@ LL | let ref mut a @ b = NotCopy;
| | |
| | value moved here
| value borrowed here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref mut a @ ref b = NotCopy;
+ | +++
error: aborting due to 6 previous errors
diff --git a/src/test/ui/issues/issue-52240.rs b/src/test/ui/pattern/issue-52240.rs
index 5def55778..5def55778 100644
--- a/src/test/ui/issues/issue-52240.rs
+++ b/src/test/ui/pattern/issue-52240.rs
diff --git a/src/test/ui/issues/issue-52240.stderr b/src/test/ui/pattern/issue-52240.stderr
index 69b663b17..69b663b17 100644
--- a/src/test/ui/issues/issue-52240.stderr
+++ b/src/test/ui/pattern/issue-52240.stderr
diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
index bac2db6ce..bb7b81836 100644
--- a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
+++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
@@ -129,6 +129,10 @@ LL | drop(tup.1);
| ^^^^^ value used here after move
|
= note: move occurs because `tup.1` has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let (ref _x0, ref _x1, ref _x2, ..) = tup;
+ | +++
error[E0382]: borrow of moved value: `tup.1`
--> $DIR/borrowck-move-ref-pattern.rs:29:20
diff --git a/src/test/ui/pattern/non-structural-match-types.stderr b/src/test/ui/pattern/non-structural-match-types.stderr
index 45e162649..dea7c4695 100644
--- a/src/test/ui/pattern/non-structural-match-types.stderr
+++ b/src/test/ui/pattern/non-structural-match-types.stderr
@@ -4,7 +4,7 @@ error: `[closure@$DIR/non-structural-match-types.rs:9:17: 9:19]` cannot be used
LL | const { || {} } => {},
| ^^^^^^^^^^^^^^^
-error: `impl Future<Output = ()>` cannot be used in patterns
+error: `[async block@$DIR/non-structural-match-types.rs:12:17: 12:25]` cannot be used in patterns
--> $DIR/non-structural-match-types.rs:12:9
|
LL | const { async {} } => {},
diff --git a/src/test/ui/pattern/pattern-binding-disambiguation.rs b/src/test/ui/pattern/pattern-binding-disambiguation.rs
index 2e80ea345..ce1d8c6c0 100644
--- a/src/test/ui/pattern/pattern-binding-disambiguation.rs
+++ b/src/test/ui/pattern/pattern-binding-disambiguation.rs
@@ -33,7 +33,7 @@ fn main() {
TupleVariant => {} //~ ERROR match bindings cannot shadow tuple variants
}
match doesnt_matter {
- BracedVariant => {} //~ ERROR match bindings cannot shadow struct variants
+ BracedVariant => {} // OK, `BracedVariant` is a fresh binding
}
match CONST {
CONST => {} // OK, `CONST` is a const pattern
@@ -50,7 +50,7 @@ fn main() {
let BracedStruct = doesnt_matter; // OK, `BracedStruct` is a fresh binding
let UnitVariant = UnitVariant; // OK, `UnitVariant` is a unit variant pattern
let TupleVariant = doesnt_matter; //~ ERROR let bindings cannot shadow tuple variants
- let BracedVariant = doesnt_matter; //~ ERROR let bindings cannot shadow struct variants
+ let BracedVariant = doesnt_matter; // OK, `BracedVariant` is a fresh binding
let CONST = CONST; // OK, `CONST` is a const pattern
let STATIC = doesnt_matter; //~ ERROR let bindings cannot shadow statics
let function = doesnt_matter; // OK, `function` is a fresh binding
diff --git a/src/test/ui/pattern/pattern-binding-disambiguation.stderr b/src/test/ui/pattern/pattern-binding-disambiguation.stderr
index 1529e538b..d54467b3c 100644
--- a/src/test/ui/pattern/pattern-binding-disambiguation.stderr
+++ b/src/test/ui/pattern/pattern-binding-disambiguation.stderr
@@ -22,15 +22,6 @@ LL | TupleVariant => {}
| cannot be named the same as a tuple variant
| help: try specify the pattern arguments: `TupleVariant(..)`
-error[E0530]: match bindings cannot shadow struct variants
- --> $DIR/pattern-binding-disambiguation.rs:36:9
- |
-LL | use E::*;
- | ---- the struct variant `BracedVariant` is imported here
-...
-LL | BracedVariant => {}
- | ^^^^^^^^^^^^^ cannot be named the same as a struct variant
-
error[E0530]: match bindings cannot shadow statics
--> $DIR/pattern-binding-disambiguation.rs:42:9
|
@@ -58,15 +49,6 @@ LL | use E::*;
LL | let TupleVariant = doesnt_matter;
| ^^^^^^^^^^^^ cannot be named the same as a tuple variant
-error[E0530]: let bindings cannot shadow struct variants
- --> $DIR/pattern-binding-disambiguation.rs:53:9
- |
-LL | use E::*;
- | ---- the struct variant `BracedVariant` is imported here
-...
-LL | let BracedVariant = doesnt_matter;
- | ^^^^^^^^^^^^^ cannot be named the same as a struct variant
-
error[E0530]: let bindings cannot shadow statics
--> $DIR/pattern-binding-disambiguation.rs:55:9
|
@@ -76,6 +58,6 @@ LL | static STATIC: () = ();
LL | let STATIC = doesnt_matter;
| ^^^^^^ cannot be named the same as a static
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0530`.
diff --git a/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs b/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs
new file mode 100644
index 000000000..02599d7c0
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.rs
@@ -0,0 +1,18 @@
+#![allow(warnings)]
+
+struct MyType;
+
+impl PartialEq<usize> for MyType {
+ fn eq(&self, y: &usize) -> bool {
+ true
+ }
+}
+
+const CONSTANT: &&MyType = &&MyType;
+
+fn main() {
+ if let CONSTANT = &&MyType {
+ //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+ println!("did match!");
+ }
+}
diff --git a/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr
new file mode 100644
index 000000000..358421cd6
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr
@@ -0,0 +1,8 @@
+error: to use a constant of type `MyType` in a pattern, `MyType` must be annotated with `#[derive(PartialEq, Eq)]`
+ --> $DIR/const-partial_eq-fallback-ice.rs:14:12
+ |
+LL | if let CONSTANT = &&MyType {
+ | ^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pattern/usefulness/uninhabited.rs b/src/test/ui/pattern/usefulness/uninhabited.rs
index 77cd0f400..5622808d4 100644
--- a/src/test/ui/pattern/usefulness/uninhabited.rs
+++ b/src/test/ui/pattern/usefulness/uninhabited.rs
@@ -2,7 +2,7 @@
// aux-build:empty.rs
//
// This tests plays with matching and uninhabited types. This also serves as a test for the
-// `tcx.is_ty_uninhabited_from()` function.
+// `Ty::is_inhabited_from` function.
#![feature(never_type)]
#![feature(never_type_fallback)]
#![feature(exhaustive_patterns)]
diff --git a/src/test/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr b/src/test/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
index 4971263af..fc1be052f 100644
--- a/src/test/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
+++ b/src/test/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let phantom_pinned = identity(pin!(PhantomPinned));
| ^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
LL |
LL | stuff(phantom_pinned)
| -------------- borrow later used here
@@ -18,7 +18,7 @@ error[E0716]: temporary value dropped while borrowed
LL | let phantom_pinned = {
| -------------- borrow later stored here
LL | let phantom_pinned = pin!(PhantomPinned);
- | ^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
...
LL | };
| - temporary value is freed at the end of this statement
diff --git a/src/test/ui/issues/auxiliary/issue-75907.rs b/src/test/ui/privacy/auxiliary/issue-75907.rs
index 389c9c351..389c9c351 100644
--- a/src/test/ui/issues/auxiliary/issue-75907.rs
+++ b/src/test/ui/privacy/auxiliary/issue-75907.rs
diff --git a/src/test/ui/privacy/effective_visibilities.rs b/src/test/ui/privacy/effective_visibilities.rs
index 1d806a1d1..ff20e20d3 100644
--- a/src/test/ui/privacy/effective_visibilities.rs
+++ b/src/test/ui/privacy/effective_visibilities.rs
@@ -6,7 +6,7 @@ mod outer { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub
pub mod inner1 { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
- extern "C" {} //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+ extern "C" {} //~ ERROR not in the table
#[rustc_effective_visibility]
pub trait PubTrait { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
@@ -17,12 +17,13 @@ mod outer { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub
}
#[rustc_effective_visibility]
- struct PrivStruct; //~ ERROR not in the table
+ struct PrivStruct; //~ ERROR Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
+ //~| ERROR Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
#[rustc_effective_visibility]
pub union PubUnion { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
- a: u8, //~ ERROR not in the table
+ a: u8, //~ ERROR Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
#[rustc_effective_visibility]
pub b: u8, //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
}
@@ -31,6 +32,7 @@ mod outer { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub
pub enum Enum { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
A( //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+ //~| ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
PubUnion, //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
),
@@ -38,13 +40,13 @@ mod outer { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub
}
#[rustc_effective_visibility]
- macro_rules! none_macro { //~ Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
+ macro_rules! none_macro { //~ ERROR not in the table
() => {};
}
#[macro_export]
#[rustc_effective_visibility]
- macro_rules! public_macro { //~ Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+ macro_rules! public_macro { //~ ERROR Direct: pub(self), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
() => {};
}
@@ -70,6 +72,5 @@ mod half_public_import {
#[rustc_effective_visibility]
pub use half_public_import::HalfPublicImport; //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- //~^ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
fn main() {}
diff --git a/src/test/ui/privacy/effective_visibilities.stderr b/src/test/ui/privacy/effective_visibilities.stderr
index 1c6201600..046b6095f 100644
--- a/src/test/ui/privacy/effective_visibilities.stderr
+++ b/src/test/ui/privacy/effective_visibilities.stderr
@@ -10,7 +10,7 @@ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImpl
LL | pub mod inner1 {
| ^^^^^^^^^^^^^^
-error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+error: not in the table
--> $DIR/effective_visibilities.rs:9:9
|
LL | extern "C" {}
@@ -22,98 +22,104 @@ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImpl
LL | pub trait PubTrait {
| ^^^^^^^^^^^^^^^^^^
-error: not in the table
+error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
+ --> $DIR/effective_visibilities.rs:20:9
+ |
+LL | struct PrivStruct;
+ | ^^^^^^^^^^^^^^^^^
+
+error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
--> $DIR/effective_visibilities.rs:20:9
|
LL | struct PrivStruct;
| ^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:23:9
+ --> $DIR/effective_visibilities.rs:24:9
|
LL | pub union PubUnion {
| ^^^^^^^^^^^^^^^^^^
-error: not in the table
- --> $DIR/effective_visibilities.rs:25:13
+error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
+ --> $DIR/effective_visibilities.rs:26:13
|
LL | a: u8,
| ^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:27:13
+ --> $DIR/effective_visibilities.rs:28:13
|
LL | pub b: u8,
| ^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:31:9
+ --> $DIR/effective_visibilities.rs:32:9
|
LL | pub enum Enum {
| ^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:33:13
+ --> $DIR/effective_visibilities.rs:34:13
+ |
+LL | A(
+ | ^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+ --> $DIR/effective_visibilities.rs:34:13
|
LL | A(
| ^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:35:17
+ --> $DIR/effective_visibilities.rs:37:17
|
LL | PubUnion,
| ^^^^^^^^
-error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
- --> $DIR/effective_visibilities.rs:41:5
+error: not in the table
+ --> $DIR/effective_visibilities.rs:43:5
|
LL | macro_rules! none_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^
-error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:47:5
+error: Direct: pub(self), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+ --> $DIR/effective_visibilities.rs:49:5
|
LL | macro_rules! public_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:52:5
+ --> $DIR/effective_visibilities.rs:54:5
|
LL | pub struct ReachableStruct {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:54:9
+ --> $DIR/effective_visibilities.rs:56:9
|
LL | pub a: u8,
| ^^^^^^^^^
error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:59:9
+ --> $DIR/effective_visibilities.rs:61:9
|
LL | pub use outer::inner1;
| ^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:65:5
+ --> $DIR/effective_visibilities.rs:67:5
|
LL | pub type HalfPublicImport = u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
- --> $DIR/effective_visibilities.rs:68:5
+ --> $DIR/effective_visibilities.rs:70:5
|
LL | pub(crate) const HalfPublicImport: u8 = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:72:9
- |
-LL | pub use half_public_import::HalfPublicImport;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
- --> $DIR/effective_visibilities.rs:72:9
+ --> $DIR/effective_visibilities.rs:74:9
|
LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -130,5 +136,5 @@ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImpl
LL | type B;
| ^^^^^^
-error: aborting due to 22 previous errors
+error: aborting due to 23 previous errors
diff --git a/src/test/ui/privacy/effective_visibilities_glob.rs b/src/test/ui/privacy/effective_visibilities_glob.rs
new file mode 100644
index 000000000..eb9dcd6cd
--- /dev/null
+++ b/src/test/ui/privacy/effective_visibilities_glob.rs
@@ -0,0 +1,21 @@
+// Effective visibility tracking for imports is fine-grained, so `S2` is not fully exported
+// even if its parent import (`m::*`) is fully exported as a `use` item.
+
+#![feature(rustc_attrs)]
+
+mod m {
+ #[rustc_effective_visibility]
+ pub struct S1 {} //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+ #[rustc_effective_visibility]
+ pub struct S2 {} //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
+}
+
+mod glob {
+ #[rustc_effective_visibility]
+ pub use crate::m::*; //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+}
+
+#[rustc_effective_visibility]
+pub use glob::S1; //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+
+fn main() {}
diff --git a/src/test/ui/privacy/effective_visibilities_glob.stderr b/src/test/ui/privacy/effective_visibilities_glob.stderr
new file mode 100644
index 000000000..0496cd5df
--- /dev/null
+++ b/src/test/ui/privacy/effective_visibilities_glob.stderr
@@ -0,0 +1,26 @@
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+ --> $DIR/effective_visibilities_glob.rs:8:5
+ |
+LL | pub struct S1 {}
+ | ^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
+ --> $DIR/effective_visibilities_glob.rs:10:5
+ |
+LL | pub struct S2 {}
+ | ^^^^^^^^^^^^^
+
+error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+ --> $DIR/effective_visibilities_glob.rs:15:13
+ |
+LL | pub use crate::m::*;
+ | ^^^^^^^^
+
+error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+ --> $DIR/effective_visibilities_glob.rs:19:9
+ |
+LL | pub use glob::S1;
+ | ^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/privacy/effective_visibilities_invariants.rs b/src/test/ui/privacy/effective_visibilities_invariants.rs
new file mode 100644
index 000000000..af5a2bed6
--- /dev/null
+++ b/src/test/ui/privacy/effective_visibilities_invariants.rs
@@ -0,0 +1,12 @@
+// Invariant checking doesn't ICE in some cases with errors (issue #104249).
+
+#![feature(staged_api)] //~ ERROR module has missing stability attribute
+
+pub mod m {} //~ ERROR module has missing stability attribute
+
+pub mod m { //~ ERROR the name `m` is defined multiple times
+ mod inner {}
+ type Inner = u8;
+}
+
+fn main() {}
diff --git a/src/test/ui/privacy/effective_visibilities_invariants.stderr b/src/test/ui/privacy/effective_visibilities_invariants.stderr
new file mode 100644
index 000000000..fd205f405
--- /dev/null
+++ b/src/test/ui/privacy/effective_visibilities_invariants.stderr
@@ -0,0 +1,32 @@
+error[E0428]: the name `m` is defined multiple times
+ --> $DIR/effective_visibilities_invariants.rs:7:1
+ |
+LL | pub mod m {}
+ | --------- previous definition of the module `m` here
+LL |
+LL | pub mod m {
+ | ^^^^^^^^^ `m` redefined here
+ |
+ = note: `m` must be defined only once in the type namespace of this module
+
+error: module has missing stability attribute
+ --> $DIR/effective_visibilities_invariants.rs:3:1
+ |
+LL | / #![feature(staged_api)]
+LL | |
+LL | | pub mod m {}
+LL | |
+... |
+LL | |
+LL | | fn main() {}
+ | |____________^
+
+error: module has missing stability attribute
+ --> $DIR/effective_visibilities_invariants.rs:5:1
+ |
+LL | pub mod m {}
+ | ^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0428`.
diff --git a/src/test/ui/issues/issue-75906.rs b/src/test/ui/privacy/issue-75906.rs
index 710039d79..710039d79 100644
--- a/src/test/ui/issues/issue-75906.rs
+++ b/src/test/ui/privacy/issue-75906.rs
diff --git a/src/test/ui/issues/issue-75906.stderr b/src/test/ui/privacy/issue-75906.stderr
index 4c6a68646..4c6a68646 100644
--- a/src/test/ui/issues/issue-75906.stderr
+++ b/src/test/ui/privacy/issue-75906.stderr
diff --git a/src/test/ui/issues/issue-75907.rs b/src/test/ui/privacy/issue-75907.rs
index 6da99cf64..6da99cf64 100644
--- a/src/test/ui/issues/issue-75907.rs
+++ b/src/test/ui/privacy/issue-75907.rs
diff --git a/src/test/ui/issues/issue-75907.stderr b/src/test/ui/privacy/issue-75907.stderr
index 2f89e31a3..2f89e31a3 100644
--- a/src/test/ui/issues/issue-75907.stderr
+++ b/src/test/ui/privacy/issue-75907.stderr
diff --git a/src/test/ui/issues/issue-75907_b.rs b/src/test/ui/privacy/issue-75907_b.rs
index fdfc5907c..fdfc5907c 100644
--- a/src/test/ui/issues/issue-75907_b.rs
+++ b/src/test/ui/privacy/issue-75907_b.rs
diff --git a/src/test/ui/issues/issue-75907_b.stderr b/src/test/ui/privacy/issue-75907_b.stderr
index b82d08473..b82d08473 100644
--- a/src/test/ui/issues/issue-75907_b.stderr
+++ b/src/test/ui/privacy/issue-75907_b.stderr
diff --git a/src/test/ui/proc-macro/amputate-span.stderr b/src/test/ui/proc-macro/amputate-span.stderr
index 9553ba3da..ab4670411 100644
--- a/src/test/ui/proc-macro/amputate-span.stderr
+++ b/src/test/ui/proc-macro/amputate-span.stderr
@@ -2,7 +2,7 @@ error[E0433]: failed to resolve: use of undeclared type `Command`
--> $DIR/amputate-span.rs:49:5
|
LL | Command::new("git");
- | ^^^^^^^ not found in this scope
+ | ^^^^^^^ use of undeclared type `Command`
|
help: consider importing this struct
|
@@ -13,7 +13,7 @@ error[E0433]: failed to resolve: use of undeclared type `Command`
--> $DIR/amputate-span.rs:63:9
|
LL | Command::new("git");
- | ^^^^^^^ not found in this scope
+ | ^^^^^^^ use of undeclared type `Command`
|
help: consider importing this struct
|
diff --git a/src/test/ui/proc-macro/auxiliary/issue-104884.rs b/src/test/ui/proc-macro/auxiliary/issue-104884.rs
new file mode 100644
index 000000000..0de59d005
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/issue-104884.rs
@@ -0,0 +1,23 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(AddImpl)]
+
+pub fn derive(input: TokenStream) -> TokenStream {
+ "use std::cmp::Ordering;
+
+ impl<T> Ord for PriorityQueue<T> {
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.0.cmp(&self.height)
+ }
+ }
+ "
+ .parse()
+ .unwrap()
+}
diff --git a/src/test/ui/proc-macro/expand-expr.rs b/src/test/ui/proc-macro/expand-expr.rs
index d1146d970..901b3a951 100644
--- a/src/test/ui/proc-macro/expand-expr.rs
+++ b/src/test/ui/proc-macro/expand-expr.rs
@@ -1,5 +1,5 @@
// aux-build:expand-expr.rs
-
+#![feature(concat_bytes)]
extern crate expand_expr;
use expand_expr::{
@@ -23,6 +23,11 @@ expand_expr_is!(
concat!("contents: ", include_str!("auxiliary/included-file.txt"))
);
+expand_expr_is!(
+ b"contents: Included file contents\n",
+ concat_bytes!(b"contents: ", include_bytes!("auxiliary/included-file.txt"))
+);
+
// Correct value is checked for multiple sources.
check_expand_expr_file!(file!());
@@ -118,4 +123,10 @@ expand_expr_fail!(echo_pm!(arbitrary_expression() + "etc"));
const _: u32 = recursive_expand!(); //~ ERROR: recursion limit reached while expanding `recursive_expand!`
-fn main() {}
+fn main() {
+ // https://github.com/rust-lang/rust/issues/104414
+ match b"Included file contents\n" {
+ include_bytes!("auxiliary/included-file.txt") => (),
+ _ => panic!("include_bytes! in pattern"),
+ }
+}
diff --git a/src/test/ui/proc-macro/expand-expr.stderr b/src/test/ui/proc-macro/expand-expr.stderr
index 8dc2d0cfc..c6c4695fd 100644
--- a/src/test/ui/proc-macro/expand-expr.stderr
+++ b/src/test/ui/proc-macro/expand-expr.stderr
@@ -1,29 +1,29 @@
error: expected one of `.`, `?`, or an operator, found `;`
- --> $DIR/expand-expr.rs:101:27
+ --> $DIR/expand-expr.rs:106:27
|
LL | expand_expr_fail!("string"; hello);
| ^ expected one of `.`, `?`, or an operator
error: expected expression, found `$`
- --> $DIR/expand-expr.rs:104:19
+ --> $DIR/expand-expr.rs:109:19
|
LL | expand_expr_fail!($);
| ^ expected expression
error: expected expression, found `$`
- --> $DIR/expand-expr.rs:33:23
+ --> $DIR/expand-expr.rs:38:23
|
LL | ($($t:tt)*) => { $($t)* };
| ^^^^ expected expression
error: expected expression, found `$`
- --> $DIR/expand-expr.rs:106:28
+ --> $DIR/expand-expr.rs:111:28
|
LL | expand_expr_fail!(echo_pm!($));
| ^ expected expression
error: macro expansion ignores token `hello` and any following
- --> $DIR/expand-expr.rs:110:47
+ --> $DIR/expand-expr.rs:115:47
|
LL | expand_expr_is!("string", echo_tts!("string"; hello));
| --------------------^^^^^-- help: you might be missing a semicolon here: `;`
@@ -33,7 +33,7 @@ LL | expand_expr_is!("string", echo_tts!("string"; hello));
= note: the usage of `echo_tts!` is likely invalid in expression context
error: macro expansion ignores token `;` and any following
- --> $DIR/expand-expr.rs:111:44
+ --> $DIR/expand-expr.rs:116:44
|
LL | expand_expr_is!("string", echo_pm!("string"; hello));
| -----------------^-------- help: you might be missing a semicolon here: `;`
@@ -43,7 +43,7 @@ LL | expand_expr_is!("string", echo_pm!("string"; hello));
= note: the usage of `echo_pm!` is likely invalid in expression context
error: recursion limit reached while expanding `recursive_expand!`
- --> $DIR/expand-expr.rs:119:16
+ --> $DIR/expand-expr.rs:124:16
|
LL | const _: u32 = recursive_expand!();
| ^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs b/src/test/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs
new file mode 100644
index 000000000..a0d619c45
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs
@@ -0,0 +1,20 @@
+// aux-build:issue-104884.rs
+
+use std::collections::BinaryHeap;
+
+#[macro_use]
+extern crate issue_104884;
+
+#[derive(PartialEq, Eq, PartialOrd, Ord)]
+struct PriorityQueueEntry<T> {
+ value: T,
+}
+
+#[derive(PartialOrd, AddImpl)]
+//~^ ERROR can't compare `PriorityQueue<T>` with `PriorityQueue<T>`
+//~| ERROR the trait bound `PriorityQueue<T>: Eq` is not satisfied
+//~| ERROR can't compare `T` with `T`
+
+struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>);
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/src/test/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr
new file mode 100644
index 000000000..ac49e04e3
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr
@@ -0,0 +1,48 @@
+error[E0277]: can't compare `PriorityQueue<T>` with `PriorityQueue<T>`
+ --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:10
+ |
+LL | #[derive(PartialOrd, AddImpl)]
+ | ^^^^^^^^^^ no implementation for `PriorityQueue<T> == PriorityQueue<T>`
+ |
+ = help: the trait `PartialEq` is not implemented for `PriorityQueue<T>`
+note: required by a bound in `PartialOrd`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ | ^^^^^^^^^^^^^^ required by this bound in `PartialOrd`
+ = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: the trait bound `PriorityQueue<T>: Eq` is not satisfied
+ --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22
+ |
+LL | #[derive(PartialOrd, AddImpl)]
+ | ^^^^^^^ the trait `Eq` is not implemented for `PriorityQueue<T>`
+ |
+note: required by a bound in `Ord`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | pub trait Ord: Eq + PartialOrd<Self> {
+ | ^^ required by this bound in `Ord`
+ = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: can't compare `T` with `T`
+ --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22
+ |
+LL | #[derive(PartialOrd, AddImpl)]
+ | ^^^^^^^ no implementation for `T < T` and `T > T`
+ |
+note: required for `PriorityQueue<T>` to implement `PartialOrd`
+ --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:10
+ |
+LL | #[derive(PartialOrd, AddImpl)]
+ | ^^^^^^^^^^
+note: required by a bound in `Ord`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | pub trait Ord: Eq + PartialOrd<Self> {
+ | ^^^^^^^^^^^^^^^^ required by this bound in `Ord`
+ = note: this error originates in the derive macro `AddImpl` which comes from the expansion of the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/qualified/qualified-path-params.stderr b/src/test/ui/qualified/qualified-path-params.stderr
index 82cc6e19f..a49ed6c8f 100644
--- a/src/test/ui/qualified/qualified-path-params.stderr
+++ b/src/test/ui/qualified/qualified-path-params.stderr
@@ -2,7 +2,7 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f
--> $DIR/qualified-path-params.rs:20:9
|
LL | <S as Tr>::A::f::<u8> => {}
- | ^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
error[E0029]: only `char` and numeric types are allowed in range patterns
--> $DIR/qualified-path-params.rs:22:15
diff --git a/src/test/ui/query-system/fn-sig-cycle-arity.rs b/src/test/ui/query-system/fn-sig-cycle-arity.rs
new file mode 100644
index 000000000..7a9b8469c
--- /dev/null
+++ b/src/test/ui/query-system/fn-sig-cycle-arity.rs
@@ -0,0 +1,8 @@
+trait Dancer {
+ fn dance(&self) -> _ {
+ //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
+ self.dance()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/query-system/fn-sig-cycle-arity.stderr b/src/test/ui/query-system/fn-sig-cycle-arity.stderr
new file mode 100644
index 000000000..67e0c2545
--- /dev/null
+++ b/src/test/ui/query-system/fn-sig-cycle-arity.stderr
@@ -0,0 +1,9 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+ --> $DIR/fn-sig-cycle-arity.rs:2:24
+ |
+LL | fn dance(&self) -> _ {
+ | ^ not allowed in type signatures
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/range/issue-54505-no-std.rs b/src/test/ui/range/issue-54505-no-std.rs
index ab1a025b5..9f378b483 100644
--- a/src/test/ui/range/issue-54505-no-std.rs
+++ b/src/test/ui/range/issue-54505-no-std.rs
@@ -1,5 +1,3 @@
-// error-pattern: `#[panic_handler]` function required, but not found
-
// Regression test for #54505 - range borrowing suggestion had
// incorrect syntax (missing parentheses).
@@ -18,6 +16,10 @@ extern "C" fn eh_personality() {}
#[lang = "eh_catch_typeinfo"]
static EH_CATCH_TYPEINFO: u8 = 0;
+#[panic_handler]
+fn panic_handler() {}
+//~^ ERROR return type should be `!`
+//~| ERROR function should have one argument
// take a reference to any built-in range
fn take_range(_r: &impl RangeBounds<i8>) {}
diff --git a/src/test/ui/range/issue-54505-no-std.stderr b/src/test/ui/range/issue-54505-no-std.stderr
index c4e36b0b1..9fb0e54a8 100644
--- a/src/test/ui/range/issue-54505-no-std.stderr
+++ b/src/test/ui/range/issue-54505-no-std.stderr
@@ -1,7 +1,17 @@
-error: `#[panic_handler]` function required, but not found
+error: return type should be `!`
+ --> $DIR/issue-54505-no-std.rs:20:20
+ |
+LL | fn panic_handler() {}
+ | ^
+
+error: function should have one argument
+ --> $DIR/issue-54505-no-std.rs:20:1
+ |
+LL | fn panic_handler() {}
+ | ^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:27:16
+ --> $DIR/issue-54505-no-std.rs:29:16
|
LL | take_range(0..1);
| ---------- ^^^^
@@ -13,13 +23,13 @@ LL | take_range(0..1);
= note: expected reference `&_`
found struct `Range<{integer}>`
note: function defined here
- --> $DIR/issue-54505-no-std.rs:23:4
+ --> $DIR/issue-54505-no-std.rs:25:4
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:32:16
+ --> $DIR/issue-54505-no-std.rs:34:16
|
LL | take_range(1..);
| ---------- ^^^
@@ -31,13 +41,13 @@ LL | take_range(1..);
= note: expected reference `&_`
found struct `RangeFrom<{integer}>`
note: function defined here
- --> $DIR/issue-54505-no-std.rs:23:4
+ --> $DIR/issue-54505-no-std.rs:25:4
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:37:16
+ --> $DIR/issue-54505-no-std.rs:39:16
|
LL | take_range(..);
| ---------- ^^
@@ -49,13 +59,13 @@ LL | take_range(..);
= note: expected reference `&_`
found struct `RangeFull`
note: function defined here
- --> $DIR/issue-54505-no-std.rs:23:4
+ --> $DIR/issue-54505-no-std.rs:25:4
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:42:16
+ --> $DIR/issue-54505-no-std.rs:44:16
|
LL | take_range(0..=1);
| ---------- ^^^^^
@@ -67,13 +77,13 @@ LL | take_range(0..=1);
= note: expected reference `&_`
found struct `RangeInclusive<{integer}>`
note: function defined here
- --> $DIR/issue-54505-no-std.rs:23:4
+ --> $DIR/issue-54505-no-std.rs:25:4
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:47:16
+ --> $DIR/issue-54505-no-std.rs:49:16
|
LL | take_range(..5);
| ---------- ^^^
@@ -85,13 +95,13 @@ LL | take_range(..5);
= note: expected reference `&_`
found struct `RangeTo<{integer}>`
note: function defined here
- --> $DIR/issue-54505-no-std.rs:23:4
+ --> $DIR/issue-54505-no-std.rs:25:4
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
error[E0308]: mismatched types
- --> $DIR/issue-54505-no-std.rs:52:16
+ --> $DIR/issue-54505-no-std.rs:54:16
|
LL | take_range(..=42);
| ---------- ^^^^^
@@ -103,11 +113,11 @@ LL | take_range(..=42);
= note: expected reference `&_`
found struct `RangeToInclusive<{integer}>`
note: function defined here
- --> $DIR/issue-54505-no-std.rs:23:4
+ --> $DIR/issue-54505-no-std.rs:25:4
|
LL | fn take_range(_r: &impl RangeBounds<i8>) {}
| ^^^^^^^^^^ -------------------------
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/raw-ref-op/raw-ref-temp-deref.rs b/src/test/ui/raw-ref-op/raw-ref-temp-deref.rs
index a814003ae..2e075a1b9 100644
--- a/src/test/ui/raw-ref-op/raw-ref-temp-deref.rs
+++ b/src/test/ui/raw-ref-op/raw-ref-temp-deref.rs
@@ -18,7 +18,7 @@ fn main() {
let index_deref_ref = &raw const SLICE_REF[1];
let x = 0;
- let ascribe_ref = &raw const (x: i32);
- let ascribe_deref = &raw const (*ARRAY_REF: [i32; 2]);
- let ascribe_index_deref = &raw const (ARRAY_REF[0]: i32);
+ let ascribe_ref = &raw const type_ascribe!(x, i32);
+ let ascribe_deref = &raw const type_ascribe!(*ARRAY_REF, [i32; 2]);
+ let ascribe_index_deref = &raw const type_ascribe!(ARRAY_REF[0], i32);
}
diff --git a/src/test/ui/raw-ref-op/raw-ref-temp.rs b/src/test/ui/raw-ref-op/raw-ref-temp.rs
index 32df56468..10e47cb34 100644
--- a/src/test/ui/raw-ref-op/raw-ref-temp.rs
+++ b/src/test/ui/raw-ref-op/raw-ref-temp.rs
@@ -8,24 +8,24 @@ const PAIR: (i32, i64) = (1, 2);
const ARRAY: [i32; 2] = [1, 2];
fn main() {
- let ref_expr = &raw const 2; //~ ERROR cannot take address
- let mut_ref_expr = &raw mut 3; //~ ERROR cannot take address
- let ref_const = &raw const FOUR; //~ ERROR cannot take address
- let mut_ref_const = &raw mut FOUR; //~ ERROR cannot take address
-
- let field_ref_expr = &raw const (1, 2).0; //~ ERROR cannot take address
- let mut_field_ref_expr = &raw mut (1, 2).0; //~ ERROR cannot take address
- let field_ref = &raw const PAIR.0; //~ ERROR cannot take address
- let mut_field_ref = &raw mut PAIR.0; //~ ERROR cannot take address
-
- let index_ref_expr = &raw const [1, 2][0]; //~ ERROR cannot take address
- let mut_index_ref_expr = &raw mut [1, 2][0]; //~ ERROR cannot take address
- let index_ref = &raw const ARRAY[0]; //~ ERROR cannot take address
- let mut_index_ref = &raw mut ARRAY[1]; //~ ERROR cannot take address
-
- let ref_ascribe = &raw const (2: i32); //~ ERROR cannot take address
- let mut_ref_ascribe = &raw mut (3: i32); //~ ERROR cannot take address
-
- let ascribe_field_ref = &raw const (PAIR.0: i32); //~ ERROR cannot take address
- let ascribe_index_ref = &raw mut (ARRAY[0]: i32); //~ ERROR cannot take address
+ let ref_expr = &raw const 2; //~ ERROR cannot take address
+ let mut_ref_expr = &raw mut 3; //~ ERROR cannot take address
+ let ref_const = &raw const FOUR; //~ ERROR cannot take address
+ let mut_ref_const = &raw mut FOUR; //~ ERROR cannot take address
+
+ let field_ref_expr = &raw const (1, 2).0; //~ ERROR cannot take address
+ let mut_field_ref_expr = &raw mut (1, 2).0; //~ ERROR cannot take address
+ let field_ref = &raw const PAIR.0; //~ ERROR cannot take address
+ let mut_field_ref = &raw mut PAIR.0; //~ ERROR cannot take address
+
+ let index_ref_expr = &raw const [1, 2][0]; //~ ERROR cannot take address
+ let mut_index_ref_expr = &raw mut [1, 2][0]; //~ ERROR cannot take address
+ let index_ref = &raw const ARRAY[0]; //~ ERROR cannot take address
+ let mut_index_ref = &raw mut ARRAY[1]; //~ ERROR cannot take address
+
+ let ref_ascribe = &raw const type_ascribe!(2, i32); //~ ERROR cannot take address
+ let mut_ref_ascribe = &raw mut type_ascribe!(3, i32); //~ ERROR cannot take address
+
+ let ascribe_field_ref = &raw const type_ascribe!(PAIR.0, i32); //~ ERROR cannot take address
+ let ascribe_index_ref = &raw mut type_ascribe!(ARRAY[0], i32); //~ ERROR cannot take address
}
diff --git a/src/test/ui/raw-ref-op/raw-ref-temp.stderr b/src/test/ui/raw-ref-op/raw-ref-temp.stderr
index 80dea76d5..b96661625 100644
--- a/src/test/ui/raw-ref-op/raw-ref-temp.stderr
+++ b/src/test/ui/raw-ref-op/raw-ref-temp.stderr
@@ -73,26 +73,26 @@ LL | let mut_index_ref = &raw mut ARRAY[1];
error[E0745]: cannot take address of a temporary
--> $DIR/raw-ref-temp.rs:26:34
|
-LL | let ref_ascribe = &raw const (2: i32);
- | ^^^^^^^^ temporary value
+LL | let ref_ascribe = &raw const type_ascribe!(2, i32);
+ | ^^^^^^^^^^^^^^^^^^^^^ temporary value
error[E0745]: cannot take address of a temporary
--> $DIR/raw-ref-temp.rs:27:36
|
-LL | let mut_ref_ascribe = &raw mut (3: i32);
- | ^^^^^^^^ temporary value
+LL | let mut_ref_ascribe = &raw mut type_ascribe!(3, i32);
+ | ^^^^^^^^^^^^^^^^^^^^^ temporary value
error[E0745]: cannot take address of a temporary
--> $DIR/raw-ref-temp.rs:29:40
|
-LL | let ascribe_field_ref = &raw const (PAIR.0: i32);
- | ^^^^^^^^^^^^^ temporary value
+LL | let ascribe_field_ref = &raw const type_ascribe!(PAIR.0, i32);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value
error[E0745]: cannot take address of a temporary
--> $DIR/raw-ref-temp.rs:30:38
|
-LL | let ascribe_index_ref = &raw mut (ARRAY[0]: i32);
- | ^^^^^^^^^^^^^^^ temporary value
+LL | let ascribe_index_ref = &raw mut type_ascribe!(ARRAY[0], i32);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value
error: aborting due to 16 previous errors
diff --git a/src/test/ui/reachable/expr_type.rs b/src/test/ui/reachable/expr_type.rs
index 8d32397b5..1ceb2f859 100644
--- a/src/test/ui/reachable/expr_type.rs
+++ b/src/test/ui/reachable/expr_type.rs
@@ -6,7 +6,7 @@
fn a() {
// the cast is unreachable:
- let x = {return}: !; //~ ERROR unreachable
+ let x = type_ascribe!({return}, !); //~ ERROR unreachable
}
fn main() { }
diff --git a/src/test/ui/reachable/expr_type.stderr b/src/test/ui/reachable/expr_type.stderr
index c56c64be7..3cb4a32e0 100644
--- a/src/test/ui/reachable/expr_type.stderr
+++ b/src/test/ui/reachable/expr_type.stderr
@@ -1,10 +1,10 @@
error: unreachable expression
--> $DIR/expr_type.rs:9:13
|
-LL | let x = {return}: !;
- | ^------^^^^
- | ||
- | |any code following this expression is unreachable
+LL | let x = type_ascribe!({return}, !);
+ | ^^^^^^^^^^^^^^^------^^^^^
+ | | |
+ | | any code following this expression is unreachable
| unreachable expression
|
note: the lint level is defined here
diff --git a/src/test/ui/recursion/issue-83150.rs b/src/test/ui/recursion/issue-83150.rs
index e647f0ff4..38353d161 100644
--- a/src/test/ui/recursion/issue-83150.rs
+++ b/src/test/ui/recursion/issue-83150.rs
@@ -1,6 +1,7 @@
// build-fail
// compile-flags: -Copt-level=0
-//~^^ ERROR overflow evaluating the requirement
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
+//~^^^ ERROR overflow evaluating the requirement
fn main() {
let mut iter = 0u8..1;
diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr
index 3e0229717..dde8ad1b6 100644
--- a/src/test/ui/recursion/issue-83150.stderr
+++ b/src/test/ui/recursion/issue-83150.stderr
@@ -1,5 +1,5 @@
warning: function cannot return without recursing
- --> $DIR/issue-83150.rs:10:1
+ --> $DIR/issue-83150.rs:11:1
|
LL | fn func<T: Iterator<Item = u8>>(iter: &mut T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -9,10 +9,11 @@ LL | func(&mut iter.map(|x| x + 1))
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default
-error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>: Iterator`
+error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>, ...>: Iterator`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
- = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
+ = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>, ...>, ...>, ...>, ...>` to implement `Iterator`
+ = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-83150/issue-83150.long-type-hash.txt'
error: aborting due to previous error; 1 warning emitted
diff --git a/src/test/ui/recursion/recursion.stderr b/src/test/ui/recursion/recursion.stderr
index d2844d0e6..cf0809537 100644
--- a/src/test/ui/recursion/recursion.stderr
+++ b/src/test/ui/recursion/recursion.stderr
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
+error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>`
--> $DIR/recursion.rs:18:11
|
LL | _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}
diff --git a/src/test/ui/regions/issue-102374.rs b/src/test/ui/regions/issue-102374.rs
index e0a116421..fd71248d9 100644
--- a/src/test/ui/regions/issue-102374.rs
+++ b/src/test/ui/regions/issue-102374.rs
@@ -1,3 +1,4 @@
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
use std::cell::Cell;
#[rustfmt::skip]
diff --git a/src/test/ui/regions/issue-102374.stderr b/src/test/ui/regions/issue-102374.stderr
index 31b855c36..157850693 100644
--- a/src/test/ui/regions/issue-102374.stderr
+++ b/src/test/ui/regions/issue-102374.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/issue-102374.rs:16:5
+ --> $DIR/issue-102374.rs:17:5
|
LL | ) -> i32 {
| --- expected `i32` because of return type
@@ -7,7 +7,8 @@ LL | f
| ^ expected `i32`, found fn pointer
|
= note: expected type `i32`
- found fn pointer `for<'z1, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'z0> fn(Cell<(&'z1 i32, &'a i32, &'b i32, &'c i32, &'d i32, &'e i32, &'f i32, &'g i32, &'h i32, &'i i32, &'j i32, &'k i32, &'l i32, &'m i32, &'n i32, &'o i32, &'p i32, &'q i32, &'r i32, &'s i32, &'t i32, &'u i32, &'v i32, &'w i32, &'x i32, &'y i32, &'z i32, &'z0 i32)>)`
+ found fn pointer `for<'z1, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'z0> fn(Cell<...>)`
+ the full type name has been written to '$TEST_BUILD_DIR/regions/issue-102374/issue-102374.long-type-hash.txt'
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-11612.rs b/src/test/ui/regions/issue-11612.rs
index 9f7f1cc6f..9f7f1cc6f 100644
--- a/src/test/ui/issues/issue-11612.rs
+++ b/src/test/ui/regions/issue-11612.rs
diff --git a/src/test/ui/regions/regions-free-region-ordering-caller1.stderr b/src/test/ui/regions/regions-free-region-ordering-caller1.stderr
index 8042b1740..8ef7e2253 100644
--- a/src/test/ui/regions/regions-free-region-ordering-caller1.stderr
+++ b/src/test/ui/regions/regions-free-region-ordering-caller1.stderr
@@ -5,7 +5,7 @@ LL | fn call1<'a>(x: &'a usize) {
| -- lifetime `'a` defined here
...
LL | let z: &'a & usize = &(&y);
- | ----------- ^^^^ creates a temporary which is freed while still in use
+ | ----------- ^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'a`
...
diff --git a/src/test/ui/regions/regions-var-type-out-of-scope.stderr b/src/test/ui/regions/regions-var-type-out-of-scope.stderr
index 476e82f04..c32bbe0ee 100644
--- a/src/test/ui/regions/regions-var-type-out-of-scope.stderr
+++ b/src/test/ui/regions/regions-var-type-out-of-scope.stderr
@@ -4,7 +4,7 @@ error[E0716]: temporary value dropped while borrowed
LL | x = &id(3);
| ^^^^^- temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
LL | assert_eq!(*x, 3);
| ----------------- borrow later used here
|
diff --git a/src/test/ui/align-with-extern-c-fn.rs b/src/test/ui/repr/align-with-extern-c-fn.rs
index 9e490e27a..9e490e27a 100644
--- a/src/test/ui/align-with-extern-c-fn.rs
+++ b/src/test/ui/repr/align-with-extern-c-fn.rs
diff --git a/src/test/ui/aligned_enum_cast.rs b/src/test/ui/repr/aligned_enum_cast.rs
index 1ddf12717..1ddf12717 100644
--- a/src/test/ui/aligned_enum_cast.rs
+++ b/src/test/ui/repr/aligned_enum_cast.rs
diff --git a/src/test/ui/repr_c_int_align.rs b/src/test/ui/repr/repr_c_int_align.rs
index fdd14fc2d..fdd14fc2d 100644
--- a/src/test/ui/repr_c_int_align.rs
+++ b/src/test/ui/repr/repr_c_int_align.rs
diff --git a/src/test/ui/resolve/bad-module.stderr b/src/test/ui/resolve/bad-module.stderr
index 581a66198..558760c67 100644
--- a/src/test/ui/resolve/bad-module.stderr
+++ b/src/test/ui/resolve/bad-module.stderr
@@ -1,15 +1,15 @@
-error[E0433]: failed to resolve: use of undeclared crate or module `thing`
- --> $DIR/bad-module.rs:2:15
- |
-LL | let foo = thing::len(Vec::new());
- | ^^^^^ use of undeclared crate or module `thing`
-
error[E0433]: failed to resolve: use of undeclared crate or module `foo`
--> $DIR/bad-module.rs:5:15
|
LL | let foo = foo::bar::baz();
| ^^^ use of undeclared crate or module `foo`
+error[E0433]: failed to resolve: use of undeclared crate or module `thing`
+ --> $DIR/bad-module.rs:2:15
+ |
+LL | let foo = thing::len(Vec::new());
+ | ^^^^^ use of undeclared crate or module `thing`
+
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/blind-item-local-shadow.rs b/src/test/ui/resolve/blind-item-local-shadow.rs
index 942aeb6fd..942aeb6fd 100644
--- a/src/test/ui/blind-item-local-shadow.rs
+++ b/src/test/ui/resolve/blind-item-local-shadow.rs
diff --git a/src/test/ui/resolve/issue-101749-2.rs b/src/test/ui/resolve/issue-101749-2.rs
new file mode 100644
index 000000000..4d3d46944
--- /dev/null
+++ b/src/test/ui/resolve/issue-101749-2.rs
@@ -0,0 +1,16 @@
+struct Rectangle {
+ width: i32,
+ height: i32,
+}
+impl Rectangle {
+ fn new(width: i32, height: i32) -> Self {
+ Self { width, height }
+ }
+}
+
+fn main() {
+ let rect = Rectangle::new(3, 4);
+ // `area` is not implemented for `Rectangle`, so this should not suggest
+ let _ = rect::area();
+ //~^ ERROR failed to resolve: use of undeclared crate or module `rect`
+}
diff --git a/src/test/ui/resolve/issue-101749-2.stderr b/src/test/ui/resolve/issue-101749-2.stderr
new file mode 100644
index 000000000..370d4b145
--- /dev/null
+++ b/src/test/ui/resolve/issue-101749-2.stderr
@@ -0,0 +1,9 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `rect`
+ --> $DIR/issue-101749-2.rs:14:13
+ |
+LL | let _ = rect::area();
+ | ^^^^ use of undeclared crate or module `rect`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/resolve/issue-101749.fixed b/src/test/ui/resolve/issue-101749.fixed
new file mode 100644
index 000000000..3e5544296
--- /dev/null
+++ b/src/test/ui/resolve/issue-101749.fixed
@@ -0,0 +1,19 @@
+// run-rustfix
+struct Rectangle {
+ width: i32,
+ height: i32,
+}
+impl Rectangle {
+ fn new(width: i32, height: i32) -> Self {
+ Self { width, height }
+ }
+ fn area(&self) -> i32 {
+ self.height * self.width
+ }
+}
+
+fn main() {
+ let rect = Rectangle::new(3, 4);
+ let _ = rect.area();
+ //~^ ERROR failed to resolve: use of undeclared crate or module `rect`
+}
diff --git a/src/test/ui/resolve/issue-101749.rs b/src/test/ui/resolve/issue-101749.rs
new file mode 100644
index 000000000..fd67ccab6
--- /dev/null
+++ b/src/test/ui/resolve/issue-101749.rs
@@ -0,0 +1,19 @@
+// run-rustfix
+struct Rectangle {
+ width: i32,
+ height: i32,
+}
+impl Rectangle {
+ fn new(width: i32, height: i32) -> Self {
+ Self { width, height }
+ }
+ fn area(&self) -> i32 {
+ self.height * self.width
+ }
+}
+
+fn main() {
+ let rect = Rectangle::new(3, 4);
+ let _ = rect::area();
+ //~^ ERROR failed to resolve: use of undeclared crate or module `rect`
+}
diff --git a/src/test/ui/resolve/issue-101749.stderr b/src/test/ui/resolve/issue-101749.stderr
new file mode 100644
index 000000000..dd29d7fc0
--- /dev/null
+++ b/src/test/ui/resolve/issue-101749.stderr
@@ -0,0 +1,14 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `rect`
+ --> $DIR/issue-101749.rs:17:13
+ |
+LL | let _ = rect::area();
+ | ^^^^ use of undeclared crate or module `rect`
+ |
+help: you may have meant to call an instance method
+ |
+LL | let _ = rect.area();
+ | ~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/resolve/issue-103474.rs b/src/test/ui/resolve/issue-103474.rs
new file mode 100644
index 000000000..14f2259e1
--- /dev/null
+++ b/src/test/ui/resolve/issue-103474.rs
@@ -0,0 +1,28 @@
+struct S {}
+impl S {
+ fn first(&self) {}
+
+ fn second(&self) {
+ first()
+ //~^ ERROR cannot find function `first` in this scope
+ }
+
+ fn third(&self) {
+ no_method_err()
+ //~^ ERROR cannot find function `no_method_err` in this scope
+ }
+}
+
+// https://github.com/rust-lang/rust/pull/103531#discussion_r1004728080
+struct Foo {
+ i: i32,
+}
+
+impl Foo {
+ fn needs_self() {
+ this.i
+ //~^ ERROR cannot find value `this` in this scope
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-103474.stderr b/src/test/ui/resolve/issue-103474.stderr
new file mode 100644
index 000000000..415d23155
--- /dev/null
+++ b/src/test/ui/resolve/issue-103474.stderr
@@ -0,0 +1,35 @@
+error[E0425]: cannot find value `this` in this scope
+ --> $DIR/issue-103474.rs:23:9
+ |
+LL | this.i
+ | ^^^^ not found in this scope
+ |
+help: you might have meant to use `self` here instead
+ |
+LL | self.i
+ | ~~~~
+help: if you meant to use `self`, you are also missing a `self` receiver argument
+ |
+LL | fn needs_self(&self) {
+ | +++++
+
+error[E0425]: cannot find function `first` in this scope
+ --> $DIR/issue-103474.rs:6:9
+ |
+LL | first()
+ | ^^^^^ not found in this scope
+ |
+help: consider using the associated function
+ |
+LL | self.first()
+ | +++++
+
+error[E0425]: cannot find function `no_method_err` in this scope
+ --> $DIR/issue-103474.rs:11:9
+ |
+LL | no_method_err()
+ | ^^^^^^^^^^^^^ not found in this scope
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/resolve/issue-105069.rs b/src/test/ui/resolve/issue-105069.rs
new file mode 100644
index 000000000..73455cf77
--- /dev/null
+++ b/src/test/ui/resolve/issue-105069.rs
@@ -0,0 +1,11 @@
+use self::A::*;
+use V; //~ ERROR `V` is ambiguous
+use self::B::*;
+enum A {
+ V
+}
+enum B {
+ V
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-105069.stderr b/src/test/ui/resolve/issue-105069.stderr
new file mode 100644
index 000000000..1e6c9c6e2
--- /dev/null
+++ b/src/test/ui/resolve/issue-105069.stderr
@@ -0,0 +1,21 @@
+error[E0659]: `V` is ambiguous
+ --> $DIR/issue-105069.rs:2:5
+ |
+LL | use V;
+ | ^ ambiguous name
+ |
+ = note: ambiguous because of multiple potential import sources
+note: `V` could refer to the variant imported here
+ --> $DIR/issue-105069.rs:1:5
+ |
+LL | use self::A::*;
+ | ^^^^^^^^^^
+note: `V` could also refer to the variant imported here
+ --> $DIR/issue-105069.rs:3:5
+ |
+LL | use self::B::*;
+ | ^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/resolve/issue-18252.rs b/src/test/ui/resolve/issue-18252.rs
index af0a3cbcb..f6ebe2920 100644
--- a/src/test/ui/resolve/issue-18252.rs
+++ b/src/test/ui/resolve/issue-18252.rs
@@ -4,5 +4,5 @@ enum Foo {
fn main() {
let f = Foo::Variant(42);
- //~^ ERROR expected function, tuple struct or tuple variant, found struct variant `Foo::Variant`
+ //~^ ERROR expected value, found struct variant `Foo::Variant`
}
diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr
index 13e7a5973..d9006c0a6 100644
--- a/src/test/ui/resolve/issue-18252.stderr
+++ b/src/test/ui/resolve/issue-18252.stderr
@@ -1,12 +1,9 @@
-error[E0423]: expected function, tuple struct or tuple variant, found struct variant `Foo::Variant`
+error[E0533]: expected value, found struct variant `Foo::Variant`
--> $DIR/issue-18252.rs:6:13
|
-LL | Variant { x: usize }
- | -------------------- `Foo::Variant` defined here
-...
LL | let f = Foo::Variant(42);
- | ^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `Foo::Variant { x: val }`
+ | ^^^^^^^^^^^^ not a value
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0423`.
+For more information about this error, try `rustc --explain E0533`.
diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr
index 8df84067e..eff89241f 100644
--- a/src/test/ui/resolve/issue-19452.stderr
+++ b/src/test/ui/resolve/issue-19452.stderr
@@ -1,23 +1,15 @@
-error[E0423]: expected value, found struct variant `Homura::Madoka`
+error[E0533]: expected value, found struct variant `Homura::Madoka`
--> $DIR/issue-19452.rs:10:18
|
-LL | Madoka { age: u32 }
- | ------------------- `Homura::Madoka` defined here
-...
LL | let homura = Homura::Madoka;
- | ^^^^^^^^^^^^^^ help: use struct literal syntax instead: `Homura::Madoka { age: val }`
+ | ^^^^^^^^^^^^^^ not a value
-error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka`
+error[E0533]: expected value, found struct variant `issue_19452_aux::Homura::Madoka`
--> $DIR/issue-19452.rs:13:18
|
LL | let homura = issue_19452_aux::Homura::Madoka;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `issue_19452_aux::Homura::Madoka { /* fields */ }`
- |
- ::: $DIR/auxiliary/issue-19452-aux.rs:2:5
- |
-LL | Madoka { age: u32 }
- | ------ `issue_19452_aux::Homura::Madoka` defined here
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a value
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0423`.
+For more information about this error, try `rustc --explain E0533`.
diff --git a/src/test/ui/resolve/issue-2356.stderr b/src/test/ui/resolve/issue-2356.stderr
index e7c53ff44..36f3da7c9 100644
--- a/src/test/ui/resolve/issue-2356.stderr
+++ b/src/test/ui/resolve/issue-2356.stderr
@@ -85,7 +85,7 @@ LL | static_method();
help: consider using the associated function
|
LL | Self::static_method();
- | ~~~~~~~~~~~~~~~~~~~
+ | ++++++
error[E0425]: cannot find function `purr` in this scope
--> $DIR/issue-2356.rs:54:9
@@ -114,7 +114,7 @@ LL | grow_older();
help: consider using the associated function
|
LL | Self::grow_older();
- | ~~~~~~~~~~~~~~~~
+ | ++++++
error[E0425]: cannot find function `shave` in this scope
--> $DIR/issue-2356.rs:74:5
diff --git a/src/test/ui/resolve/issue-24968.stderr b/src/test/ui/resolve/issue-24968.stderr
index 7e539d258..82f5a1d5b 100644
--- a/src/test/ui/resolve/issue-24968.stderr
+++ b/src/test/ui/resolve/issue-24968.stderr
@@ -1,15 +1,3 @@
-error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
- --> $DIR/issue-24968.rs:21:19
- |
-LL | const FOO2: u32 = Self::bar();
- | ^^^^ `Self` is only available in impls, traits, and type definitions
-
-error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
- --> $DIR/issue-24968.rs:27:22
- |
-LL | static FOO_S2: u32 = Self::bar();
- | ^^^^ `Self` is only available in impls, traits, and type definitions
-
error[E0411]: cannot find type `Self` in this scope
--> $DIR/issue-24968.rs:3:11
|
@@ -51,6 +39,18 @@ LL | static FOO_S: Self = 0;
| |
| `Self` not allowed in a static item
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
+ --> $DIR/issue-24968.rs:21:19
+ |
+LL | const FOO2: u32 = Self::bar();
+ | ^^^^ `Self` is only available in impls, traits, and type definitions
+
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
+ --> $DIR/issue-24968.rs:27:22
+ |
+LL | static FOO_S2: u32 = Self::bar();
+ | ^^^^ `Self` is only available in impls, traits, and type definitions
+
error: aborting due to 7 previous errors
Some errors have detailed explanations: E0411, E0433.
diff --git a/src/test/ui/issues/issue-35675.rs b/src/test/ui/resolve/issue-35675.rs
index 683761667..683761667 100644
--- a/src/test/ui/issues/issue-35675.rs
+++ b/src/test/ui/resolve/issue-35675.rs
diff --git a/src/test/ui/issues/issue-35675.stderr b/src/test/ui/resolve/issue-35675.stderr
index 4a06196d5..4a06196d5 100644
--- a/src/test/ui/issues/issue-35675.stderr
+++ b/src/test/ui/resolve/issue-35675.stderr
diff --git a/src/test/ui/resolve/issue-50599.rs b/src/test/ui/resolve/issue-50599.rs
index 78a20cf8e..72238a591 100644
--- a/src/test/ui/resolve/issue-50599.rs
+++ b/src/test/ui/resolve/issue-50599.rs
@@ -2,5 +2,5 @@ fn main() {
const N: u32 = 1_000;
const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value
let mut digits = [0u32; M];
- //~^ ERROR evaluation of constant value failed
+ //~^ constant
}
diff --git a/src/test/ui/resolve/issue-50599.stderr b/src/test/ui/resolve/issue-50599.stderr
index 910deddd8..b07482c83 100644
--- a/src/test/ui/resolve/issue-50599.stderr
+++ b/src/test/ui/resolve/issue-50599.stderr
@@ -16,13 +16,12 @@ LL - const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize;
LL + const M: usize = (f64::from(N) * LOG10_2) as usize;
|
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/issue-50599.rs:4:29
|
LL | let mut digits = [0u32; M];
- | ^ referenced constant has errors
+ | ^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-Some errors have detailed explanations: E0080, E0425.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/issues/issue-5927.rs b/src/test/ui/resolve/issue-5927.rs
index 14f95827b..14f95827b 100644
--- a/src/test/ui/issues/issue-5927.rs
+++ b/src/test/ui/resolve/issue-5927.rs
diff --git a/src/test/ui/issues/issue-5927.stderr b/src/test/ui/resolve/issue-5927.stderr
index d6cd6853d..d6cd6853d 100644
--- a/src/test/ui/issues/issue-5927.stderr
+++ b/src/test/ui/resolve/issue-5927.stderr
diff --git a/src/test/ui/issues/issue-60057.rs b/src/test/ui/resolve/issue-60057.rs
index b52343ada..b52343ada 100644
--- a/src/test/ui/issues/issue-60057.rs
+++ b/src/test/ui/resolve/issue-60057.rs
diff --git a/src/test/ui/issues/issue-60057.stderr b/src/test/ui/resolve/issue-60057.stderr
index 4d915fcd9..4d915fcd9 100644
--- a/src/test/ui/issues/issue-60057.stderr
+++ b/src/test/ui/resolve/issue-60057.stderr
diff --git a/src/test/ui/resolve/issue-73427.stderr b/src/test/ui/resolve/issue-73427.stderr
index d31c5e477..4af5f29d8 100644
--- a/src/test/ui/resolve/issue-73427.stderr
+++ b/src/test/ui/resolve/issue-73427.stderr
@@ -17,16 +17,12 @@ LL | | }
| |_^
help: you might have meant to use one of the following enum variants
|
-LL | (A::Struct {}).foo();
- | ~~~~~~~~~~~~~~
LL | (A::Tuple()).foo();
| ~~~~~~~~~~~~
LL | A::Unit.foo();
| ~~~~~~~
-help: alternatively, the following enum variants are also available
+help: alternatively, the following enum variant is available
|
-LL | (A::StructWithFields { /* fields */ }).foo();
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | (A::TupleWithFields(/* fields */)).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -34,7 +30,7 @@ error[E0423]: expected value, found enum `B`
--> $DIR/issue-73427.rs:35:5
|
LL | B.foo();
- | ^
+ | ^ help: the following enum variant is available: `(B::TupleWithFields(/* fields */))`
|
note: the enum is defined here
--> $DIR/issue-73427.rs:9:1
@@ -44,12 +40,6 @@ LL | | StructWithFields { x: () },
LL | | TupleWithFields(()),
LL | | }
| |_^
-help: the following enum variants are available
- |
-LL | (B::StructWithFields { /* fields */ }).foo();
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LL | (B::TupleWithFields(/* fields */)).foo();
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0423]: expected value, found enum `C`
--> $DIR/issue-73427.rs:37:5
@@ -70,10 +60,8 @@ help: you might have meant to use the following enum variant
|
LL | C::Unit.foo();
| ~~~~~~~
-help: alternatively, the following enum variants are also available
+help: alternatively, the following enum variant is available
|
-LL | (C::StructWithFields { /* fields */ }).foo();
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | (C::TupleWithFields(/* fields */)).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -130,7 +118,7 @@ error[E0532]: expected tuple struct or tuple variant, found enum `A`
LL | if let A(3) = x { }
| ^
|
- = help: you might have meant to match against one of the enum's non-tuple variants
+ = help: you might have meant to match against the enum's non-tuple variant
note: the enum is defined here
--> $DIR/issue-73427.rs:1:1
|
@@ -155,7 +143,7 @@ error[E0423]: expected function, tuple struct or tuple variant, found enum `A`
LL | let x = A(3);
| ^
|
- = help: you might have meant to construct one of the enum's non-tuple variants
+ = help: you might have meant to construct the enum's non-tuple variant
note: the enum is defined here
--> $DIR/issue-73427.rs:1:1
|
diff --git a/src/test/ui/resolve/missing-in-namespace.stderr b/src/test/ui/resolve/missing-in-namespace.stderr
index 3d49b2e5d..fc925ba3b 100644
--- a/src/test/ui/resolve/missing-in-namespace.stderr
+++ b/src/test/ui/resolve/missing-in-namespace.stderr
@@ -1,8 +1,8 @@
error[E0433]: failed to resolve: could not find `hahmap` in `std`
- --> $DIR/missing-in-namespace.rs:2:29
+ --> $DIR/missing-in-namespace.rs:2:21
|
LL | let _map = std::hahmap::HashMap::new();
- | ^^^^^^^ not found in `std::hahmap`
+ | ^^^^^^ could not find `hahmap` in `std`
|
help: consider importing this struct
|
diff --git a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr
index eb26cd9ca..5790e425c 100644
--- a/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr
+++ b/src/test/ui/resolve/point-at-type-parameter-shadowing-another-type.stderr
@@ -1,16 +1,14 @@
error[E0574]: expected struct, variant or union type, found type parameter `Baz`
--> $DIR/point-at-type-parameter-shadowing-another-type.rs:16:13
|
-LL | / struct Baz {
-LL | | num: usize,
-LL | | }
- | |_- you might have meant to refer to this struct
-LL |
-LL | impl<Baz> Foo<Baz> for Bar {
- | --- found this type parameter
+LL | struct Baz {
+ | --- you might have meant to refer to this struct
...
-LL | Baz { num } => num,
- | ^^^ not a struct, variant or union type
+LL | impl<Baz> Foo<Baz> for Bar {
+ | --- found this type parameter
+...
+LL | Baz { num } => num,
+ | ^^^ not a struct, variant or union type
error: aborting due to previous error
diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr
index 82a4211f0..d734fa76b 100644
--- a/src/test/ui/resolve/privacy-enum-ctor.stderr
+++ b/src/test/ui/resolve/privacy-enum-ctor.stderr
@@ -19,12 +19,10 @@ help: you might have meant to use the following enum variant
|
LL | m::Z::Unit;
| ~~~~~~~~~~
-help: alternatively, the following enum variants are also available
+help: alternatively, the following enum variant is available
|
LL | (m::Z::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~~~~
-LL | (m::Z::Struct { /* fields */ });
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0423]: expected value, found enum `Z`
--> $DIR/privacy-enum-ctor.rs:25:9
@@ -47,23 +45,10 @@ help: you might have meant to use the following enum variant
|
LL | m::Z::Unit;
| ~~~~~~~~~~
-help: alternatively, the following enum variants are also available
+help: alternatively, the following enum variant is available
|
LL | (m::Z::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~~~~
-LL | (m::Z::Struct { /* fields */ });
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-error[E0423]: expected value, found struct variant `Z::Struct`
- --> $DIR/privacy-enum-ctor.rs:29:20
- |
-LL | / Struct {
-LL | | s: u8,
-LL | | },
- | |_____________- `Z::Struct` defined here
-...
-LL | let _: Z = Z::Struct;
- | ^^^^^^^^^ help: use struct literal syntax instead: `Z::Struct { s: val }`
error[E0423]: expected value, found enum `m::E`
--> $DIR/privacy-enum-ctor.rs:41:16
@@ -89,12 +74,10 @@ help: you might have meant to use the following enum variant
|
LL | let _: E = E::Unit;
| ~~~~~~~
-help: alternatively, the following enum variants are also available
+help: alternatively, the following enum variant is available
|
LL | let _: E = (E::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~
-LL | let _: E = (E::Struct { /* fields */ });
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: a function with a similar name exists
|
LL | let _: E = m::f;
@@ -111,17 +94,6 @@ LL - let _: E = m::E;
LL + let _: E = E;
|
-error[E0423]: expected value, found struct variant `m::E::Struct`
- --> $DIR/privacy-enum-ctor.rs:45:16
- |
-LL | / Struct {
-LL | | s: u8,
-LL | | },
- | |_________- `m::E::Struct` defined here
-...
-LL | let _: E = m::E::Struct;
- | ^^^^^^^^^^^^ help: use struct literal syntax instead: `m::E::Struct { s: val }`
-
error[E0423]: expected value, found enum `E`
--> $DIR/privacy-enum-ctor.rs:49:16
|
@@ -143,12 +115,10 @@ help: you might have meant to use the following enum variant
|
LL | let _: E = E::Unit;
| ~~~~~~~
-help: alternatively, the following enum variants are also available
+help: alternatively, the following enum variant is available
|
LL | let _: E = (E::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~
-LL | let _: E = (E::Struct { /* fields */ });
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: consider importing one of these items instead
|
LL | use std::f32::consts::E;
@@ -156,17 +126,6 @@ LL | use std::f32::consts::E;
LL | use std::f64::consts::E;
|
-error[E0423]: expected value, found struct variant `E::Struct`
- --> $DIR/privacy-enum-ctor.rs:53:16
- |
-LL | / Struct {
-LL | | s: u8,
-LL | | },
- | |_________- `E::Struct` defined here
-...
-LL | let _: E = E::Struct;
- | ^^^^^^^^^ help: use struct literal syntax instead: `E::Struct { s: val }`
-
error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:57:12
|
@@ -203,12 +162,10 @@ help: you might have meant to use the following enum variant
|
LL | let _: Z = m::Z::Unit;
| ~~~~~~~~~~
-help: alternatively, the following enum variants are also available
+help: alternatively, the following enum variant is available
|
LL | let _: Z = (m::Z::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~~~~
-LL | let _: Z = (m::Z::Struct { /* fields */ });
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:61:12
@@ -240,17 +197,6 @@ note: enum `m::Z` exists but is inaccessible
LL | pub(in m) enum Z {
| ^^^^^^^^^^^^^^^^ not accessible
-error[E0423]: expected value, found struct variant `m::n::Z::Struct`
- --> $DIR/privacy-enum-ctor.rs:64:16
- |
-LL | / Struct {
-LL | | s: u8,
-LL | | },
- | |_____________- `m::n::Z::Struct` defined here
-...
-LL | let _: Z = m::n::Z::Struct;
- | ^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `m::n::Z::Struct { s: val }`
-
error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:68:12
|
@@ -332,6 +278,12 @@ help: use parentheses to construct this tuple variant
LL | let _: Z = Z::Fn(/* u8 */);
| ++++++++++
+error[E0533]: expected value, found struct variant `Z::Struct`
+ --> $DIR/privacy-enum-ctor.rs:29:20
+ |
+LL | let _: Z = Z::Struct;
+ | ^^^^^^^^^ not a value
+
error[E0618]: expected function, found enum variant `Z::Unit`
--> $DIR/privacy-enum-ctor.rs:31:17
|
@@ -367,6 +319,12 @@ help: use parentheses to construct this tuple variant
LL | let _: E = m::E::Fn(/* u8 */);
| ++++++++++
+error[E0533]: expected value, found struct variant `m::E::Struct`
+ --> $DIR/privacy-enum-ctor.rs:45:16
+ |
+LL | let _: E = m::E::Struct;
+ | ^^^^^^^^^^^^ not a value
+
error[E0618]: expected function, found enum variant `m::E::Unit`
--> $DIR/privacy-enum-ctor.rs:47:16
|
@@ -402,6 +360,12 @@ help: use parentheses to construct this tuple variant
LL | let _: E = E::Fn(/* u8 */);
| ++++++++++
+error[E0533]: expected value, found struct variant `E::Struct`
+ --> $DIR/privacy-enum-ctor.rs:53:16
+ |
+LL | let _: E = E::Struct;
+ | ^^^^^^^^^ not a value
+
error[E0618]: expected function, found enum variant `E::Unit`
--> $DIR/privacy-enum-ctor.rs:55:16
|
@@ -419,7 +383,13 @@ LL - let _: E = E::Unit();
LL + let _: E = E::Unit;
|
+error[E0533]: expected value, found struct variant `m::n::Z::Struct`
+ --> $DIR/privacy-enum-ctor.rs:64:16
+ |
+LL | let _: Z = m::n::Z::Struct;
+ | ^^^^^^^^^^^^^^^ not a value
+
error: aborting due to 23 previous errors
-Some errors have detailed explanations: E0308, E0412, E0423, E0603, E0618.
+Some errors have detailed explanations: E0308, E0412, E0423, E0533, E0603, E0618.
For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/resolve/resolve-self-in-impl.stderr b/src/test/ui/resolve/resolve-self-in-impl.stderr
index 9f9ed6889..b3042d413 100644
--- a/src/test/ui/resolve/resolve-self-in-impl.stderr
+++ b/src/test/ui/resolve/resolve-self-in-impl.stderr
@@ -1,40 +1,40 @@
error: `Self` is not valid in the self type of an impl block
- --> $DIR/resolve-self-in-impl.rs:14:13
+ --> $DIR/resolve-self-in-impl.rs:16:6
|
-LL | impl Tr for Self {}
- | ^^^^
+LL | impl Self {}
+ | ^^^^
|
= note: replace `Self` with a different type
error: `Self` is not valid in the self type of an impl block
- --> $DIR/resolve-self-in-impl.rs:15:15
+ --> $DIR/resolve-self-in-impl.rs:17:8
|
-LL | impl Tr for S<Self> {}
- | ^^^^
+LL | impl S<Self> {}
+ | ^^^^
|
= note: replace `Self` with a different type
error: `Self` is not valid in the self type of an impl block
- --> $DIR/resolve-self-in-impl.rs:16:6
+ --> $DIR/resolve-self-in-impl.rs:18:7
|
-LL | impl Self {}
- | ^^^^
+LL | impl (Self, Self) {}
+ | ^^^^ ^^^^
|
= note: replace `Self` with a different type
error: `Self` is not valid in the self type of an impl block
- --> $DIR/resolve-self-in-impl.rs:17:8
+ --> $DIR/resolve-self-in-impl.rs:14:13
|
-LL | impl S<Self> {}
- | ^^^^
+LL | impl Tr for Self {}
+ | ^^^^
|
= note: replace `Self` with a different type
error: `Self` is not valid in the self type of an impl block
- --> $DIR/resolve-self-in-impl.rs:18:7
+ --> $DIR/resolve-self-in-impl.rs:15:15
|
-LL | impl (Self, Self) {}
- | ^^^^ ^^^^
+LL | impl Tr for S<Self> {}
+ | ^^^^
|
= note: replace `Self` with a different type
diff --git a/src/test/ui/resolve/typo-suggestion-mistyped-in-path.rs b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.rs
new file mode 100644
index 000000000..3ce17a14f
--- /dev/null
+++ b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.rs
@@ -0,0 +1,42 @@
+struct Struct;
+//~^ NOTE function or associated item `fob` not found for this struct
+
+impl Struct {
+ fn foo() { }
+}
+
+mod module {
+ fn foo() { }
+
+ struct Struct;
+
+ impl Struct {
+ fn foo() { }
+ }
+}
+
+trait Trait {
+ fn foo();
+}
+
+fn main() {
+ Struct::fob();
+ //~^ ERROR no function or associated item named `fob` found for struct `Struct` in the current scope
+ //~| NOTE function or associated item not found in `Struct`
+
+ Struc::foo();
+ //~^ ERROR failed to resolve: use of undeclared type `Struc`
+ //~| NOTE use of undeclared type `Struc`
+
+ modul::foo();
+ //~^ ERROR failed to resolve: use of undeclared crate or module `modul`
+ //~| NOTE use of undeclared crate or module `modul`
+
+ module::Struc::foo();
+ //~^ ERROR failed to resolve: could not find `Struc` in `module`
+ //~| NOTE could not find `Struc` in `module`
+
+ Trai::foo();
+ //~^ ERROR failed to resolve: use of undeclared type `Trai`
+ //~| NOTE use of undeclared type `Trai`
+}
diff --git a/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr
new file mode 100644
index 000000000..89b69e140
--- /dev/null
+++ b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr
@@ -0,0 +1,54 @@
+error[E0433]: failed to resolve: could not find `Struc` in `module`
+ --> $DIR/typo-suggestion-mistyped-in-path.rs:35:13
+ |
+LL | module::Struc::foo();
+ | ^^^^^
+ | |
+ | could not find `Struc` in `module`
+ | help: a struct with a similar name exists: `Struct`
+
+error[E0599]: no function or associated item named `fob` found for struct `Struct` in the current scope
+ --> $DIR/typo-suggestion-mistyped-in-path.rs:23:13
+ |
+LL | struct Struct;
+ | ------------- function or associated item `fob` not found for this struct
+...
+LL | Struct::fob();
+ | ^^^
+ | |
+ | function or associated item not found in `Struct`
+ | help: there is an associated function with a similar name: `foo`
+
+error[E0433]: failed to resolve: use of undeclared type `Struc`
+ --> $DIR/typo-suggestion-mistyped-in-path.rs:27:5
+ |
+LL | Struc::foo();
+ | ^^^^^
+ | |
+ | use of undeclared type `Struc`
+ | help: a struct with a similar name exists: `Struct`
+
+error[E0433]: failed to resolve: use of undeclared crate or module `modul`
+ --> $DIR/typo-suggestion-mistyped-in-path.rs:31:5
+ |
+LL | modul::foo();
+ | ^^^^^ use of undeclared crate or module `modul`
+ |
+help: there is a crate or module with a similar name
+ |
+LL | module::foo();
+ | ~~~~~~
+
+error[E0433]: failed to resolve: use of undeclared type `Trai`
+ --> $DIR/typo-suggestion-mistyped-in-path.rs:39:5
+ |
+LL | Trai::foo();
+ | ^^^^
+ | |
+ | use of undeclared type `Trai`
+ | help: a trait with a similar name exists: `Trait`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0433, E0599.
+For more information about an error, try `rustc --explain E0433`.
diff --git a/src/test/ui/resolve/use_suggestion.stderr b/src/test/ui/resolve/use_suggestion.stderr
index 4fff179b1..54ad85383 100644
--- a/src/test/ui/resolve/use_suggestion.stderr
+++ b/src/test/ui/resolve/use_suggestion.stderr
@@ -1,14 +1,8 @@
-error[E0433]: failed to resolve: use of undeclared type `GooMap`
- --> $DIR/use_suggestion.rs:3:14
- |
-LL | let x2 = GooMap::new();
- | ^^^^^^ use of undeclared type `GooMap`
-
error[E0433]: failed to resolve: use of undeclared type `HashMap`
--> $DIR/use_suggestion.rs:2:14
|
LL | let x1 = HashMap::new();
- | ^^^^^^^ not found in this scope
+ | ^^^^^^^ use of undeclared type `HashMap`
|
help: consider importing this struct
|
@@ -32,6 +26,12 @@ error[E0412]: cannot find type `GooMap` in this scope
LL | let y2: GooMap;
| ^^^^^^ not found in this scope
+error[E0433]: failed to resolve: use of undeclared type `GooMap`
+ --> $DIR/use_suggestion.rs:3:14
+ |
+LL | let x2 = GooMap::new();
+ | ^^^^^^ use of undeclared type `GooMap`
+
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0412, E0433.
diff --git a/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr b/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr
index d7eeb3a72..4f938670e 100644
--- a/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr
+++ b/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr
@@ -35,17 +35,17 @@ LL | | }
error[E0572]: return statement outside of function body
--> $DIR/issue-86188-return-not-in-fn-body.rs:36:10
|
-LL | / fn main() {
-LL | |
-LL | | [(); return || {
- | |__________^
+LL | / fn main() {
+LL | |
+LL | | [(); return || {
+ | | __________^
LL | ||
LL | ||
LL | || let tx;
LL | || }];
| ||_____^ the return is part of this body...
-LL | | }
- | |_- ...not the enclosing function body
+LL | | }
+ | |__- ...not the enclosing function body
error: aborting due to 4 previous errors
diff --git a/src/test/ui/return/tail-expr-as-potential-return.rs b/src/test/ui/return/tail-expr-as-potential-return.rs
index 2c3610fb2..f46e088b8 100644
--- a/src/test/ui/return/tail-expr-as-potential-return.rs
+++ b/src/test/ui/return/tail-expr-as-potential-return.rs
@@ -12,7 +12,6 @@
// edition:2018
fn main() {
- let _ = foo(true);
}
fn foo(x: bool) -> Result<f64, i32> {
@@ -30,3 +29,19 @@ async fn bar(x: bool) -> Result<f64, i32> {
}
Ok(42.0)
}
+
+trait Identity {
+ type Out;
+}
+
+impl<T> Identity for T {
+ type Out = T;
+}
+
+async fn foo2() -> i32 {
+ if true {
+ 1i32 //~ ERROR mismatched types
+ //| HELP you might have meant to return this value
+ }
+ 0
+}
diff --git a/src/test/ui/return/tail-expr-as-potential-return.stderr b/src/test/ui/return/tail-expr-as-potential-return.stderr
index dec1cbc46..9183b4599 100644
--- a/src/test/ui/return/tail-expr-as-potential-return.stderr
+++ b/src/test/ui/return/tail-expr-as-potential-return.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/tail-expr-as-potential-return.rs:28:9
+ --> $DIR/tail-expr-as-potential-return.rs:27:9
|
LL | / if x {
LL | | Err(42)
@@ -16,7 +16,22 @@ LL | return Err(42);
| ++++++ +
error[E0308]: mismatched types
- --> $DIR/tail-expr-as-potential-return.rs:20:9
+ --> $DIR/tail-expr-as-potential-return.rs:43:9
+ |
+LL | / if true {
+LL | | 1i32
+ | | ^^^^ expected `()`, found `i32`
+LL | | //| HELP you might have meant to return this value
+LL | | }
+ | |_____- expected this to be `()`
+ |
+help: you might have meant to return this value
+ |
+LL | return 1i32;
+ | ++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/tail-expr-as-potential-return.rs:19:9
|
LL | / if x {
LL | | Err(42)
@@ -32,6 +47,6 @@ help: you might have meant to return this value
LL | return Err(42);
| ++++++ +
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs b/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs
index 6b7d94603..a8deb8a75 100644
--- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs
+++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs
@@ -5,7 +5,7 @@ struct Foo {
impl PartialEq for Foo {
fn eq(&self, _: &Foo) -> bool {
- false // ha ha sucker!
+ false // ha ha!
}
}
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index 6ee323146..957795211 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -1,12 +1,10 @@
error[E0277]: the trait bound `f32: Termination` is not satisfied
- --> $DIR/termination-trait-test-wrong-type.rs:6:1
+ --> $DIR/termination-trait-test-wrong-type.rs:6:31
|
-LL | #[test]
- | ------- in this procedural macro expansion
-LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
-LL | | "0".parse()
-LL | | }
- | |_^ the trait `Termination` is not implemented for `f32`
+LL | #[test]
+ | ------- in this procedural macro expansion
+LL | fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Termination` is not implemented for `f32`
|
= note: required for `Result<f32, ParseFloatError>` to implement `Termination`
note: required by a bound in `assert_test_result`
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
index e017d04a5..96fe11911 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
@@ -72,6 +72,12 @@ LL | macro_rules! use_expr {
...
LL | use_expr!(let 0 = 1);
| ^^^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$e:expr`
+ --> $DIR/feature-gate.rs:61:10
+ |
+LL | ($e:expr) => {
+ | ^^^^^^^
error[E0658]: `if let` guards are experimental
--> $DIR/feature-gate.rs:7:12
diff --git a/src/test/ui/rfc-2294-if-let-guard/run-pass.rs b/src/test/ui/rfc-2294-if-let-guard/run-pass.rs
index 3da57989d..a303a0d1f 100644
--- a/src/test/ui/rfc-2294-if-let-guard/run-pass.rs
+++ b/src/test/ui/rfc-2294-if-let-guard/run-pass.rs
@@ -30,4 +30,11 @@ fn main() {
Some(x) if let Foo::Qux(y) = qux(x) => assert_eq!(y, 84),
_ => panic!(),
}
+
+ // issue #88015
+ #[allow(irrefutable_let_patterns)]
+ match () {
+ () | () if let x = 42 => assert_eq!(x, 42),
+ _ => panic!()
+ }
}
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
index 5611b5f4e..06699b947 100644
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
@@ -7,6 +7,12 @@ LL | let _ = dbg!(a);
| ------- value moved here
LL | let _ = dbg!(a);
| ^ value used here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ --> $SRC_DIR/std/src/macros.rs:LL:COL
+ |
+LL | ref tmp => {
+ | +++
error: aborting due to previous error
diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
index feea1c254..7a43b71fc 100644
--- a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
@@ -18,6 +18,12 @@ LL | macro_rules! use_expr {
...
LL | use_expr!(let 0 = 1);
| ^^^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$e:expr`
+ --> $DIR/feature-gate.rs:50:10
+ |
+LL | ($e:expr) => {
+ | ^^^^^^^
error[E0658]: `let` expressions in this position are unstable
--> $DIR/feature-gate.rs:14:16
diff --git a/src/test/ui/rfc-2497-if-let-chains/issue-99938.rs b/src/test/ui/rfc-2497-if-let-chains/issue-99938.rs
new file mode 100644
index 000000000..bd81ce0b1
--- /dev/null
+++ b/src/test/ui/rfc-2497-if-let-chains/issue-99938.rs
@@ -0,0 +1,31 @@
+// compile-flags: -Zvalidate-mir -C opt-level=3
+// build-pass
+#![feature(let_chains)]
+struct TupleIter<T, I: Iterator<Item = T>> {
+ inner: I,
+}
+
+impl<T, I: Iterator<Item = T>> Iterator for TupleIter<T, I> {
+ type Item = (T, T, T);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let inner = &mut self.inner;
+
+ if let Some(first) = inner.next()
+ && let Some(second) = inner.next()
+ && let Some(third) = inner.next()
+ {
+ Some((first, second, third))
+ } else {
+ None
+ }
+ }
+}
+
+fn main() {
+ let vec: Vec<u8> = Vec::new();
+ let mut tup_iter = TupleIter {
+ inner: vec.into_iter(),
+ };
+ tup_iter.next();
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
index f515ec198..36a09add4 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
@@ -10,7 +10,7 @@ LL | impl const std::ops::Add for i32 {
|
= note: define and implement a trait or new type instead
-error[E0119]: conflicting implementations of trait `std::ops::Add` for type `Int`
+error[E0119]: conflicting implementations of trait `Add` for type `Int`
--> $DIR/const-and-non-const-impl.rs:22:1
|
LL | impl std::ops::Add for Int {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
new file mode 100644
index 000000000..348ca0ab1
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
@@ -0,0 +1,4 @@
+#[derive_const(Default)] //~ ERROR use of unstable library feature
+pub struct S;
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
new file mode 100644
index 000000000..cc9bdd271
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
@@ -0,0 +1,11 @@
+error[E0658]: use of unstable library feature 'derive_const'
+ --> $DIR/derive-const-gate.rs:1:3
+ |
+LL | #[derive_const(Default)]
+ | ^^^^^^^^^^^^
+ |
+ = help: add `#![feature(derive_const)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
new file mode 100644
index 000000000..92843a8a2
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
@@ -0,0 +1,13 @@
+#![feature(derive_const)]
+
+pub struct A;
+
+impl Default for A {
+ fn default() -> A { A }
+}
+
+#[derive_const(Default)]
+pub struct S(A);
+//~^ cannot call non-const fn
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr
new file mode 100644
index 000000000..d463c774e
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr
@@ -0,0 +1,14 @@
+error[E0015]: cannot call non-const fn `<A as Default>::default` in constant functions
+ --> $DIR/derive-const-non-const-type.rs:10:14
+ |
+LL | #[derive_const(Default)]
+ | ------- in this derive macro expansion
+LL | pub struct S(A);
+ | ^
+ |
+ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+ = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs
new file mode 100644
index 000000000..d1fbeac85
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs
@@ -0,0 +1,19 @@
+// check-pass
+#![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
+
+pub struct A;
+
+impl const Default for A {
+ fn default() -> A { A }
+}
+
+impl const PartialEq for A {
+ fn eq(&self, _: &A) -> bool { true }
+}
+
+#[derive_const(Default, PartialEq)]
+pub struct S((), A);
+
+const _: () = assert!(S((), A) == S::default());
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-79450.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-79450.rs
new file mode 100644
index 000000000..b604c65d7
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-79450.rs
@@ -0,0 +1,20 @@
+#![feature(const_fmt_arguments_new)]
+#![feature(const_trait_impl)]
+
+#[const_trait]
+trait Tr {
+ fn req(&self);
+
+ fn prov(&self) {
+ println!("lul"); //~ ERROR: cannot call non-const fn `_print` in constant functions
+ self.req();
+ }
+}
+
+struct S;
+
+impl const Tr for S {
+ fn req(&self) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-79450.stderr b/src/test/ui/rfc-2632-const-trait-impl/issue-79450.stderr
new file mode 100644
index 000000000..082c0333f
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/issue-79450.stderr
@@ -0,0 +1,12 @@
+error[E0015]: cannot call non-const fn `_print` in constant functions
+ --> $DIR/issue-79450.rs:9:9
+ |
+LL | println!("lul");
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
new file mode 100644
index 000000000..3ac909924
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
@@ -0,0 +1,46 @@
+// Tests that trait bounds on specializing trait impls must be `~const` if the
+// same bound is present on the default impl and is `~const` there.
+
+#![feature(const_trait_impl)]
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+
+#[rustc_specialization_trait]
+trait Specialize {}
+
+#[const_trait]
+trait Foo {}
+
+#[const_trait]
+trait Bar {}
+
+// bgr360: I was only able to exercise the code path that raises the
+// "missing ~const qualifier" error by making this base impl non-const, even
+// though that doesn't really make sense to do. As seen below, if the base impl
+// is made const, rustc fails earlier with an overlapping impl failure.
+impl<T> Bar for T
+where
+ T: ~const Foo,
+{}
+
+impl<T> Bar for T
+where
+ T: Foo, //~ ERROR missing `~const` qualifier
+ T: Specialize,
+{}
+
+#[const_trait]
+trait Baz {}
+
+impl<T> const Baz for T
+where
+ T: ~const Foo,
+{}
+
+impl<T> const Baz for T //~ ERROR conflicting implementations of trait `Baz`
+where
+ T: Foo,
+ T: Specialize,
+{}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
new file mode 100644
index 000000000..4aea19794
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
@@ -0,0 +1,18 @@
+error: missing `~const` qualifier for specialization
+ --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:8
+ |
+LL | T: Foo,
+ | ^^^
+
+error[E0119]: conflicting implementations of trait `Baz`
+ --> $DIR/const-default-bound-non-const-specialized-bound.rs:40:1
+ |
+LL | impl<T> const Baz for T
+ | ----------------------- first implementation here
+...
+LL | impl<T> const Baz for T
+ | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
new file mode 100644
index 000000000..9ddea427c
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
@@ -0,0 +1,39 @@
+// Tests that a const default trait impl can be specialized by another const
+// trait impl and that the specializing impl will be used during const-eval.
+
+// run-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Value {
+ fn value() -> u32;
+}
+
+const fn get_value<T: ~const Value>() -> u32 {
+ T::value()
+}
+
+impl<T> const Value for T {
+ default fn value() -> u32 {
+ 0
+ }
+}
+
+struct FortyTwo;
+
+impl const Value for FortyTwo {
+ fn value() -> u32 {
+ 42
+ }
+}
+
+const ZERO: u32 = get_value::<()>();
+
+const FORTY_TWO: u32 = get_value::<FortyTwo>();
+
+fn main() {
+ assert_eq!(ZERO, 0);
+ assert_eq!(FORTY_TWO, 42);
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
new file mode 100644
index 000000000..a3bb9b3f9
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
@@ -0,0 +1,26 @@
+// Tests that specializing trait impls must be at least as const as the default impl.
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Value {
+ fn value() -> u32;
+}
+
+impl<T> const Value for T {
+ default fn value() -> u32 {
+ 0
+ }
+}
+
+struct FortyTwo;
+
+impl Value for FortyTwo { //~ ERROR cannot specialize on const impl with non-const impl
+ fn value() -> u32 {
+ println!("You can't do that (constly)");
+ 42
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr
new file mode 100644
index 000000000..247668047
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr
@@ -0,0 +1,8 @@
+error: cannot specialize on const impl with non-const impl
+ --> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1
+ |
+LL | impl Value for FortyTwo {
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs
new file mode 100644
index 000000000..2aac0a2b4
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Foo {
+ fn foo();
+}
+
+impl const Foo for u32 {
+ default fn foo() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
new file mode 100644
index 000000000..9c2c2cf16
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
@@ -0,0 +1,37 @@
+// Tests that `~const` trait bounds can be used to specialize const trait impls.
+
+// check-pass
+
+#![feature(const_trait_impl)]
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+
+#[const_trait]
+#[rustc_specialization_trait]
+trait Specialize {}
+
+#[const_trait]
+trait Foo {}
+
+impl<T> const Foo for T {}
+
+impl<T> const Foo for T
+where
+ T: ~const Specialize,
+{}
+
+#[const_trait]
+trait Bar {}
+
+impl<T> const Bar for T
+where
+ T: ~const Foo,
+{}
+
+impl<T> const Bar for T
+where
+ T: ~const Foo,
+ T: ~const Specialize,
+{}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
new file mode 100644
index 000000000..1e6b1c651
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
@@ -0,0 +1,45 @@
+// Tests that `T: ~const Foo` in a specializing impl is treated as equivalent to
+// `T: Foo` in the default impl for the purposes of specialization (i.e., it
+// does not think that the user is attempting to specialize on trait `Foo`).
+
+// check-pass
+
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+#![feature(const_trait_impl)]
+
+#[rustc_specialization_trait]
+trait Specialize {}
+
+#[const_trait]
+trait Foo {}
+
+#[const_trait]
+trait Bar {}
+
+impl<T> Bar for T
+where
+ T: Foo,
+{}
+
+impl<T> const Bar for T
+where
+ T: ~const Foo,
+ T: Specialize,
+{}
+
+#[const_trait]
+trait Baz {}
+
+impl<T> const Baz for T
+where
+ T: Foo,
+{}
+
+impl<T> const Baz for T
+where
+ T: ~const Foo,
+ T: Specialize,
+{}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
new file mode 100644
index 000000000..35aa52fbd
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
@@ -0,0 +1,39 @@
+// Tests that a non-const default impl can be specialized by a const trait impl,
+// but that the default impl cannot be used in a const context.
+
+// run-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Value {
+ fn value() -> u32;
+}
+
+const fn get_value<T: ~const Value>() -> u32 {
+ T::value()
+}
+
+impl<T> Value for T {
+ default fn value() -> u32 {
+ println!("You can't do that (constly)");
+ 0
+ }
+}
+
+struct FortyTwo;
+
+impl const Value for FortyTwo {
+ fn value() -> u32 {
+ 42
+ }
+}
+
+fn main() {
+ let zero = get_value::<()>();
+ assert_eq!(zero, 0);
+
+ const FORTY_TWO: u32 = get_value::<FortyTwo>();
+ assert_eq!(FORTY_TWO, 42);
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs
index ff0cd489d..9ab170f09 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs
@@ -17,7 +17,9 @@ impl<T: ~const Default> const A for T {
}
}
-impl<T: Default + Sup> A for T { //~ ERROR: cannot specialize
+impl<T: Default + Sup> A for T {
+//~^ ERROR: cannot specialize
+//~| ERROR: missing `~const` qualifier
fn a() -> u32 {
3
}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
index 3296c109c..843fc6ce8 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
@@ -1,8 +1,14 @@
-error: cannot specialize on trait `Default`
+error: cannot specialize on const impl with non-const impl
+ --> $DIR/specializing-constness.rs:20:1
+ |
+LL | impl<T: Default + Sup> A for T {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing `~const` qualifier for specialization
--> $DIR/specializing-constness.rs:20:9
|
LL | impl<T: Default + Sup> A for T {
| ^^^^^^^
-error: aborting due to previous error
+error: aborting due to 2 previous errors
diff --git a/src/test/ui/rfc1623.rs b/src/test/ui/rfcs/rfc1623-2.rs
index c0e13a5f5..c0e13a5f5 100644
--- a/src/test/ui/rfc1623.rs
+++ b/src/test/ui/rfcs/rfc1623-2.rs
diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfcs/rfc1623-2.stderr
index b15a4cb11..d183eaaa6 100644
--- a/src/test/ui/rfc1623.stderr
+++ b/src/test/ui/rfcs/rfc1623-2.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/rfc1623.rs:28:8
+ --> $DIR/rfc1623-2.rs:28:8
|
LL | f: &id,
| ^^^ one type is more general than the other
@@ -8,7 +8,7 @@ LL | f: &id,
found trait `Fn<(&Foo<'_>,)>`
error[E0308]: mismatched types
- --> $DIR/rfc1623.rs:28:8
+ --> $DIR/rfc1623-2.rs:28:8
|
LL | f: &id,
| ^^^ one type is more general than the other
@@ -17,7 +17,7 @@ LL | f: &id,
found trait `Fn<(&Foo<'_>,)>`
error: implementation of `FnOnce` is not general enough
- --> $DIR/rfc1623.rs:28:8
+ --> $DIR/rfc1623-2.rs:28:8
|
LL | f: &id,
| ^^^ implementation of `FnOnce` is not general enough
@@ -26,7 +26,7 @@ LL | f: &id,
= note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2`
error: implementation of `FnOnce` is not general enough
- --> $DIR/rfc1623.rs:28:8
+ --> $DIR/rfc1623-2.rs:28:8
|
LL | f: &id,
| ^^^ implementation of `FnOnce` is not general enough
diff --git a/src/test/ui/rfc1623-2.rs b/src/test/ui/rfcs/rfc1623-3.rs
index 26fa6fdb5..26fa6fdb5 100644
--- a/src/test/ui/rfc1623-2.rs
+++ b/src/test/ui/rfcs/rfc1623-3.rs
diff --git a/src/test/ui/rfc1623-2.stderr b/src/test/ui/rfcs/rfc1623-3.stderr
index 945c6533c..77fc3f041 100644
--- a/src/test/ui/rfc1623-2.stderr
+++ b/src/test/ui/rfcs/rfc1623-3.stderr
@@ -1,5 +1,5 @@
error[E0106]: missing lifetime specifier
- --> $DIR/rfc1623-2.rs:8:42
+ --> $DIR/rfc1623-3.rs:8:42
|
LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 =
| --- --- ^ expected named lifetime parameter
@@ -12,7 +12,7 @@ LL | static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 =
| +++++++ ++ ++ ++
error[E0106]: missing lifetime specifier
- --> $DIR/rfc1623-2.rs:10:39
+ --> $DIR/rfc1623-3.rs:10:39
|
LL | &(non_elidable as fn(&u8, &u8) -> &u8);
| --- --- ^ expected named lifetime parameter
@@ -24,7 +24,7 @@ LL | &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8);
| +++++++ ++ ++ ++
error[E0605]: non-primitive cast: `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {non_elidable}` as `for<'a, 'b> fn(&'a u8, &'b u8) -> &u8`
- --> $DIR/rfc1623-2.rs:10:6
+ --> $DIR/rfc1623-3.rs:10:6
|
LL | &(non_elidable as fn(&u8, &u8) -> &u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
diff --git a/src/test/ui/sanitize/memory-passing.rs b/src/test/ui/sanitize/memory-passing.rs
new file mode 100644
index 000000000..6d9b70ad6
--- /dev/null
+++ b/src/test/ui/sanitize/memory-passing.rs
@@ -0,0 +1,32 @@
+// needs-sanitizer-support
+// needs-sanitizer-memory
+//
+// revisions: unoptimized optimized
+//
+// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
+// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins
+//
+// run-pass
+//
+// This test case intentionally limits the usage of the std,
+// since it will be linked with an uninstrumented version of it.
+
+#![feature(core_intrinsics)]
+#![feature(start)]
+#![allow(invalid_value)]
+
+use std::hint::black_box;
+
+fn calling_black_box_on_zst_ok() {
+ // It's OK to call black_box on a value of a zero-sized type, even if its
+ // underlying the memory location is uninitialized. For non-zero-sized types,
+ // this would be an MSAN error.
+ let zst = ();
+ black_box(zst);
+}
+
+#[start]
+fn main(_: isize, _: *const *const u8) -> isize {
+ calling_black_box_on_zst_ok();
+ 0
+}
diff --git a/src/test/ui/self/class-missing-self.stderr b/src/test/ui/self/class-missing-self.stderr
index d501200d7..063c3f013 100644
--- a/src/test/ui/self/class-missing-self.stderr
+++ b/src/test/ui/self/class-missing-self.stderr
@@ -10,6 +10,10 @@ error[E0425]: cannot find function `sleep` in this scope
LL | sleep();
| ^^^^^ not found in this scope
|
+help: consider using the associated function
+ |
+LL | self.sleep();
+ | +++++
help: consider importing this function
|
LL | use std::thread::sleep;
diff --git a/src/test/ui/sized/coinductive-1-gat.rs b/src/test/ui/sized/coinductive-1-gat.rs
new file mode 100644
index 000000000..cdf70920f
--- /dev/null
+++ b/src/test/ui/sized/coinductive-1-gat.rs
@@ -0,0 +1,14 @@
+// check-pass
+struct Node<C: Trait>(C::Assoc::<Self>);
+
+trait Trait {
+ type Assoc<T>;
+}
+
+impl Trait for Vec<()> {
+ type Assoc<T> = Vec<T>;
+}
+
+fn main() {
+ let _ = Node::<Vec<()>>(Vec::new());
+}
diff --git a/src/test/ui/sized/coinductive-1.rs b/src/test/ui/sized/coinductive-1.rs
new file mode 100644
index 000000000..7bcd0f1fd
--- /dev/null
+++ b/src/test/ui/sized/coinductive-1.rs
@@ -0,0 +1,14 @@
+// check-pass
+struct Node<C: Trait<Self>>(C::Assoc);
+
+trait Trait<T> {
+ type Assoc;
+}
+
+impl<T> Trait<T> for Vec<()> {
+ type Assoc = Vec<T>;
+}
+
+fn main() {
+ let _ = Node::<Vec<()>>(Vec::new());
+}
diff --git a/src/test/ui/sized/coinductive-2.rs b/src/test/ui/sized/coinductive-2.rs
new file mode 100644
index 000000000..212274d2e
--- /dev/null
+++ b/src/test/ui/sized/coinductive-2.rs
@@ -0,0 +1,28 @@
+// run-pass
+struct Node<C: CollectionFactory<Self>> {
+ _children: C::Collection,
+}
+
+trait CollectionFactory<T> {
+ type Collection;
+}
+
+impl<T> CollectionFactory<T> for Vec<()> {
+ type Collection = Vec<T>;
+}
+
+trait Collection<T>: Sized {
+ fn push(&mut self, v: T);
+}
+
+impl<T> Collection<T> for Vec<T> {
+ fn push(&mut self, v: T) {
+ self.push(v)
+ }
+}
+
+fn main() {
+ let _ = Node::<Vec<()>> {
+ _children: Vec::new(),
+ };
+}
diff --git a/src/test/ui/sized/recursive-type-1.rs b/src/test/ui/sized/recursive-type-1.rs
new file mode 100644
index 000000000..cd6805967
--- /dev/null
+++ b/src/test/ui/sized/recursive-type-1.rs
@@ -0,0 +1,10 @@
+// check-pass
+trait A { type Assoc; }
+
+impl A for () {
+ // FIXME: it would be nice for this to at least cause a warning.
+ type Assoc = Foo<()>;
+}
+struct Foo<T: A>(T::Assoc);
+
+fn main() {}
diff --git a/src/test/ui/sized/recursive-type-2.rs b/src/test/ui/sized/recursive-type-2.rs
new file mode 100644
index 000000000..7d95417a6
--- /dev/null
+++ b/src/test/ui/sized/recursive-type-2.rs
@@ -0,0 +1,13 @@
+// build-fail
+//~^ ERROR cycle detected when computing layout of `Foo<()>`
+
+trait A { type Assoc: ?Sized; }
+
+impl A for () {
+ type Assoc = Foo<()>;
+}
+struct Foo<T: A>(T::Assoc);
+
+fn main() {
+ let x: Foo<()>;
+}
diff --git a/src/test/ui/sized/recursive-type-2.stderr b/src/test/ui/sized/recursive-type-2.stderr
new file mode 100644
index 000000000..d0e6e9db0
--- /dev/null
+++ b/src/test/ui/sized/recursive-type-2.stderr
@@ -0,0 +1,13 @@
+error[E0391]: cycle detected when computing layout of `Foo<()>`
+ |
+ = note: ...which requires computing layout of `<() as A>::Assoc`...
+ = note: ...which again requires computing layout of `Foo<()>`, completing the cycle
+note: cycle used when elaborating drops for `main`
+ --> $DIR/recursive-type-2.rs:11:1
+ |
+LL | fn main() {
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.rs b/src/test/ui/span/borrowck-let-suggestion-suffixes.rs
index 6240f103c..18abfb5c3 100644
--- a/src/test/ui/span/borrowck-let-suggestion-suffixes.rs
+++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.rs
@@ -18,7 +18,7 @@ fn f() {
v3.push(&id('x')); // statement 6
//~^ ERROR temporary value dropped while borrowed
- //~| NOTE creates a temporary which is freed while still in use
+ //~| NOTE creates a temporary value which is freed while still in use
//~| NOTE temporary value is freed at the end of this statement
//~| HELP consider using a `let` binding to create a longer lived value
@@ -28,7 +28,7 @@ fn f() {
v4.push(&id('y'));
//~^ ERROR temporary value dropped while borrowed
- //~| NOTE creates a temporary which is freed while still in use
+ //~| NOTE creates a temporary value which is freed while still in use
//~| NOTE temporary value is freed at the end of this statement
//~| NOTE consider using a `let` binding to create a longer lived value
v4.use_ref();
@@ -39,7 +39,7 @@ fn f() {
v5.push(&id('z'));
//~^ ERROR temporary value dropped while borrowed
- //~| NOTE creates a temporary which is freed while still in use
+ //~| NOTE creates a temporary value which is freed while still in use
//~| NOTE temporary value is freed at the end of this statement
//~| HELP consider using a `let` binding to create a longer lived value
diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr
index a236dab3a..2dc29a78d 100644
--- a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr
+++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr
@@ -16,7 +16,7 @@ error[E0716]: temporary value dropped while borrowed
LL | v3.push(&id('x')); // statement 6
| ^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref();
| -- borrow later used here
@@ -33,7 +33,7 @@ error[E0716]: temporary value dropped while borrowed
LL | v4.push(&id('y'));
| ^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | v4.use_ref();
| ------------ borrow later used here
@@ -46,7 +46,7 @@ error[E0716]: temporary value dropped while borrowed
LL | v5.push(&id('z'));
| ^^^^^^^ - temporary value is freed at the end of this statement
| |
- | creates a temporary which is freed while still in use
+ | creates a temporary value which is freed while still in use
...
LL | (v1, v2, v3, /* v4 is above. */ v5).use_ref();
| -- borrow later used here
diff --git a/src/test/ui/span/borrowck-ref-into-rvalue.stderr b/src/test/ui/span/borrowck-ref-into-rvalue.stderr
index cb5289d24..25e344fed 100644
--- a/src/test/ui/span/borrowck-ref-into-rvalue.stderr
+++ b/src/test/ui/span/borrowck-ref-into-rvalue.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/borrowck-ref-into-rvalue.rs:4:11
|
LL | match Some("Hello".to_string()) {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
...
LL | }
| - temporary value is freed at the end of this statement
diff --git a/src/test/ui/span/issue-11925.rs b/src/test/ui/span/issue-11925.rs
index d9c08fbdd..cac9fd5bf 100644
--- a/src/test/ui/span/issue-11925.rs
+++ b/src/test/ui/span/issue-11925.rs
@@ -1,6 +1,6 @@
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, tuple_trait)]
-fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
+fn to_fn_once<A:std::marker::Tuple,F:FnOnce<A>>(f: F) -> F { f }
fn main() {
let r = {
diff --git a/src/test/ui/span/issue-15480.stderr b/src/test/ui/span/issue-15480.stderr
index 460ad9ac7..d9cce2254 100644
--- a/src/test/ui/span/issue-15480.stderr
+++ b/src/test/ui/span/issue-15480.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/issue-15480.rs:6:10
|
LL | &id(3)
- | ^^^^^ creates a temporary which is freed while still in use
+ | ^^^^^ creates a temporary value which is freed while still in use
LL | ];
| - temporary value is freed at the end of this statement
...
diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr
index d8fddc800..057d40ac0 100644
--- a/src/test/ui/span/issue-35987.stderr
+++ b/src/test/ui/span/issue-35987.stderr
@@ -1,6 +1,9 @@
error[E0404]: expected trait, found type parameter `Add`
--> $DIR/issue-35987.rs:5:21
|
+LL | use std::ops::Add;
+ | --- you might have meant to refer to this trait
+LL |
LL | impl<T: Clone, Add> Add for Foo<T> {
| --- ^^^ not a trait
| |
diff --git a/src/test/ui/span/issue-71363.rs b/src/test/ui/span/issue-71363.rs
index bbb4a9362..f187d0efa 100644
--- a/src/test/ui/span/issue-71363.rs
+++ b/src/test/ui/span/issue-71363.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z simulate-remapped-rust-src-base=/rustc/xyz -Z translate-remapped-path-to-local-path=no -Z ui-testing=no
+// compile-flags: -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ui-testing=no
struct MyError;
impl std::error::Error for MyError {}
diff --git a/src/test/ui/span/issue-71363.stderr b/src/test/ui/span/issue-71363.stderr
index 04e2b46c3..0370e46e6 100644
--- a/src/test/ui/span/issue-71363.stderr
+++ b/src/test/ui/span/issue-71363.stderr
@@ -7,6 +7,9 @@ error[E0277]: `MyError` doesn't implement `std::fmt::Display`
= help: the trait `std::fmt::Display` is not implemented for `MyError`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `std::error::Error`
+ --> $SRC_DIR/core/src/error.rs:LL:COL
+ |
+ = note: required by this bound in `std::error::Error`
error[E0277]: `MyError` doesn't implement `Debug`
--> $DIR/issue-71363.rs:4:6
@@ -17,6 +20,9 @@ error[E0277]: `MyError` doesn't implement `Debug`
= help: the trait `Debug` is not implemented for `MyError`
= note: add `#[derive(Debug)]` to `MyError` or manually `impl Debug for MyError`
note: required by a bound in `std::error::Error`
+ --> $SRC_DIR/core/src/error.rs:LL:COL
+ |
+ = note: required by this bound in `std::error::Error`
help: consider annotating `MyError` with `#[derive(Debug)]`
|
3 | #[derive(Debug)]
diff --git a/src/test/ui/span/macro-ty-params.rs b/src/test/ui/span/macro-ty-params.rs
index 0a93105b6..cf28b0255 100644
--- a/src/test/ui/span/macro-ty-params.rs
+++ b/src/test/ui/span/macro-ty-params.rs
@@ -9,5 +9,7 @@ macro_rules! foo { () => () }
fn main() {
foo::<T>!(); //~ ERROR generic arguments in macro path
foo::<>!(); //~ ERROR generic arguments in macro path
- m!(Default<>); //~ ERROR unexpected generic arguments in path
+ m!(Default<>);
+ //~^ ERROR unexpected generic arguments in path
+ //~^^ ERROR generic arguments in macro path
}
diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr
index 138cd2598..7023ef8cd 100644
--- a/src/test/ui/span/macro-ty-params.stderr
+++ b/src/test/ui/span/macro-ty-params.stderr
@@ -16,5 +16,11 @@ error: unexpected generic arguments in path
LL | m!(Default<>);
| ^^
-error: aborting due to 3 previous errors
+error: generic arguments in macro path
+ --> $DIR/macro-ty-params.rs:12:15
+ |
+LL | m!(Default<>);
+ | ^^
+
+error: aborting due to 4 previous errors
diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr
index c0d9a8634..b44df962a 100644
--- a/src/test/ui/span/multiline-span-simple.stderr
+++ b/src/test/ui/span/multiline-span-simple.stderr
@@ -6,15 +6,10 @@ LL | foo(1 as u32 +
|
= help: the trait `Add<()>` is not implemented for `u32`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&'a u32 as Add<u32>>
+ <&u32 as Add<&u32>>
+ <u32 as Add<&u32>>
+ <u32 as Add>
error: aborting due to previous error
diff --git a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr
index ba0c45acf..81e858fa0 100644
--- a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr
+++ b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/regions-close-over-borrowed-ref-in-obj.rs:12:27
|
LL | let ss: &isize = &id(1);
- | ^^^^^ creates a temporary which is freed while still in use
+ | ^^^^^ creates a temporary value which is freed while still in use
...
LL | }
| - temporary value is freed at the end of this statement
diff --git a/src/test/ui/span/slice-borrow.stderr b/src/test/ui/span/slice-borrow.stderr
index 27df25be3..b70bf69d6 100644
--- a/src/test/ui/span/slice-borrow.stderr
+++ b/src/test/ui/span/slice-borrow.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/slice-borrow.rs:6:28
|
LL | let x: &[isize] = &vec![1, 2, 3, 4, 5];
- | ^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
+ | ^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
...
LL | }
| - temporary value is freed at the end of this statement
diff --git a/src/test/ui/specialization/issue-43037.stderr b/src/test/ui/specialization/issue-43037.current.stderr
index 4249cd894..26db9d7c9 100644
--- a/src/test/ui/specialization/issue-43037.stderr
+++ b/src/test/ui/specialization/issue-43037.current.stderr
@@ -1,5 +1,5 @@
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
- --> $DIR/issue-43037.rs:17:6
+ --> $DIR/issue-43037.rs:19:6
|
LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
| ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/issue-100191.stderr b/src/test/ui/specialization/issue-43037.negative.stderr
index 1adb0f1e4..26db9d7c9 100644
--- a/src/test/ui/coherence/issue-100191.stderr
+++ b/src/test/ui/specialization/issue-43037.negative.stderr
@@ -1,5 +1,5 @@
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
- --> $DIR/issue-100191.rs:18:6
+ --> $DIR/issue-43037.rs:19:6
|
LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
| ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/specialization/issue-43037.rs b/src/test/ui/specialization/issue-43037.rs
index c49119f9c..a1e3f998b 100644
--- a/src/test/ui/specialization/issue-43037.rs
+++ b/src/test/ui/specialization/issue-43037.rs
@@ -1,4 +1,6 @@
+// revisions: current negative
#![feature(specialization)]
+#![cfg_attr(negative, feature(with_negative_coherence))]
#![allow(incomplete_features)]
trait X {}
diff --git a/src/test/ui/specialization/issue-45814.stderr b/src/test/ui/specialization/issue-45814.current.stderr
index 419345add..5013559b8 100644
--- a/src/test/ui/specialization/issue-45814.stderr
+++ b/src/test/ui/specialization/issue-45814.current.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow evaluating the requirement `T: Trait<_>`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
note: required for `T` to implement `Trait<_>`
- --> $DIR/issue-45814.rs:8:20
+ --> $DIR/issue-45814.rs:9:20
|
LL | default impl<T, U> Trait<T> for U {}
| ^^^^^^^^ ^
diff --git a/src/test/ui/coherence/issue-100191-2.stderr b/src/test/ui/specialization/issue-45814.negative.stderr
index d50c220bc..5013559b8 100644
--- a/src/test/ui/coherence/issue-100191-2.stderr
+++ b/src/test/ui/specialization/issue-45814.negative.stderr
@@ -1,8 +1,8 @@
error[E0275]: overflow evaluating the requirement `T: Trait<_>`
|
- = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_100191_2`)
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
note: required for `T` to implement `Trait<_>`
- --> $DIR/issue-100191-2.rs:8:20
+ --> $DIR/issue-45814.rs:9:20
|
LL | default impl<T, U> Trait<T> for U {}
| ^^^^^^^^ ^
diff --git a/src/test/ui/specialization/issue-45814.rs b/src/test/ui/specialization/issue-45814.rs
index 8ee5d3e2e..fce236390 100644
--- a/src/test/ui/specialization/issue-45814.rs
+++ b/src/test/ui/specialization/issue-45814.rs
@@ -1,6 +1,7 @@
//~ ERROR overflow evaluating the requirement `T: Trait<_>`
-
+// revisions: current negative
#![feature(specialization)]
+#![cfg_attr(negative, feature(with_negative_coherence))]
#![allow(incomplete_features)]
pub trait Trait<T> {}
diff --git a/src/test/ui/specialization/specialization-overlap-negative.stderr b/src/test/ui/specialization/specialization-overlap-negative.stderr
index fb3d9723a..1fe4869ff 100644
--- a/src/test/ui/specialization/specialization-overlap-negative.stderr
+++ b/src/test/ui/specialization/specialization-overlap-negative.stderr
@@ -8,7 +8,7 @@ LL | #![feature(specialization)]
= help: consider using `min_specialization` instead, which is more stable and complete
= note: `#[warn(incomplete_features)]` on by default
-error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
+error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
--> $DIR/specialization-overlap-negative.rs:9:1
|
LL | unsafe impl<T: Clone> Send for TestType<T> {}
diff --git a/src/test/ui/specialization/specialization-overlap.stderr b/src/test/ui/specialization/specialization-overlap.stderr
index 989264467..098bf4a70 100644
--- a/src/test/ui/specialization/specialization-overlap.stderr
+++ b/src/test/ui/specialization/specialization-overlap.stderr
@@ -8,13 +8,13 @@ LL | #![feature(specialization)]
= help: consider using `min_specialization` instead, which is more stable and complete
= note: `#[warn(incomplete_features)]` on by default
-error[E0119]: conflicting implementations of trait `Foo` for type `std::vec::Vec<_>`
+error[E0119]: conflicting implementations of trait `Foo` for type `Vec<_>`
--> $DIR/specialization-overlap.rs:5:1
|
LL | impl<T: Clone> Foo for T {}
| ------------------------ first implementation here
LL | impl<T> Foo for Vec<T> {}
- | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::vec::Vec<_>`
+ | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Vec<_>`
error[E0119]: conflicting implementations of trait `Bar` for type `(u8, u8)`
--> $DIR/specialization-overlap.rs:9:1
diff --git a/src/test/ui/issues/issue-5216.rs b/src/test/ui/static/issue-5216.rs
index 4072a57cb..4072a57cb 100644
--- a/src/test/ui/issues/issue-5216.rs
+++ b/src/test/ui/static/issue-5216.rs
diff --git a/src/test/ui/issues/issue-5216.stderr b/src/test/ui/static/issue-5216.stderr
index 1afff28f0..1afff28f0 100644
--- a/src/test/ui/issues/issue-5216.stderr
+++ b/src/test/ui/static/issue-5216.stderr
diff --git a/src/test/ui/static/static-drop-scope.stderr b/src/test/ui/static/static-drop-scope.stderr
index 112bfc003..cedcb7367 100644
--- a/src/test/ui/static/static-drop-scope.stderr
+++ b/src/test/ui/static/static-drop-scope.stderr
@@ -13,7 +13,7 @@ LL | static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
| ------^^^^^^^^-
| | | |
| | | temporary value is freed at the end of this statement
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| using this value as a static requires that borrow lasts for `'static`
error[E0493]: destructor of `WithDtor` cannot be evaluated at compile-time
@@ -31,7 +31,7 @@ LL | const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
| ------^^^^^^^^-
| | | |
| | | temporary value is freed at the end of this statement
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| using this value as a constant requires that borrow lasts for `'static`
error[E0493]: destructor of `(WithDtor, i32)` cannot be evaluated at compile-time
diff --git a/src/test/ui/static/static-reference-to-fn-2.stderr b/src/test/ui/static/static-reference-to-fn-2.stderr
index ff15884bd..133d8ec2e 100644
--- a/src/test/ui/static/static-reference-to-fn-2.stderr
+++ b/src/test/ui/static/static-reference-to-fn-2.stderr
@@ -6,7 +6,7 @@ LL | fn state1(self_: &mut StateMachineIter) -> Option<&'static str> {
LL | self_.statefn = &id(state2 as StateMachineFunc);
| -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
| | |
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| assignment requires that borrow lasts for `'1`
error[E0716]: temporary value dropped while borrowed
@@ -17,7 +17,7 @@ LL | fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> {
LL | self_.statefn = &id(state3 as StateMachineFunc);
| -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
| | |
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| assignment requires that borrow lasts for `'1`
error[E0716]: temporary value dropped while borrowed
@@ -28,7 +28,7 @@ LL | fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> {
LL | self_.statefn = &id(finished as StateMachineFunc);
| -----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
| | |
- | | creates a temporary which is freed while still in use
+ | | creates a temporary value which is freed while still in use
| assignment requires that borrow lasts for `'1`
error[E0515]: cannot return value referencing temporary value
diff --git a/src/test/ui/static/static-region-bound.stderr b/src/test/ui/static/static-region-bound.stderr
index 15261259e..1a607e3c0 100644
--- a/src/test/ui/static/static-region-bound.stderr
+++ b/src/test/ui/static/static-region-bound.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/static-region-bound.rs:10:14
|
LL | let x = &id(3);
- | ^^^^^ creates a temporary which is freed while still in use
+ | ^^^^^ creates a temporary value which is freed while still in use
LL | f(x);
| ---- argument requires that borrow lasts for `'static`
LL | }
diff --git a/src/test/ui/statics/issue-44373.stderr b/src/test/ui/statics/issue-44373.stderr
index 6f92fbb1e..2d29dec88 100644
--- a/src/test/ui/statics/issue-44373.stderr
+++ b/src/test/ui/statics/issue-44373.stderr
@@ -2,7 +2,7 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/issue-44373.rs:4:42
|
LL | let _val: &'static [&'static u32] = &[&FOO];
- | ----------------------- ^^^^^^ creates a temporary which is freed while still in use
+ | ----------------------- ^^^^^^ creates a temporary value which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
LL | }
diff --git a/src/test/ui/stats/hir-stats.rs b/src/test/ui/stats/hir-stats.rs
index a24b3ada5..0b89d0b16 100644
--- a/src/test/ui/stats/hir-stats.rs
+++ b/src/test/ui/stats/hir-stats.rs
@@ -1,6 +1,7 @@
// check-pass
// compile-flags: -Zhir-stats
// only-x86_64
+// ignore-stage1 FIXME: remove after next bootstrap bump
// The aim here is to include at least one of every different type of top-level
// AST/HIR node reported by `-Zhir-stats`.
diff --git a/src/test/ui/stats/hir-stats.stderr b/src/test/ui/stats/hir-stats.stderr
index 1521b692a..15900bef7 100644
--- a/src/test/ui/stats/hir-stats.stderr
+++ b/src/test/ui/stats/hir-stats.stderr
@@ -2,124 +2,124 @@ ast-stats-1 PRE EXPANSION AST STATS
ast-stats-1 Name Accumulated Size Count Item Size
ast-stats-1 ----------------------------------------------------------------
ast-stats-1 ExprField 48 ( 0.6%) 1 48
-ast-stats-1 Crate 56 ( 0.7%) 1 56
-ast-stats-1 Attribute 64 ( 0.8%) 2 32
+ast-stats-1 GenericArgs 56 ( 0.8%) 1 56
+ast-stats-1 - AngleBracketed 56 ( 0.8%) 1
+ast-stats-1 Crate 56 ( 0.8%) 1 56
+ast-stats-1 Attribute 64 ( 0.9%) 2 32
ast-stats-1 - Normal 32 ( 0.4%) 1
ast-stats-1 - DocComment 32 ( 0.4%) 1
-ast-stats-1 GenericArgs 64 ( 0.8%) 1 64
-ast-stats-1 - AngleBracketed 64 ( 0.8%) 1
-ast-stats-1 Local 72 ( 0.9%) 1 72
-ast-stats-1 WherePredicate 72 ( 0.9%) 1 72
-ast-stats-1 - BoundPredicate 72 ( 0.9%) 1
-ast-stats-1 Arm 96 ( 1.1%) 2 48
-ast-stats-1 ForeignItem 96 ( 1.1%) 1 96
-ast-stats-1 - Fn 96 ( 1.1%) 1
-ast-stats-1 FieldDef 160 ( 1.9%) 2 80
-ast-stats-1 Stmt 160 ( 1.9%) 5 32
+ast-stats-1 Local 72 ( 1.0%) 1 72
+ast-stats-1 WherePredicate 72 ( 1.0%) 1 72
+ast-stats-1 - BoundPredicate 72 ( 1.0%) 1
+ast-stats-1 Arm 96 ( 1.3%) 2 48
+ast-stats-1 ForeignItem 96 ( 1.3%) 1 96
+ast-stats-1 - Fn 96 ( 1.3%) 1
+ast-stats-1 FieldDef 160 ( 2.2%) 2 80
+ast-stats-1 Stmt 160 ( 2.2%) 5 32
ast-stats-1 - Local 32 ( 0.4%) 1
ast-stats-1 - MacCall 32 ( 0.4%) 1
-ast-stats-1 - Expr 96 ( 1.1%) 3
-ast-stats-1 Param 160 ( 1.9%) 4 40
-ast-stats-1 FnDecl 200 ( 2.4%) 5 40
-ast-stats-1 Variant 240 ( 2.9%) 2 120
-ast-stats-1 Block 288 ( 3.4%) 6 48
-ast-stats-1 GenericBound 352 ( 4.2%) 4 88
-ast-stats-1 - Trait 352 ( 4.2%) 4
-ast-stats-1 AssocItem 416 ( 4.9%) 4 104
-ast-stats-1 - Type 208 ( 2.5%) 2
-ast-stats-1 - Fn 208 ( 2.5%) 2
-ast-stats-1 GenericParam 480 ( 5.7%) 5 96
-ast-stats-1 PathSegment 720 ( 8.6%) 30 24
-ast-stats-1 Expr 832 ( 9.9%) 8 104
-ast-stats-1 - Path 104 ( 1.2%) 1
-ast-stats-1 - Match 104 ( 1.2%) 1
-ast-stats-1 - Struct 104 ( 1.2%) 1
-ast-stats-1 - Lit 208 ( 2.5%) 2
-ast-stats-1 - Block 312 ( 3.7%) 3
-ast-stats-1 Pat 840 (10.0%) 7 120
-ast-stats-1 - Struct 120 ( 1.4%) 1
-ast-stats-1 - Wild 120 ( 1.4%) 1
-ast-stats-1 - Ident 600 ( 7.1%) 5
-ast-stats-1 Ty 1_344 (16.0%) 14 96
-ast-stats-1 - Rptr 96 ( 1.1%) 1
-ast-stats-1 - Ptr 96 ( 1.1%) 1
-ast-stats-1 - ImplicitSelf 192 ( 2.3%) 2
-ast-stats-1 - Path 960 (11.4%) 10
-ast-stats-1 Item 1_656 (19.7%) 9 184
-ast-stats-1 - Trait 184 ( 2.2%) 1
-ast-stats-1 - Enum 184 ( 2.2%) 1
-ast-stats-1 - ForeignMod 184 ( 2.2%) 1
-ast-stats-1 - Impl 184 ( 2.2%) 1
-ast-stats-1 - Fn 368 ( 4.4%) 2
-ast-stats-1 - Use 552 ( 6.6%) 3
+ast-stats-1 - Expr 96 ( 1.3%) 3
+ast-stats-1 Param 160 ( 2.2%) 4 40
+ast-stats-1 FnDecl 200 ( 2.7%) 5 40
+ast-stats-1 Variant 240 ( 3.2%) 2 120
+ast-stats-1 GenericBound 288 ( 3.9%) 4 72
+ast-stats-1 - Trait 288 ( 3.9%) 4
+ast-stats-1 Block 288 ( 3.9%) 6 48
+ast-stats-1 AssocItem 416 ( 5.6%) 4 104
+ast-stats-1 - Type 208 ( 2.8%) 2
+ast-stats-1 - Fn 208 ( 2.8%) 2
+ast-stats-1 GenericParam 480 ( 6.5%) 5 96
+ast-stats-1 Expr 576 ( 7.8%) 8 72
+ast-stats-1 - Path 72 ( 1.0%) 1
+ast-stats-1 - Match 72 ( 1.0%) 1
+ast-stats-1 - Struct 72 ( 1.0%) 1
+ast-stats-1 - Lit 144 ( 1.9%) 2
+ast-stats-1 - Block 216 ( 2.9%) 3
+ast-stats-1 Pat 616 ( 8.3%) 7 88
+ast-stats-1 - Struct 88 ( 1.2%) 1
+ast-stats-1 - Wild 88 ( 1.2%) 1
+ast-stats-1 - Ident 440 ( 5.9%) 5
+ast-stats-1 PathSegment 720 ( 9.7%) 30 24
+ast-stats-1 Ty 896 (12.1%) 14 64
+ast-stats-1 - Rptr 64 ( 0.9%) 1
+ast-stats-1 - Ptr 64 ( 0.9%) 1
+ast-stats-1 - ImplicitSelf 128 ( 1.7%) 2
+ast-stats-1 - Path 640 ( 8.6%) 10
+ast-stats-1 Item 1_656 (22.3%) 9 184
+ast-stats-1 - Trait 184 ( 2.5%) 1
+ast-stats-1 - Enum 184 ( 2.5%) 1
+ast-stats-1 - ForeignMod 184 ( 2.5%) 1
+ast-stats-1 - Impl 184 ( 2.5%) 1
+ast-stats-1 - Fn 368 ( 5.0%) 2
+ast-stats-1 - Use 552 ( 7.4%) 3
ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total 8_416
+ast-stats-1 Total 7_416
ast-stats-1
ast-stats-2 POST EXPANSION AST STATS
ast-stats-2 Name Accumulated Size Count Item Size
ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 ExprField 48 ( 0.5%) 1 48
-ast-stats-2 Crate 56 ( 0.6%) 1 56
-ast-stats-2 GenericArgs 64 ( 0.7%) 1 64
-ast-stats-2 - AngleBracketed 64 ( 0.7%) 1
-ast-stats-2 Local 72 ( 0.8%) 1 72
-ast-stats-2 WherePredicate 72 ( 0.8%) 1 72
-ast-stats-2 - BoundPredicate 72 ( 0.8%) 1
-ast-stats-2 Arm 96 ( 1.0%) 2 48
-ast-stats-2 ForeignItem 96 ( 1.0%) 1 96
-ast-stats-2 - Fn 96 ( 1.0%) 1
-ast-stats-2 InlineAsm 120 ( 1.3%) 1 120
-ast-stats-2 Attribute 128 ( 1.4%) 4 32
-ast-stats-2 - DocComment 32 ( 0.3%) 1
-ast-stats-2 - Normal 96 ( 1.0%) 3
-ast-stats-2 FieldDef 160 ( 1.7%) 2 80
-ast-stats-2 Stmt 160 ( 1.7%) 5 32
-ast-stats-2 - Local 32 ( 0.3%) 1
-ast-stats-2 - Semi 32 ( 0.3%) 1
-ast-stats-2 - Expr 96 ( 1.0%) 3
-ast-stats-2 Param 160 ( 1.7%) 4 40
-ast-stats-2 FnDecl 200 ( 2.2%) 5 40
-ast-stats-2 Variant 240 ( 2.6%) 2 120
-ast-stats-2 Block 288 ( 3.1%) 6 48
-ast-stats-2 GenericBound 352 ( 3.8%) 4 88
-ast-stats-2 - Trait 352 ( 3.8%) 4
-ast-stats-2 AssocItem 416 ( 4.5%) 4 104
-ast-stats-2 - Type 208 ( 2.3%) 2
-ast-stats-2 - Fn 208 ( 2.3%) 2
-ast-stats-2 GenericParam 480 ( 5.2%) 5 96
-ast-stats-2 PathSegment 792 ( 8.7%) 33 24
-ast-stats-2 Pat 840 ( 9.2%) 7 120
-ast-stats-2 - Struct 120 ( 1.3%) 1
-ast-stats-2 - Wild 120 ( 1.3%) 1
-ast-stats-2 - Ident 600 ( 6.6%) 5
-ast-stats-2 Expr 936 (10.2%) 9 104
-ast-stats-2 - Path 104 ( 1.1%) 1
-ast-stats-2 - Match 104 ( 1.1%) 1
-ast-stats-2 - Struct 104 ( 1.1%) 1
-ast-stats-2 - InlineAsm 104 ( 1.1%) 1
-ast-stats-2 - Lit 208 ( 2.3%) 2
-ast-stats-2 - Block 312 ( 3.4%) 3
-ast-stats-2 Ty 1_344 (14.7%) 14 96
-ast-stats-2 - Rptr 96 ( 1.0%) 1
-ast-stats-2 - Ptr 96 ( 1.0%) 1
-ast-stats-2 - ImplicitSelf 192 ( 2.1%) 2
-ast-stats-2 - Path 960 (10.5%) 10
-ast-stats-2 Item 2_024 (22.1%) 11 184
-ast-stats-2 - Trait 184 ( 2.0%) 1
-ast-stats-2 - Enum 184 ( 2.0%) 1
-ast-stats-2 - ExternCrate 184 ( 2.0%) 1
-ast-stats-2 - ForeignMod 184 ( 2.0%) 1
-ast-stats-2 - Impl 184 ( 2.0%) 1
-ast-stats-2 - Fn 368 ( 4.0%) 2
-ast-stats-2 - Use 736 ( 8.0%) 4
+ast-stats-2 ExprField 48 ( 0.6%) 1 48
+ast-stats-2 GenericArgs 56 ( 0.7%) 1 56
+ast-stats-2 - AngleBracketed 56 ( 0.7%) 1
+ast-stats-2 Crate 56 ( 0.7%) 1 56
+ast-stats-2 Local 72 ( 0.9%) 1 72
+ast-stats-2 WherePredicate 72 ( 0.9%) 1 72
+ast-stats-2 - BoundPredicate 72 ( 0.9%) 1
+ast-stats-2 Arm 96 ( 1.2%) 2 48
+ast-stats-2 ForeignItem 96 ( 1.2%) 1 96
+ast-stats-2 - Fn 96 ( 1.2%) 1
+ast-stats-2 InlineAsm 120 ( 1.5%) 1 120
+ast-stats-2 Attribute 128 ( 1.6%) 4 32
+ast-stats-2 - DocComment 32 ( 0.4%) 1
+ast-stats-2 - Normal 96 ( 1.2%) 3
+ast-stats-2 FieldDef 160 ( 2.0%) 2 80
+ast-stats-2 Stmt 160 ( 2.0%) 5 32
+ast-stats-2 - Local 32 ( 0.4%) 1
+ast-stats-2 - Semi 32 ( 0.4%) 1
+ast-stats-2 - Expr 96 ( 1.2%) 3
+ast-stats-2 Param 160 ( 2.0%) 4 40
+ast-stats-2 FnDecl 200 ( 2.5%) 5 40
+ast-stats-2 Variant 240 ( 3.0%) 2 120
+ast-stats-2 GenericBound 288 ( 3.6%) 4 72
+ast-stats-2 - Trait 288 ( 3.6%) 4
+ast-stats-2 Block 288 ( 3.6%) 6 48
+ast-stats-2 AssocItem 416 ( 5.1%) 4 104
+ast-stats-2 - Type 208 ( 2.6%) 2
+ast-stats-2 - Fn 208 ( 2.6%) 2
+ast-stats-2 GenericParam 480 ( 5.9%) 5 96
+ast-stats-2 Pat 616 ( 7.6%) 7 88
+ast-stats-2 - Struct 88 ( 1.1%) 1
+ast-stats-2 - Wild 88 ( 1.1%) 1
+ast-stats-2 - Ident 440 ( 5.4%) 5
+ast-stats-2 Expr 648 ( 8.0%) 9 72
+ast-stats-2 - Path 72 ( 0.9%) 1
+ast-stats-2 - Match 72 ( 0.9%) 1
+ast-stats-2 - Struct 72 ( 0.9%) 1
+ast-stats-2 - InlineAsm 72 ( 0.9%) 1
+ast-stats-2 - Lit 144 ( 1.8%) 2
+ast-stats-2 - Block 216 ( 2.7%) 3
+ast-stats-2 PathSegment 792 ( 9.8%) 33 24
+ast-stats-2 Ty 896 (11.0%) 14 64
+ast-stats-2 - Rptr 64 ( 0.8%) 1
+ast-stats-2 - Ptr 64 ( 0.8%) 1
+ast-stats-2 - ImplicitSelf 128 ( 1.6%) 2
+ast-stats-2 - Path 640 ( 7.9%) 10
+ast-stats-2 Item 2_024 (25.0%) 11 184
+ast-stats-2 - Trait 184 ( 2.3%) 1
+ast-stats-2 - Enum 184 ( 2.3%) 1
+ast-stats-2 - ExternCrate 184 ( 2.3%) 1
+ast-stats-2 - ForeignMod 184 ( 2.3%) 1
+ast-stats-2 - Impl 184 ( 2.3%) 1
+ast-stats-2 - Fn 368 ( 4.5%) 2
+ast-stats-2 - Use 736 ( 9.1%) 4
ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total 9_144
+ast-stats-2 Total 8_112
ast-stats-2
hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size
hir-stats ----------------------------------------------------------------
hir-stats ForeignItemRef 24 ( 0.3%) 1 24
-hir-stats Lifetime 32 ( 0.4%) 1 32
+hir-stats Lifetime 24 ( 0.3%) 1 24
hir-stats Mod 32 ( 0.4%) 1 32
hir-stats ExprField 40 ( 0.4%) 1 40
hir-stats TraitItemRef 56 ( 0.6%) 2 28
@@ -128,9 +128,6 @@ hir-stats Param 64 ( 0.7%) 2 32
hir-stats InlineAsm 72 ( 0.8%) 1 72
hir-stats ImplItemRef 72 ( 0.8%) 2 36
hir-stats Body 96 ( 1.1%) 3 32
-hir-stats GenericArg 96 ( 1.1%) 4 24
-hir-stats - Type 24 ( 0.3%) 1
-hir-stats - Lifetime 72 ( 0.8%) 3
hir-stats FieldDef 96 ( 1.1%) 2 48
hir-stats Arm 96 ( 1.1%) 2 48
hir-stats Stmt 96 ( 1.1%) 3 32
@@ -139,40 +136,43 @@ hir-stats - Semi 32 ( 0.4%) 1
hir-stats - Expr 32 ( 0.4%) 1
hir-stats FnDecl 120 ( 1.3%) 3 40
hir-stats Attribute 128 ( 1.4%) 4 32
+hir-stats GenericArg 128 ( 1.4%) 4 32
+hir-stats - Type 32 ( 0.4%) 1
+hir-stats - Lifetime 96 ( 1.1%) 3
hir-stats GenericArgs 144 ( 1.6%) 3 48
-hir-stats Variant 160 ( 1.8%) 2 80
+hir-stats Variant 176 ( 1.9%) 2 88
hir-stats GenericBound 192 ( 2.1%) 4 48
hir-stats - Trait 192 ( 2.1%) 4
hir-stats WherePredicate 192 ( 2.1%) 3 64
hir-stats - BoundPredicate 192 ( 2.1%) 3
hir-stats Block 288 ( 3.2%) 6 48
-hir-stats Pat 360 ( 3.9%) 5 72
+hir-stats Pat 360 ( 4.0%) 5 72
hir-stats - Wild 72 ( 0.8%) 1
hir-stats - Struct 72 ( 0.8%) 1
hir-stats - Binding 216 ( 2.4%) 3
hir-stats GenericParam 400 ( 4.4%) 5 80
-hir-stats Generics 560 ( 6.1%) 10 56
-hir-stats Ty 720 ( 7.9%) 15 48
+hir-stats Generics 560 ( 6.2%) 10 56
+hir-stats Ty 720 ( 8.0%) 15 48
hir-stats - Ptr 48 ( 0.5%) 1
hir-stats - Rptr 48 ( 0.5%) 1
-hir-stats - Path 624 ( 6.8%) 13
-hir-stats Expr 768 ( 8.4%) 12 64
+hir-stats - Path 624 ( 6.9%) 13
+hir-stats Expr 768 ( 8.5%) 12 64
hir-stats - Path 64 ( 0.7%) 1
hir-stats - Struct 64 ( 0.7%) 1
hir-stats - Match 64 ( 0.7%) 1
hir-stats - InlineAsm 64 ( 0.7%) 1
hir-stats - Lit 128 ( 1.4%) 2
hir-stats - Block 384 ( 4.2%) 6
-hir-stats Item 960 (10.5%) 12 80
+hir-stats Item 880 ( 9.7%) 11 80
hir-stats - Trait 80 ( 0.9%) 1
hir-stats - Enum 80 ( 0.9%) 1
hir-stats - ExternCrate 80 ( 0.9%) 1
hir-stats - ForeignMod 80 ( 0.9%) 1
hir-stats - Impl 80 ( 0.9%) 1
hir-stats - Fn 160 ( 1.8%) 2
-hir-stats - Use 400 ( 4.4%) 5
-hir-stats Path 1_280 (14.0%) 32 40
-hir-stats PathSegment 1_920 (21.0%) 40 48
+hir-stats - Use 320 ( 3.5%) 4
+hir-stats Path 1_240 (13.7%) 31 40
+hir-stats PathSegment 1_920 (21.2%) 40 48
hir-stats ----------------------------------------------------------------
-hir-stats Total 9_128
+hir-stats Total 9_048
hir-stats
diff --git a/src/test/ui/structs-enums/type-sizes.rs b/src/test/ui/structs-enums/type-sizes.rs
index 7a23f1363..63e2f3150 100644
--- a/src/test/ui/structs-enums/type-sizes.rs
+++ b/src/test/ui/structs-enums/type-sizes.rs
@@ -3,6 +3,7 @@
#![allow(non_camel_case_types)]
#![allow(dead_code)]
#![feature(never_type)]
+#![feature(pointer_is_aligned)]
use std::mem::size_of;
use std::num::NonZeroU8;
@@ -168,6 +169,18 @@ pub enum EnumManyVariant<X> {
_F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _FA, _FB, _FC, _FD, _FE, _FF,
}
+struct Reorder4 {
+ a: u32,
+ b: u8,
+ ary: [u8; 4],
+}
+
+struct Reorder2 {
+ a: u16,
+ b: u8,
+ ary: [u8; 6],
+}
+
pub fn main() {
assert_eq!(size_of::<u8>(), 1 as usize);
assert_eq!(size_of::<u32>(), 4 as usize);
@@ -249,4 +262,12 @@ pub fn main() {
assert_eq!(size_of::<EnumManyVariant<Option<NicheU16>>>(), 4);
assert_eq!(size_of::<EnumManyVariant<Option2<NicheU16,u8>>>(), 6);
assert_eq!(size_of::<EnumManyVariant<Option<(NicheU16,u8)>>>(), 6);
+
+
+ let v = Reorder4 {a: 0, b: 0, ary: [0; 4]};
+ assert_eq!(size_of::<Reorder4>(), 12);
+ assert!((&v.ary).as_ptr().is_aligned_to(4), "[u8; 4] should group with align-4 fields");
+ let v = Reorder2 {a: 0, b: 0, ary: [0; 6]};
+ assert_eq!(size_of::<Reorder2>(), 10);
+ assert!((&v.ary).as_ptr().is_aligned_to(2), "[u8; 6] should group with align-2 fields");
}
diff --git a/src/test/ui/structs/multi-line-fru-suggestion.rs b/src/test/ui/structs/multi-line-fru-suggestion.rs
new file mode 100644
index 000000000..7b2b13914
--- /dev/null
+++ b/src/test/ui/structs/multi-line-fru-suggestion.rs
@@ -0,0 +1,22 @@
+#[derive(Default)]
+struct Inner {
+ a: u8,
+ b: u8,
+}
+
+#[derive(Default)]
+struct Outer {
+ inner: Inner,
+ defaulted: u8,
+}
+
+fn main(){
+ Outer {
+ //~^ ERROR missing field `defaulted` in initializer of `Outer`
+ inner: Inner {
+ a: 1,
+ b: 2,
+ }
+ ..Default::default()
+ };
+}
diff --git a/src/test/ui/structs/multi-line-fru-suggestion.stderr b/src/test/ui/structs/multi-line-fru-suggestion.stderr
new file mode 100644
index 000000000..8bbd3ace7
--- /dev/null
+++ b/src/test/ui/structs/multi-line-fru-suggestion.stderr
@@ -0,0 +1,25 @@
+error[E0063]: missing field `defaulted` in initializer of `Outer`
+ --> $DIR/multi-line-fru-suggestion.rs:14:5
+ |
+LL | Outer {
+ | ^^^^^ missing `defaulted`
+ |
+note: this expression may have been misinterpreted as a `..` range expression
+ --> $DIR/multi-line-fru-suggestion.rs:16:16
+ |
+LL | inner: Inner {
+ | ________________^
+LL | | a: 1,
+LL | | b: 2,
+LL | | }
+ | |_________^ this expression does not end in a comma...
+LL | ..Default::default()
+ | ^^^^^^^^^^^^^^^^^^^^ ... so this is interpreted as a `..` range expression, instead of functional record update syntax
+help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
+ |
+LL | },
+ | +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0063`.
diff --git a/src/test/ui/structs/struct-fn-in-definition.rs b/src/test/ui/structs/struct-fn-in-definition.rs
index 5ae1b727d..7f48f55fe 100644
--- a/src/test/ui/structs/struct-fn-in-definition.rs
+++ b/src/test/ui/structs/struct-fn-in-definition.rs
@@ -28,6 +28,7 @@ enum E {
//~^ ERROR functions are not allowed in enum definitions
//~| HELP unlike in C++, Java, and C#, functions are declared in `impl` blocks
//~| HELP see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+ //~| HELP enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
}
fn main() {}
diff --git a/src/test/ui/structs/struct-fn-in-definition.stderr b/src/test/ui/structs/struct-fn-in-definition.stderr
index 472365c6e..439c86ec2 100644
--- a/src/test/ui/structs/struct-fn-in-definition.stderr
+++ b/src/test/ui/structs/struct-fn-in-definition.stderr
@@ -33,6 +33,7 @@ LL | fn foo() {}
|
= help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
= help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+ = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/structs/struct-record-suggestion.fixed b/src/test/ui/structs/struct-record-suggestion.fixed
index 49e38b196..d93a62185 100644
--- a/src/test/ui/structs/struct-record-suggestion.fixed
+++ b/src/test/ui/structs/struct-record-suggestion.fixed
@@ -7,9 +7,8 @@ struct A {
}
fn a() {
- let q = A { c: 5,..Default::default() };
- //~^ ERROR mismatched types
- //~| ERROR missing fields
+ let q = A { c: 5, ..Default::default() };
+ //~^ ERROR missing fields
//~| HELP separate the last named field with a comma
let r = A { c: 5, ..Default::default() };
assert_eq!(q, r);
@@ -21,7 +20,7 @@ struct B {
}
fn b() {
- let q = B { b: 1,..Default::default() };
+ let q = B { b: 1, ..Default::default() };
//~^ ERROR mismatched types
//~| HELP separate the last named field with a comma
let r = B { b: 1 };
diff --git a/src/test/ui/structs/struct-record-suggestion.rs b/src/test/ui/structs/struct-record-suggestion.rs
index 901f310c8..f0fd1c94e 100644
--- a/src/test/ui/structs/struct-record-suggestion.rs
+++ b/src/test/ui/structs/struct-record-suggestion.rs
@@ -8,8 +8,7 @@ struct A {
fn a() {
let q = A { c: 5..Default::default() };
- //~^ ERROR mismatched types
- //~| ERROR missing fields
+ //~^ ERROR missing fields
//~| HELP separate the last named field with a comma
let r = A { c: 5, ..Default::default() };
assert_eq!(q, r);
diff --git a/src/test/ui/structs/struct-record-suggestion.stderr b/src/test/ui/structs/struct-record-suggestion.stderr
index 66e9f021e..f4fd655e6 100644
--- a/src/test/ui/structs/struct-record-suggestion.stderr
+++ b/src/test/ui/structs/struct-record-suggestion.stderr
@@ -1,37 +1,38 @@
-error[E0308]: mismatched types
- --> $DIR/struct-record-suggestion.rs:10:20
- |
-LL | let q = A { c: 5..Default::default() };
- | ^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found struct `std::ops::Range`
- |
- = note: expected type `u64`
- found struct `std::ops::Range<{integer}>`
-
error[E0063]: missing fields `b` and `d` in initializer of `A`
--> $DIR/struct-record-suggestion.rs:10:13
|
LL | let q = A { c: 5..Default::default() };
| ^ missing `b` and `d`
|
+note: this expression may have been misinterpreted as a `..` range expression
+ --> $DIR/struct-record-suggestion.rs:10:20
+ |
+LL | let q = A { c: 5..Default::default() };
+ | ^^^^^^^^^^^^^^^^^^^^^
help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
|
-LL | let q = A { c: 5,..Default::default() };
+LL | let q = A { c: 5, ..Default::default() };
| +
error[E0308]: mismatched types
- --> $DIR/struct-record-suggestion.rs:24:20
+ --> $DIR/struct-record-suggestion.rs:23:20
|
LL | let q = B { b: 1..Default::default() };
| ^^^^^^^^^^^^^^^^^^^^^ expected `u32`, found struct `std::ops::Range`
|
= note: expected type `u32`
found struct `std::ops::Range<{integer}>`
+note: this expression may have been misinterpreted as a `..` range expression
+ --> $DIR/struct-record-suggestion.rs:23:20
+ |
+LL | let q = B { b: 1..Default::default() };
+ | ^^^^^^^^^^^^^^^^^^^^^
help: to set the remaining fields from `Default::default()`, separate the last named field with a comma
|
-LL | let q = B { b: 1,..Default::default() };
+LL | let q = B { b: 1, ..Default::default() };
| +
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
Some errors have detailed explanations: E0063, E0308.
For more information about an error, try `rustc --explain E0063`.
diff --git a/src/test/ui/structs/unresolved-struct-with-fru.rs b/src/test/ui/structs/unresolved-struct-with-fru.rs
new file mode 100644
index 000000000..c9fdca457
--- /dev/null
+++ b/src/test/ui/structs/unresolved-struct-with-fru.rs
@@ -0,0 +1,12 @@
+struct S {
+ a: u32,
+}
+
+fn main() {
+ let s1 = S { a: 1 };
+
+ let _ = || {
+ let s2 = Oops { a: 2, ..s1 };
+ //~^ ERROR cannot find struct, variant or union type `Oops` in this scope
+ };
+}
diff --git a/src/test/ui/structs/unresolved-struct-with-fru.stderr b/src/test/ui/structs/unresolved-struct-with-fru.stderr
new file mode 100644
index 000000000..a5796a222
--- /dev/null
+++ b/src/test/ui/structs/unresolved-struct-with-fru.stderr
@@ -0,0 +1,9 @@
+error[E0422]: cannot find struct, variant or union type `Oops` in this scope
+ --> $DIR/unresolved-struct-with-fru.rs:9:18
+ |
+LL | let s2 = Oops { a: 2, ..s1 };
+ | ^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0422`.
diff --git a/src/test/ui/suggestions/assoc-const-as-fn.rs b/src/test/ui/suggestions/assoc-const-as-fn.rs
new file mode 100644
index 000000000..4b4595dd5
--- /dev/null
+++ b/src/test/ui/suggestions/assoc-const-as-fn.rs
@@ -0,0 +1,18 @@
+unsafe fn pointer(v: usize, w: u32) {}
+
+pub trait UniformScalar {}
+impl UniformScalar for u32 {}
+
+pub trait GlUniformScalar: UniformScalar {
+ const FACTORY: unsafe fn(usize, Self) -> ();
+}
+impl GlUniformScalar for u32 {
+ const FACTORY: unsafe fn(usize, Self) -> () = pointer;
+}
+
+pub fn foo<T: UniformScalar>(value: T) {
+ <T as GlUniformScalar>::FACTORY(1, value);
+ //~^ ERROR the trait bound `T: GlUniformScalar` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/assoc-const-as-fn.stderr b/src/test/ui/suggestions/assoc-const-as-fn.stderr
new file mode 100644
index 000000000..3b6e947c5
--- /dev/null
+++ b/src/test/ui/suggestions/assoc-const-as-fn.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `T: GlUniformScalar` is not satisfied
+ --> $DIR/assoc-const-as-fn.rs:14:40
+ |
+LL | <T as GlUniformScalar>::FACTORY(1, value);
+ | ------------------------------- ^^^^^ the trait `GlUniformScalar` is not implemented for `T`
+ | |
+ | required by a bound introduced by this call
+ |
+help: consider further restricting this bound
+ |
+LL | pub fn foo<T: UniformScalar + GlUniformScalar>(value: T) {
+ | +++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/assoc_fn_without_self.stderr b/src/test/ui/suggestions/assoc_fn_without_self.stderr
index 88920b852..febdd6733 100644
--- a/src/test/ui/suggestions/assoc_fn_without_self.stderr
+++ b/src/test/ui/suggestions/assoc_fn_without_self.stderr
@@ -7,13 +7,18 @@ LL | foo();
help: consider using the associated function
|
LL | Self::foo();
- | ~~~~~~~~~
+ | ++++++
error[E0425]: cannot find function `bar` in this scope
--> $DIR/assoc_fn_without_self.rs:17:9
|
LL | bar();
| ^^^ not found in this scope
+ |
+help: consider using the associated function
+ |
+LL | self.bar();
+ | +++++
error[E0425]: cannot find function `baz` in this scope
--> $DIR/assoc_fn_without_self.rs:18:9
@@ -24,7 +29,7 @@ LL | baz(2, 3);
help: consider using the associated function
|
LL | Self::baz(2, 3);
- | ~~~~~~~~~
+ | ++++++
error[E0425]: cannot find function `foo` in this scope
--> $DIR/assoc_fn_without_self.rs:14:13
diff --git a/src/test/ui/suggestions/borrow-for-loop-head.stderr b/src/test/ui/suggestions/borrow-for-loop-head.stderr
index 1059e3d15..0cc8994fe 100644
--- a/src/test/ui/suggestions/borrow-for-loop-head.stderr
+++ b/src/test/ui/suggestions/borrow-for-loop-head.stderr
@@ -12,6 +12,7 @@ error[E0382]: use of moved value: `a`
LL | let a = vec![1, 2, 3];
| - move occurs because `a` has type `Vec<i32>`, which does not implement the `Copy` trait
LL | for i in &a {
+ | ----------- inside of this loop
LL | for j in a {
| ^ `a` moved due to this implicit call to `.into_iter()`, in previous iteration of loop
|
diff --git a/src/test/ui/suggestions/core-std-import-order-issue-83564.stderr b/src/test/ui/suggestions/core-std-import-order-issue-83564.stderr
index ce85d93b9..e4e1fc591 100644
--- a/src/test/ui/suggestions/core-std-import-order-issue-83564.stderr
+++ b/src/test/ui/suggestions/core-std-import-order-issue-83564.stderr
@@ -2,7 +2,7 @@ error[E0433]: failed to resolve: use of undeclared type `NonZeroU32`
--> $DIR/core-std-import-order-issue-83564.rs:8:14
|
LL | let _x = NonZeroU32::new(5).unwrap();
- | ^^^^^^^^^^ not found in this scope
+ | ^^^^^^^^^^ use of undeclared type `NonZeroU32`
|
help: consider importing one of these items
|
diff --git a/src/test/ui/suggestions/crate-or-module-typo.stderr b/src/test/ui/suggestions/crate-or-module-typo.stderr
index e8250c9fa..98b88b4fb 100644
--- a/src/test/ui/suggestions/crate-or-module-typo.stderr
+++ b/src/test/ui/suggestions/crate-or-module-typo.stderr
@@ -20,12 +20,6 @@ help: there is a crate or module with a similar name
LL | use bar::bar;
| ~~~
-error[E0433]: failed to resolve: use of undeclared crate or module `bar`
- --> $DIR/crate-or-module-typo.rs:6:20
- |
-LL | pub fn bar() { bar::baz(); }
- | ^^^ use of undeclared crate or module `bar`
-
error[E0433]: failed to resolve: use of undeclared crate or module `st`
--> $DIR/crate-or-module-typo.rs:14:10
|
@@ -37,6 +31,12 @@ help: there is a crate or module with a similar name
LL | bar: std::cell::Cell<bool>
| ~~~
+error[E0433]: failed to resolve: use of undeclared crate or module `bar`
+ --> $DIR/crate-or-module-typo.rs:6:20
+ |
+LL | pub fn bar() { bar::baz(); }
+ | ^^^ use of undeclared crate or module `bar`
+
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0432, E0433.
diff --git a/src/test/ui/suggestions/dont-suggest-ufcs-for-const.rs b/src/test/ui/suggestions/dont-suggest-ufcs-for-const.rs
new file mode 100644
index 000000000..06cf243f1
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-ufcs-for-const.rs
@@ -0,0 +1,4 @@
+fn main() {
+ 1_u32.MAX();
+ //~^ ERROR no method named `MAX` found for type `u32` in the current scope
+}
diff --git a/src/test/ui/suggestions/dont-suggest-ufcs-for-const.stderr b/src/test/ui/suggestions/dont-suggest-ufcs-for-const.stderr
new file mode 100644
index 000000000..0d9543e0b
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-ufcs-for-const.stderr
@@ -0,0 +1,9 @@
+error[E0599]: no method named `MAX` found for type `u32` in the current scope
+ --> $DIR/dont-suggest-ufcs-for-const.rs:2:11
+ |
+LL | 1_u32.MAX();
+ | ^^^ method not found in `u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
index 77cef485f..34ff59a9b 100644
--- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -78,20 +78,21 @@ LL | impl<P: Deref<Target: Unpin>> Pin<P> {
error[E0308]: mismatched types
--> $DIR/expected-boxed-future-isnt-pinned.rs:28:5
|
-LL | fn zap() -> BoxFuture<'static, i32> {
- | ----------------------- expected `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>` because of return type
LL | / async {
LL | | 42
LL | | }
- | |_____^ expected struct `Pin`, found opaque type
- |
- ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
- |
-LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
- | ------------------------------- the found opaque type
- |
- = note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
- found opaque type `impl Future<Output = {integer}>`
+ | | ^
+ | | |
+ | |_____expected struct `Pin`, found `async` block
+ | arguments to this function are incorrect
+ |
+ = note: expected struct `Pin<Box<dyn Future<Output = i32> + Send>>`
+ found `async` block `[async block@$DIR/expected-boxed-future-isnt-pinned.rs:28:5: 30:6]`
+note: function defined here
+ --> $SRC_DIR/core/src/future/mod.rs:LL:COL
+ |
+LL | pub const fn identity_future<O, Fut: Future<Output = O>>(f: Fut) -> Fut {
+ | ^^^^^^^^^^^^^^^
help: you need to pin and box this expression
|
LL ~ Box::pin(async {
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
index 597dc61c3..d0ddb34d9 100644
--- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
+++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
@@ -1,23 +1,3 @@
-error[E0423]: expected value, found struct variant `E::B`
- --> $DIR/fn-or-tuple-struct-without-args.rs:36:16
- |
-LL | A(usize),
- | -------- similarly named tuple variant `A` defined here
-LL | B { a: usize },
- | -------------- `E::B` defined here
-...
-LL | let _: E = E::B;
- | ^^^^
- |
-help: use struct literal syntax instead
- |
-LL | let _: E = E::B { a: val };
- | ~~~~~~~~~~~~~~~
-help: a tuple variant with a similar name exists
- |
-LL | let _: E = E::A;
- | ~
-
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:29:20
|
@@ -144,6 +124,12 @@ help: use parentheses to construct this tuple variant
LL | let _: E = E::A(/* usize */);
| +++++++++++++
+error[E0533]: expected value, found struct variant `E::B`
+ --> $DIR/fn-or-tuple-struct-without-args.rs:36:16
+ |
+LL | let _: E = E::B;
+ | ^^^^ not a value
+
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:37:20
|
@@ -293,5 +279,5 @@ LL | let _: usize = closure();
error: aborting due to 17 previous errors
-Some errors have detailed explanations: E0308, E0423, E0615.
+Some errors have detailed explanations: E0308, E0533, E0615.
For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/if-let-typo.stderr b/src/test/ui/suggestions/if-let-typo.stderr
index 3d9ac40ec..02148b7f7 100644
--- a/src/test/ui/suggestions/if-let-typo.stderr
+++ b/src/test/ui/suggestions/if-let-typo.stderr
@@ -25,12 +25,22 @@ error[E0308]: mismatched types
|
LL | if Some(x) = foo {}
| ^^^^^^^^^^^^^ expected `bool`, found `()`
+ |
+help: consider adding `let`
+ |
+LL | if let Some(x) = foo {}
+ | +++
error[E0308]: mismatched types
--> $DIR/if-let-typo.rs:6:8
|
LL | if Some(foo) = bar {}
| ^^^^^^^^^^^^^^^ expected `bool`, found `()`
+ |
+help: consider adding `let`
+ |
+LL | if let Some(foo) = bar {}
+ | +++
error[E0308]: mismatched types
--> $DIR/if-let-typo.rs:7:8
@@ -51,6 +61,11 @@ error[E0308]: mismatched types
|
LL | if Some(3) = foo {}
| ^^^^^^^^^^^^^ expected `bool`, found `()`
+ |
+help: consider adding `let`
+ |
+LL | if let Some(3) = foo {}
+ | +++
error: aborting due to 7 previous errors
diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs b/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs
index fe291e021..a1a51c481 100644
--- a/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs
+++ b/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs
@@ -2,20 +2,67 @@
// gate-test-anonymous_lifetime_in_impl_trait
// Verify the behaviour of `feature(anonymous_lifetime_in_impl_trait)`.
-fn f(_: impl Iterator<Item = &'_ ()>) {}
-//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
+mod elided {
+ fn f(_: impl Iterator<Item = &()>) {}
+ //~^ ERROR anonymous lifetimes in `impl Trait` are unstable
-fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
-//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
-//~| ERROR missing lifetime specifier
+ fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
+ //~^ ERROR anonymous lifetimes in `impl Trait` are unstable
+ //~| ERROR missing lifetime specifier
-// Anonymous lifetimes in async fn are already allowed.
-// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
-async fn h(_: impl Iterator<Item = &'_ ()>) {}
+ // Anonymous lifetimes in async fn are already allowed.
+ // This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
+ async fn h(_: impl Iterator<Item = &()>) {}
-// Anonymous lifetimes in async fn are already allowed.
-// But that lifetime does not participate in resolution.
-async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
-//~^ ERROR missing lifetime specifier
+ // Anonymous lifetimes in async fn are already allowed.
+ // But that lifetime does not participate in resolution.
+ async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
+ //~^ ERROR missing lifetime specifier
+}
+
+mod underscore {
+ fn f(_: impl Iterator<Item = &'_ ()>) {}
+ //~^ ERROR anonymous lifetimes in `impl Trait` are unstable
+
+ fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
+ //~^ ERROR anonymous lifetimes in `impl Trait` are unstable
+ //~| ERROR missing lifetime specifier
+
+ // Anonymous lifetimes in async fn are already allowed.
+ // This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
+ async fn h(_: impl Iterator<Item = &'_ ()>) {}
+
+ // Anonymous lifetimes in async fn are already allowed.
+ // But that lifetime does not participate in resolution.
+ async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
+ //~^ ERROR missing lifetime specifier
+}
+
+mod alone_in_path {
+ trait Foo<'a> { fn next(&mut self) -> Option<&'a ()>; }
+
+ fn f(_: impl Foo) {}
+ //~^ ERROR anonymous lifetimes in `impl Trait` are unstable
+
+ fn g(mut x: impl Foo) -> Option<&()> { x.next() }
+ //~^ ERROR anonymous lifetimes in `impl Trait` are unstable
+ //~| ERROR missing lifetime specifier
+}
+
+mod in_path {
+ trait Foo<'a, T> { fn next(&mut self) -> Option<&'a T>; }
+
+ fn f(_: impl Foo<()>) {}
+ //~^ ERROR anonymous lifetimes in `impl Trait` are unstable
+
+ fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
+ //~^ ERROR anonymous lifetimes in `impl Trait` are unstable
+ //~| ERROR missing lifetime specifier
+}
+
+// This must not err, as the `&` actually resolves to `'a`.
+fn resolved_anonymous<'a, T>(f: impl Fn(&'a str) -> &T) {
+ f("f")
+}
fn main() {}
diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
index 9833da13f..50806a672 100644
--- a/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
+++ b/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
@@ -1,52 +1,172 @@
error[E0106]: missing lifetime specifier
- --> $DIR/impl-trait-missing-lifetime-gated.rs:8:50
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:9:54
|
-LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
- | ^^ expected named lifetime parameter
+LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
-LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
- | ~~~~~~~
+LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&'static ()> { x.next() }
+ | +++++++
error[E0106]: missing lifetime specifier
- --> $DIR/impl-trait-missing-lifetime-gated.rs:18:56
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:19:60
|
-LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
- | ^^ expected named lifetime parameter
+LL | async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
-LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
- | ~~~~~~~
+LL | async fn i(mut x: impl Iterator<Item = &()>) -> Option<&'static ()> { x.next() }
+ | +++++++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:27:58
+ |
+LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
+ | ^^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
+ | ~~~~~~~
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:37:64
+ |
+LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
+ | ^^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
+ | ~~~~~~~
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:47:37
+ |
+LL | fn g(mut x: impl Foo) -> Option<&()> { x.next() }
+ | ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn g(mut x: impl Foo) -> Option<&'static ()> { x.next() }
+ | +++++++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:58:41
+ |
+LL | fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
+ | ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn g(mut x: impl Foo<()>) -> Option<&'static ()> { x.next() }
+ | +++++++
+
+error[E0658]: anonymous lifetimes in `impl Trait` are unstable
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:6:35
+ |
+LL | fn f(_: impl Iterator<Item = &()>) {}
+ | ^ expected named lifetime parameter
+ |
+ = help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
+help: consider introducing a named lifetime parameter
+ |
+LL | fn f<'a>(_: impl Iterator<Item = &'a ()>) {}
+ | ++++ ++
+
+error[E0658]: anonymous lifetimes in `impl Trait` are unstable
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:9:39
+ |
+LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
+ | ^ expected named lifetime parameter
+ |
+ = help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
+help: consider introducing a named lifetime parameter
+ |
+LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&()> { x.next() }
+ | ++++ ++
+
+error[E0658]: anonymous lifetimes in `impl Trait` are unstable
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:24:35
+ |
+LL | fn f(_: impl Iterator<Item = &'_ ()>) {}
+ | ^^ expected named lifetime parameter
+ |
+ = help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
+help: consider introducing a named lifetime parameter
+ |
+LL | fn f<'a>(_: impl Iterator<Item = &'a ()>) {}
+ | ++++ ~~
+
+error[E0658]: anonymous lifetimes in `impl Trait` are unstable
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:27:39
+ |
+LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
+ | ^^ expected named lifetime parameter
+ |
+ = help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
+help: consider introducing a named lifetime parameter
+ |
+LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'_ ()> { x.next() }
+ | ++++ ~~
+
+error[E0658]: anonymous lifetimes in `impl Trait` are unstable
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:44:18
+ |
+LL | fn f(_: impl Foo) {}
+ | ^^^ expected named lifetime parameter
+ |
+ = help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
+help: consider introducing a named lifetime parameter
+ |
+LL | fn f<'a>(_: impl Foo<'a>) {}
+ | ++++ ++++
+
+error[E0658]: anonymous lifetimes in `impl Trait` are unstable
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:47:22
+ |
+LL | fn g(mut x: impl Foo) -> Option<&()> { x.next() }
+ | ^^^ expected named lifetime parameter
+ |
+ = help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
+help: consider introducing a named lifetime parameter
+ |
+LL | fn g<'a>(mut x: impl Foo<'a>) -> Option<&()> { x.next() }
+ | ++++ ++++
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
- --> $DIR/impl-trait-missing-lifetime-gated.rs:5:31
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:55:22
|
-LL | fn f(_: impl Iterator<Item = &'_ ()>) {}
- | ^^ expected named lifetime parameter
+LL | fn f(_: impl Foo<()>) {}
+ | ^ expected named lifetime parameter
|
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
help: consider introducing a named lifetime parameter
|
-LL | fn f<'a>(_: impl Iterator<Item = &'_'a ()>) {}
- | ++++ ++
+LL | fn f<'a>(_: impl Foo<'a, ()>) {}
+ | ++++ +++
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
- --> $DIR/impl-trait-missing-lifetime-gated.rs:8:31
+ --> $DIR/impl-trait-missing-lifetime-gated.rs:58:26
|
-LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
- | ^^ expected named lifetime parameter
+LL | fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
+ | ^ expected named lifetime parameter
|
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
help: consider introducing a named lifetime parameter
|
-LL | fn g<'a>(x: impl Iterator<Item = &'_'a ()>) -> Option<&'_ ()> { x.next() }
- | ++++ ++
+LL | fn g<'a>(mut x: impl Foo<'a, ()>) -> Option<&()> { x.next() }
+ | ++++ +++
-error: aborting due to 4 previous errors
+error: aborting due to 14 previous errors
Some errors have detailed explanations: E0106, E0658.
For more information about an error, try `rustc --explain E0106`.
diff --git a/src/test/ui/suggestions/inner_type2.rs b/src/test/ui/suggestions/inner_type2.rs
index c56ea7c03..fac68c053 100644
--- a/src/test/ui/suggestions/inner_type2.rs
+++ b/src/test/ui/suggestions/inner_type2.rs
@@ -22,5 +22,5 @@ fn main() {
let item = std::mem::MaybeUninit::new(Struct { p: 42_u32 });
item.method();
//~^ ERROR no method named `method` found for union `MaybeUninit` in the current scope [E0599]
- //~| HELP if this `MaybeUninit::<Struct<u32>>` has been initialized, use one of the `assume_init` methods to access the inner value
+ //~| HELP if this `MaybeUninit<Struct<u32>>` has been initialized, use one of the `assume_init` methods to access the inner value
}
diff --git a/src/test/ui/suggestions/inner_type2.stderr b/src/test/ui/suggestions/inner_type2.stderr
index eddfd9d63..984366123 100644
--- a/src/test/ui/suggestions/inner_type2.stderr
+++ b/src/test/ui/suggestions/inner_type2.stderr
@@ -17,7 +17,7 @@ error[E0599]: no method named `method` found for union `MaybeUninit` in the curr
LL | item.method();
| ^^^^^^ method not found in `MaybeUninit<Struct<u32>>`
|
- = help: if this `MaybeUninit::<Struct<u32>>` has been initialized, use one of the `assume_init` methods to access the inner value
+ = help: if this `MaybeUninit<Struct<u32>>` has been initialized, use one of the `assume_init` methods to access the inner value
note: the method `method` exists on the type `Struct<u32>`
--> $DIR/inner_type2.rs:6:5
|
diff --git a/src/test/ui/suggestions/issue-102354.stderr b/src/test/ui/suggestions/issue-102354.stderr
index 4f76c5f2e..08d4b9955 100644
--- a/src/test/ui/suggestions/issue-102354.stderr
+++ b/src/test/ui/suggestions/issue-102354.stderr
@@ -2,7 +2,10 @@ error[E0599]: no method named `func` found for type `i32` in the current scope
--> $DIR/issue-102354.rs:9:7
|
LL | x.func();
- | ^^^^ this is an associated function, not a method
+ | --^^^^--
+ | | |
+ | | this is an associated function, not a method
+ | help: use associated function syntax instead: `i32::func()`
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in the trait `Trait`
@@ -10,14 +13,6 @@ note: the candidate is defined in the trait `Trait`
|
LL | fn func() {}
| ^^^^^^^^^
-help: use associated function syntax instead
- |
-LL | i32::func();
- | ~~~~~~~~~
-help: disambiguate the associated function for the candidate
- |
-LL | <i32 as Trait>::func(x);
- | ~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
diff --git a/src/test/ui/suggestions/issue-104086-suggest-let.rs b/src/test/ui/suggestions/issue-104086-suggest-let.rs
new file mode 100644
index 000000000..d22ad27d0
--- /dev/null
+++ b/src/test/ui/suggestions/issue-104086-suggest-let.rs
@@ -0,0 +1,30 @@
+fn main() {
+ x = x = x;
+ //~^ ERROR cannot find value `x` in this scope
+ //~| ERROR cannot find value `x` in this scope
+ //~| ERROR cannot find value `x` in this scope
+
+ x = y = y = y;
+ //~^ ERROR cannot find value `y` in this scope
+ //~| ERROR cannot find value `y` in this scope
+ //~| ERROR cannot find value `y` in this scope
+ //~| ERROR cannot find value `x` in this scope
+
+ x = y = y;
+ //~^ ERROR cannot find value `x` in this scope
+ //~| ERROR cannot find value `y` in this scope
+ //~| ERROR cannot find value `y` in this scope
+
+ x = x = y;
+ //~^ ERROR cannot find value `x` in this scope
+ //~| ERROR cannot find value `x` in this scope
+ //~| ERROR cannot find value `y` in this scope
+
+ x = x; // will suggest add `let`
+ //~^ ERROR cannot find value `x` in this scope
+ //~| ERROR cannot find value `x` in this scope
+
+ x = y // will suggest add `let`
+ //~^ ERROR cannot find value `x` in this scope
+ //~| ERROR cannot find value `y` in this scope
+}
diff --git a/src/test/ui/suggestions/issue-104086-suggest-let.stderr b/src/test/ui/suggestions/issue-104086-suggest-let.stderr
new file mode 100644
index 000000000..fb4ea3121
--- /dev/null
+++ b/src/test/ui/suggestions/issue-104086-suggest-let.stderr
@@ -0,0 +1,135 @@
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:2:5
+ |
+LL | x = x = x;
+ | ^
+ |
+help: you might have meant to introduce a new binding
+ |
+LL | let x = x = x;
+ | +++
+
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:2:9
+ |
+LL | x = x = x;
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:2:13
+ |
+LL | x = x = x;
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:7:5
+ |
+LL | x = y = y = y;
+ | ^
+ |
+help: you might have meant to introduce a new binding
+ |
+LL | let x = y = y = y;
+ | +++
+
+error[E0425]: cannot find value `y` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:7:9
+ |
+LL | x = y = y = y;
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:7:13
+ |
+LL | x = y = y = y;
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:7:17
+ |
+LL | x = y = y = y;
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:13:5
+ |
+LL | x = y = y;
+ | ^
+ |
+help: you might have meant to introduce a new binding
+ |
+LL | let x = y = y;
+ | +++
+
+error[E0425]: cannot find value `y` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:13:9
+ |
+LL | x = y = y;
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:13:13
+ |
+LL | x = y = y;
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:18:5
+ |
+LL | x = x = y;
+ | ^
+ |
+help: you might have meant to introduce a new binding
+ |
+LL | let x = x = y;
+ | +++
+
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:18:9
+ |
+LL | x = x = y;
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:18:13
+ |
+LL | x = x = y;
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:23:5
+ |
+LL | x = x; // will suggest add `let`
+ | ^
+ |
+help: you might have meant to introduce a new binding
+ |
+LL | let x = x; // will suggest add `let`
+ | +++
+
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:23:9
+ |
+LL | x = x; // will suggest add `let`
+ | ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:27:5
+ |
+LL | x = y // will suggest add `let`
+ | ^
+ |
+help: you might have meant to introduce a new binding
+ |
+LL | let x = y // will suggest add `let`
+ | +++
+
+error[E0425]: cannot find value `y` in this scope
+ --> $DIR/issue-104086-suggest-let.rs:27:9
+ |
+LL | x = y // will suggest add `let`
+ | ^ not found in this scope
+
+error: aborting due to 17 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/suggestions/issue-104287.rs b/src/test/ui/suggestions/issue-104287.rs
new file mode 100644
index 000000000..b7601a548
--- /dev/null
+++ b/src/test/ui/suggestions/issue-104287.rs
@@ -0,0 +1,9 @@
+// The purpose of this test is not to validate the output of the compiler.
+// Instead, it ensures the suggestion is generated without performing an arithmetic overflow.
+
+fn main() {
+ let x = not_found; //~ ERROR cannot find value `not_found` in this scope
+ simd_gt::<()>(x);
+ //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
+ //~| ERROR cannot find function `simd_gt` in this scope
+}
diff --git a/src/test/ui/suggestions/issue-104287.stderr b/src/test/ui/suggestions/issue-104287.stderr
new file mode 100644
index 000000000..4b302dd65
--- /dev/null
+++ b/src/test/ui/suggestions/issue-104287.stderr
@@ -0,0 +1,36 @@
+error[E0425]: cannot find value `not_found` in this scope
+ --> $DIR/issue-104287.rs:5:13
+ |
+LL | let x = not_found;
+ | ^^^^^^^^^ not found in this scope
+
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/issue-104287.rs:6:5
+ |
+LL | simd_gt::<()>(x);
+ | ^^^^^^^------ help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: associated function defined here, with 0 generic parameters
+ --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/ord.rs:LL:COL
+ |
+LL | fn simd_gt(self, other: Self) -> Self::Mask;
+ | ^^^^^^^
+
+error[E0425]: cannot find function `simd_gt` in this scope
+ --> $DIR/issue-104287.rs:6:5
+ |
+LL | simd_gt::<()>(x);
+ | ^^^^^^^ not found in this scope
+ |
+help: use the `.` operator to call the method `SimdPartialOrd::simd_gt` on `[type error]`
+ |
+LL - simd_gt::<()>(x);
+LL + x.simd_gt();
+ |
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0107, E0425.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/suggestions/issue-84700.stderr b/src/test/ui/suggestions/issue-84700.stderr
index b36d8aba3..ac9f5ab0b 100644
--- a/src/test/ui/suggestions/issue-84700.stderr
+++ b/src/test/ui/suggestions/issue-84700.stderr
@@ -7,15 +7,13 @@ LL | Cow,
LL | FarmAnimal::Cow(_) => "moo".to_string(),
| ^^^^^^^^^^^^^^^^^^ help: use this syntax instead: `FarmAnimal::Cow`
-error[E0532]: expected tuple struct or tuple variant, found struct variant `FarmAnimal::Chicken`
+error[E0164]: expected tuple struct or tuple variant, found struct variant `FarmAnimal::Chicken`
--> $DIR/issue-84700.rs:17:9
|
-LL | Chicken { num_eggs: usize },
- | --------------------------- `FarmAnimal::Chicken` defined here
-...
LL | FarmAnimal::Chicken(_) => "cluck, cluck!".to_string(),
- | ^^^^^^^^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `FarmAnimal::Chicken { num_eggs }`
+ | ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0532`.
+Some errors have detailed explanations: E0164, E0532.
+For more information about an error, try `rustc --explain E0164`.
diff --git a/src/test/ui/suggestions/issue-99240-2.stderr b/src/test/ui/suggestions/issue-99240-2.stderr
index 2af60f597..260df8565 100644
--- a/src/test/ui/suggestions/issue-99240-2.stderr
+++ b/src/test/ui/suggestions/issue-99240-2.stderr
@@ -5,12 +5,12 @@ LL | Unit,
| ---- enum variant `Alias::Unit` defined here
...
LL | Alias::
- | _____^
- | |_____|
+ | ______^
+ | | _____|
| ||
LL | || Unit();
| ||________^_- call expression requires function
- | |_________|
+ | |________|
|
|
help: `Alias::Unit` is a unit enum variant, and does not take parentheses to be constructed
diff --git a/src/test/ui/suggestions/missing-lifetime-specifier.stderr b/src/test/ui/suggestions/missing-lifetime-specifier.stderr
index 10fb28c18..997bbb5e9 100644
--- a/src/test/ui/suggestions/missing-lifetime-specifier.stderr
+++ b/src/test/ui/suggestions/missing-lifetime-specifier.stderr
@@ -166,8 +166,8 @@ LL | pub union Qux<'t, 'k, I> {
| ^^^ -- --
help: add missing lifetime argument
|
-LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
- | ++++
+LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+ | +++++++++
error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:39:44
@@ -184,8 +184,8 @@ LL | pub union Qux<'t, 'k, I> {
| ^^^ -- --
help: add missing lifetime argument
|
-LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
- | ++++
+LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+ | +++++++++
error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:39:44
@@ -202,8 +202,8 @@ LL | pub union Qux<'t, 'k, I> {
| ^^^ -- --
help: add missing lifetime argument
|
-LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
- | ++++
+LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+ | +++++++++
error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:39:44
@@ -256,8 +256,8 @@ LL | trait Tar<'t, 'k, I> {}
| ^^^ -- --
help: add missing lifetime argument
|
-LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
- | ++++
+LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+ | +++++++++
error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:47:45
@@ -274,8 +274,8 @@ LL | trait Tar<'t, 'k, I> {}
| ^^^ -- --
help: add missing lifetime argument
|
-LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
- | ++++
+LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+ | +++++++++
error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:47:45
@@ -292,8 +292,8 @@ LL | trait Tar<'t, 'k, I> {}
| ^^^ -- --
help: add missing lifetime argument
|
-LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
- | ++++
+LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+ | +++++++++
error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:47:45
diff --git a/src/test/ui/suggestions/multibyte-escapes.rs b/src/test/ui/suggestions/multibyte-escapes.rs
index fd5d46a4e..c41051862 100644
--- a/src/test/ui/suggestions/multibyte-escapes.rs
+++ b/src/test/ui/suggestions/multibyte-escapes.rs
@@ -2,17 +2,17 @@
fn main() {
b'µ';
- //~^ ERROR: non-ASCII character in byte constant
+ //~^ ERROR: non-ASCII character in byte literal
//~| HELP: if you meant to use the unicode code point for 'µ', use a \xHH escape
- //~| NOTE: byte constant must be ASCII
+ //~| NOTE: must be ASCII
b'å­—';
- //~^ ERROR: non-ASCII character in byte constant
+ //~^ ERROR: non-ASCII character in byte literal
//~| NOTE: this multibyte character does not fit into a single byte
- //~| NOTE: byte constant must be ASCII
+ //~| NOTE: must be ASCII
b"å­—";
- //~^ ERROR: non-ASCII character in byte constant
+ //~^ ERROR: non-ASCII character in byte string literal
//~| HELP: if you meant to use the UTF-8 encoding of 'å­—', use \xHH escapes
- //~| NOTE: byte constant must be ASCII
+ //~| NOTE: must be ASCII
}
diff --git a/src/test/ui/suggestions/multibyte-escapes.stderr b/src/test/ui/suggestions/multibyte-escapes.stderr
index 6e26bc1f0..1e7c43e65 100644
--- a/src/test/ui/suggestions/multibyte-escapes.stderr
+++ b/src/test/ui/suggestions/multibyte-escapes.stderr
@@ -1,28 +1,28 @@
-error: non-ASCII character in byte constant
+error: non-ASCII character in byte literal
--> $DIR/multibyte-escapes.rs:4:7
|
LL | b'µ';
- | ^ byte constant must be ASCII
+ | ^ must be ASCII
|
help: if you meant to use the unicode code point for 'µ', use a \xHH escape
|
LL | b'\xB5';
| ~~~~
-error: non-ASCII character in byte constant
+error: non-ASCII character in byte literal
--> $DIR/multibyte-escapes.rs:9:7
|
LL | b'å­—';
| ^^
| |
- | byte constant must be ASCII
+ | must be ASCII
| this multibyte character does not fit into a single byte
-error: non-ASCII character in byte constant
+error: non-ASCII character in byte string literal
--> $DIR/multibyte-escapes.rs:14:7
|
LL | b"å­—";
- | ^^ byte constant must be ASCII
+ | ^^ must be ASCII
|
help: if you meant to use the UTF-8 encoding of 'å­—', use \xHH escapes
|
diff --git a/src/test/ui/suggestions/option-to-bool.rs b/src/test/ui/suggestions/option-to-bool.rs
new file mode 100644
index 000000000..2a1823b15
--- /dev/null
+++ b/src/test/ui/suggestions/option-to-bool.rs
@@ -0,0 +1,9 @@
+#![cfg_attr(let_chains, feature(let_chains))]
+
+fn foo(x: Option<i32>) {
+ if true && x {}
+ //~^ ERROR mismatched types
+ //~| HELP use `Option::is_some` to test if the `Option` has a value
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/option-to-bool.stderr b/src/test/ui/suggestions/option-to-bool.stderr
new file mode 100644
index 000000000..57a934b83
--- /dev/null
+++ b/src/test/ui/suggestions/option-to-bool.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+ --> $DIR/option-to-bool.rs:4:16
+ |
+LL | if true && x {}
+ | ^ expected `bool`, found enum `Option`
+ |
+ = note: expected type `bool`
+ found enum `Option<i32>`
+help: use `Option::is_some` to test if the `Option` has a value
+ |
+LL | if true && x.is_some() {}
+ | ++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/ref-pattern-binding.fixed b/src/test/ui/suggestions/ref-pattern-binding.fixed
new file mode 100644
index 000000000..c36040eec
--- /dev/null
+++ b/src/test/ui/suggestions/ref-pattern-binding.fixed
@@ -0,0 +1,19 @@
+// run-rustfix
+#![allow(unused)]
+
+struct S {
+ f: String,
+}
+
+fn main() {
+ let ref _moved @ ref _from = String::from("foo"); //~ ERROR
+ let ref _moved @ ref _from = String::from("foo"); //~ ERROR
+ let ref _moved @ ref _from = String::from("foo"); //~ ERROR
+ //~^ ERROR
+ let ref _moved @ ref _from = String::from("foo"); // ok
+ let ref _moved @ S { ref f } = S { f: String::from("foo") }; //~ ERROR
+ let ref _moved @ S { ref f } = S { f: String::from("foo") }; //~ ERROR
+ //~^ ERROR
+ let ref _moved @ S { ref f } = S { f: String::from("foo") }; // ok
+ let ref _moved @ S { ref f } = S { f: String::from("foo") }; //~ ERROR
+}
diff --git a/src/test/ui/suggestions/ref-pattern-binding.rs b/src/test/ui/suggestions/ref-pattern-binding.rs
new file mode 100644
index 000000000..c0d4feb03
--- /dev/null
+++ b/src/test/ui/suggestions/ref-pattern-binding.rs
@@ -0,0 +1,19 @@
+// run-rustfix
+#![allow(unused)]
+
+struct S {
+ f: String,
+}
+
+fn main() {
+ let _moved @ _from = String::from("foo"); //~ ERROR
+ let _moved @ ref _from = String::from("foo"); //~ ERROR
+ let ref _moved @ _from = String::from("foo"); //~ ERROR
+ //~^ ERROR
+ let ref _moved @ ref _from = String::from("foo"); // ok
+ let _moved @ S { f } = S { f: String::from("foo") }; //~ ERROR
+ let ref _moved @ S { f } = S { f: String::from("foo") }; //~ ERROR
+ //~^ ERROR
+ let ref _moved @ S { ref f } = S { f: String::from("foo") }; // ok
+ let _moved @ S { ref f } = S { f: String::from("foo") }; //~ ERROR
+}
diff --git a/src/test/ui/suggestions/ref-pattern-binding.stderr b/src/test/ui/suggestions/ref-pattern-binding.stderr
new file mode 100644
index 000000000..10447ba70
--- /dev/null
+++ b/src/test/ui/suggestions/ref-pattern-binding.stderr
@@ -0,0 +1,107 @@
+error: borrow of moved value
+ --> $DIR/ref-pattern-binding.rs:10:9
+ |
+LL | let _moved @ ref _from = String::from("foo");
+ | ------^^^---------
+ | | |
+ | | value borrowed here after move
+ | value moved into `_moved` here
+ | move occurs because `_moved` has type `String` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref _moved @ ref _from = String::from("foo");
+ | +++
+
+error: cannot move out of value because it is borrowed
+ --> $DIR/ref-pattern-binding.rs:11:9
+ |
+LL | let ref _moved @ _from = String::from("foo");
+ | ----------^^^-----
+ | | |
+ | | value moved into `_from` here
+ | value borrowed, by `_moved`, here
+
+error: cannot move out of value because it is borrowed
+ --> $DIR/ref-pattern-binding.rs:15:9
+ |
+LL | let ref _moved @ S { f } = S { f: String::from("foo") };
+ | ----------^^^^^^^-^^
+ | | |
+ | | value moved into `f` here
+ | value borrowed, by `_moved`, here
+
+error: borrow of moved value
+ --> $DIR/ref-pattern-binding.rs:18:9
+ |
+LL | let _moved @ S { ref f } = S { f: String::from("foo") };
+ | ------^^^^^^^-----^^
+ | | |
+ | | value borrowed here after move
+ | value moved into `_moved` here
+ | move occurs because `_moved` has type `S` which does not implement the `Copy` trait
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref _moved @ S { ref f } = S { f: String::from("foo") };
+ | +++
+
+error[E0382]: use of moved value
+ --> $DIR/ref-pattern-binding.rs:9:9
+ |
+LL | let _moved @ _from = String::from("foo");
+ | ^^^^^^ ----- ------------------- move occurs because value has type `String`, which does not implement the `Copy` trait
+ | | |
+ | | value moved here
+ | value used here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref _moved @ ref _from = String::from("foo");
+ | +++ +++
+
+error[E0382]: borrow of moved value
+ --> $DIR/ref-pattern-binding.rs:11:9
+ |
+LL | let ref _moved @ _from = String::from("foo");
+ | ^^^^^^^^^^ ----- ------------------- move occurs because value has type `String`, which does not implement the `Copy` trait
+ | | |
+ | | value moved here
+ | value borrowed here after move
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref _moved @ ref _from = String::from("foo");
+ | +++
+
+error[E0382]: use of partially moved value
+ --> $DIR/ref-pattern-binding.rs:14:9
+ |
+LL | let _moved @ S { f } = S { f: String::from("foo") };
+ | ^^^^^^ - value partially moved here
+ | |
+ | value used here after partial move
+ |
+ = note: partial move occurs because value has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref _moved @ S { ref f } = S { f: String::from("foo") };
+ | +++ +++
+
+error[E0382]: borrow of partially moved value
+ --> $DIR/ref-pattern-binding.rs:15:9
+ |
+LL | let ref _moved @ S { f } = S { f: String::from("foo") };
+ | ^^^^^^^^^^ - value partially moved here
+ | |
+ | value borrowed here after partial move
+ |
+ = note: partial move occurs because value has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref _moved @ S { ref f } = S { f: String::from("foo") };
+ | +++
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-deref.fixed b/src/test/ui/suggestions/suggest-assoc-fn-call-deref.fixed
new file mode 100644
index 000000000..8d96cf590
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-deref.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+
+#![allow(unused)]
+
+struct Foo<T>(T);
+
+impl<T> Foo<T> {
+ fn test() -> i32 { 1 }
+}
+
+fn main() {
+ let x = Box::new(Foo(1i32));
+ Foo::<i32>::test();
+ //~^ ERROR no method named `test` found for struct `Box<Foo<i32>>` in the current scope
+}
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-deref.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-deref.rs
new file mode 100644
index 000000000..186901f75
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-deref.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+
+#![allow(unused)]
+
+struct Foo<T>(T);
+
+impl<T> Foo<T> {
+ fn test() -> i32 { 1 }
+}
+
+fn main() {
+ let x = Box::new(Foo(1i32));
+ x.test();
+ //~^ ERROR no method named `test` found for struct `Box<Foo<i32>>` in the current scope
+}
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-deref.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-deref.stderr
new file mode 100644
index 000000000..00fb96f03
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-deref.stderr
@@ -0,0 +1,19 @@
+error[E0599]: no method named `test` found for struct `Box<Foo<i32>>` in the current scope
+ --> $DIR/suggest-assoc-fn-call-deref.rs:13:7
+ |
+LL | x.test();
+ | --^^^^--
+ | | |
+ | | this is an associated function, not a method
+ | help: use associated function syntax instead: `Foo::<i32>::test()`
+ |
+ = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `Foo<T>`
+ --> $DIR/suggest-assoc-fn-call-deref.rs:8:5
+ |
+LL | fn test() -> i32 { 1 }
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs
new file mode 100644
index 000000000..a39b8711d
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.rs
@@ -0,0 +1,11 @@
+struct GenericAssocMethod<T>(T);
+
+impl<T> GenericAssocMethod<T> {
+ fn default_hello() {}
+}
+
+fn main() {
+ let x = GenericAssocMethod(33);
+ x.default_hello();
+ //~^ ERROR no method named `default_hello` found
+}
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr
new file mode 100644
index 000000000..c247e73b3
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr
@@ -0,0 +1,22 @@
+error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope
+ --> $DIR/suggest-assoc-fn-call-with-turbofish-placeholder.rs:9:7
+ |
+LL | struct GenericAssocMethod<T>(T);
+ | ---------------------------- method `default_hello` not found for this struct
+...
+LL | x.default_hello();
+ | --^^^^^^^^^^^^^--
+ | | |
+ | | this is an associated function, not a method
+ | help: use associated function syntax instead: `GenericAssocMethod::<_>::default_hello()`
+ |
+ = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `GenericAssocMethod<T>`
+ --> $DIR/suggest-assoc-fn-call-with-turbofish-placeholder.rs:4:5
+ |
+LL | fn default_hello() {}
+ | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr
index 996d57731..7c9f0b6c2 100644
--- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr
@@ -2,10 +2,10 @@ error[E0599]: no method named `hello` found for struct `RefMut<'_, HasAssocMetho
--> $DIR/suggest-assoc-fn-call-with-turbofish-through-deref.rs:11:11
|
LL | state.hello();
- | ------^^^^^
+ | ------^^^^^--
| | |
| | this is an associated function, not a method
- | help: use associated function syntax instead: `HasAssocMethod::hello`
+ | help: use associated function syntax instead: `HasAssocMethod::hello()`
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in an impl for the type `HasAssocMethod`
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed
new file mode 100644
index 000000000..02dd0715c
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.fixed
@@ -0,0 +1,26 @@
+// run-rustfix
+
+struct GenericAssocMethod<T>(T);
+
+impl<T> GenericAssocMethod<T> {
+ fn default_hello() {}
+ fn self_ty_hello(_: Self) {}
+ fn self_ty_ref_hello(_: &Self) {}
+}
+
+fn main() {
+ // Test for inferred types
+ let x = GenericAssocMethod(33);
+ GenericAssocMethod::<_>::self_ty_ref_hello(&x);
+ //~^ ERROR no method named `self_ty_ref_hello` found
+ GenericAssocMethod::<_>::self_ty_hello(x);
+ //~^ ERROR no method named `self_ty_hello` found
+ // Test for known types
+ let y = GenericAssocMethod(33i32);
+ GenericAssocMethod::<i32>::default_hello();
+ //~^ ERROR no method named `default_hello` found
+ GenericAssocMethod::<i32>::self_ty_ref_hello(&y);
+ //~^ ERROR no method named `self_ty_ref_hello` found
+ GenericAssocMethod::<i32>::self_ty_hello(y);
+ //~^ ERROR no method named `self_ty_hello` found
+}
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs
index 2a829db53..1d0ca8e78 100644
--- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs
@@ -1,11 +1,26 @@
+// run-rustfix
+
struct GenericAssocMethod<T>(T);
impl<T> GenericAssocMethod<T> {
fn default_hello() {}
+ fn self_ty_hello(_: Self) {}
+ fn self_ty_ref_hello(_: &Self) {}
}
fn main() {
- let x = GenericAssocMethod(33i32);
- x.default_hello();
+ // Test for inferred types
+ let x = GenericAssocMethod(33);
+ x.self_ty_ref_hello();
+ //~^ ERROR no method named `self_ty_ref_hello` found
+ x.self_ty_hello();
+ //~^ ERROR no method named `self_ty_hello` found
+ // Test for known types
+ let y = GenericAssocMethod(33i32);
+ y.default_hello();
//~^ ERROR no method named `default_hello` found
+ y.self_ty_ref_hello();
+ //~^ ERROR no method named `self_ty_ref_hello` found
+ y.self_ty_hello();
+ //~^ ERROR no method named `self_ty_hello` found
}
diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr
index 3fb418b1c..92b03fc77 100644
--- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr
+++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr
@@ -1,22 +1,98 @@
+error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope
+ --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:14:7
+ |
+LL | struct GenericAssocMethod<T>(T);
+ | ---------------------------- method `self_ty_ref_hello` not found for this struct
+...
+LL | x.self_ty_ref_hello();
+ | --^^^^^^^^^^^^^^^^^--
+ | | |
+ | | this is an associated function, not a method
+ | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_ref_hello(&x)`
+ |
+ = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `GenericAssocMethod<T>`
+ --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:8:5
+ |
+LL | fn self_ty_ref_hello(_: &Self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope
+ --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:16:7
+ |
+LL | struct GenericAssocMethod<T>(T);
+ | ---------------------------- method `self_ty_hello` not found for this struct
+...
+LL | x.self_ty_hello();
+ | --^^^^^^^^^^^^^--
+ | | |
+ | | this is an associated function, not a method
+ | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_hello(x)`
+ |
+ = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `GenericAssocMethod<T>`
+ --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:7:5
+ |
+LL | fn self_ty_hello(_: Self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod<i32>` in the current scope
- --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:9:7
+ --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:20:7
|
LL | struct GenericAssocMethod<T>(T);
| ---------------------------- method `default_hello` not found for this struct
...
-LL | x.default_hello();
- | --^^^^^^^^^^^^^
+LL | y.default_hello();
+ | --^^^^^^^^^^^^^--
| | |
| | this is an associated function, not a method
- | help: use associated function syntax instead: `GenericAssocMethod::<i32>::default_hello`
+ | help: use associated function syntax instead: `GenericAssocMethod::<i32>::default_hello()`
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: the candidate is defined in an impl for the type `GenericAssocMethod<T>`
- --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5
+ --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:6:5
|
LL | fn default_hello() {}
| ^^^^^^^^^^^^^^^^^^
-error: aborting due to previous error
+error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod<i32>` in the current scope
+ --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:22:7
+ |
+LL | struct GenericAssocMethod<T>(T);
+ | ---------------------------- method `self_ty_ref_hello` not found for this struct
+...
+LL | y.self_ty_ref_hello();
+ | --^^^^^^^^^^^^^^^^^--
+ | | |
+ | | this is an associated function, not a method
+ | help: use associated function syntax instead: `GenericAssocMethod::<i32>::self_ty_ref_hello(&y)`
+ |
+ = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `GenericAssocMethod<T>`
+ --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:8:5
+ |
+LL | fn self_ty_ref_hello(_: &Self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod<i32>` in the current scope
+ --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:24:7
+ |
+LL | struct GenericAssocMethod<T>(T);
+ | ---------------------------- method `self_ty_hello` not found for this struct
+...
+LL | y.self_ty_hello();
+ | --^^^^^^^^^^^^^--
+ | | |
+ | | this is an associated function, not a method
+ | help: use associated function syntax instead: `GenericAssocMethod::<i32>::self_ty_hello(y)`
+ |
+ = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `GenericAssocMethod<T>`
+ --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:7:5
+ |
+LL | fn self_ty_hello(_: Self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/suggestions/suggest-remove-refs-3.stderr b/src/test/ui/suggestions/suggest-remove-refs-3.stderr
index 4d0732427..31cca323d 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-3.stderr
+++ b/src/test/ui/suggestions/suggest-remove-refs-3.stderr
@@ -2,8 +2,8 @@ error[E0277]: `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterat
--> $DIR/suggest-remove-refs-3.rs:6:19
|
LL | for (i, _) in & & &
- | ___________________^
- | |___________________|
+ | ____________________^
+ | | ___________________|
| ||
LL | || & &v
| ||___________- help: consider removing 5 leading `&`-references
diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
index f03b42bbe..70c4b210d 100644
--- a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs
@@ -10,18 +10,19 @@ fn test() {
let _i: i16 = TryFrom::try_from(0_i32).unwrap();
//~^ ERROR failed to resolve: use of undeclared type
- //~| NOTE not found in this scope
+ //~| NOTE use of undeclared type
//~| NOTE 'std::convert::TryFrom' is included in the prelude starting in Edition 2021
//~| NOTE 'core::convert::TryFrom' is included in the prelude starting in Edition 2021
let _i: i16 = TryInto::try_into(0_i32).unwrap();
//~^ ERROR failed to resolve: use of undeclared type
- //~| NOTE not found in this scope
+ //~| NOTE use of undeclared type
//~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021
//~| NOTE 'core::convert::TryInto' is included in the prelude starting in Edition 2021
let _v: Vec<_> = FromIterator::from_iter(&[1]);
//~^ ERROR failed to resolve: use of undeclared type
+ //~| NOTE use of undeclared type
//~| NOTE 'std::iter::FromIterator' is included in the prelude starting in Edition 2021
//~| NOTE 'core::iter::FromIterator' is included in the prelude starting in Edition 2021
}
diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
index 86f48716b..3d1f24923 100644
--- a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
+++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr
@@ -2,7 +2,7 @@ error[E0433]: failed to resolve: use of undeclared type `TryFrom`
--> $DIR/suggest-tryinto-edition-change.rs:11:19
|
LL | let _i: i16 = TryFrom::try_from(0_i32).unwrap();
- | ^^^^^^^ not found in this scope
+ | ^^^^^^^ use of undeclared type `TryFrom`
|
= note: 'std::convert::TryFrom' is included in the prelude starting in Edition 2021
= note: 'core::convert::TryFrom' is included in the prelude starting in Edition 2021
@@ -17,7 +17,7 @@ error[E0433]: failed to resolve: use of undeclared type `TryInto`
--> $DIR/suggest-tryinto-edition-change.rs:17:19
|
LL | let _i: i16 = TryInto::try_into(0_i32).unwrap();
- | ^^^^^^^ not found in this scope
+ | ^^^^^^^ use of undeclared type `TryInto`
|
= note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
= note: 'core::convert::TryInto' is included in the prelude starting in Edition 2021
@@ -32,12 +32,7 @@ error[E0433]: failed to resolve: use of undeclared type `FromIterator`
--> $DIR/suggest-tryinto-edition-change.rs:23:22
|
LL | let _v: Vec<_> = FromIterator::from_iter(&[1]);
- | ^^^^^^^^^^^^
- |
- ::: $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
- |
-LL | pub trait IntoIterator {
- | ---------------------- similarly named trait `IntoIterator` defined here
+ | ^^^^^^^^^^^^ use of undeclared type `FromIterator`
|
= note: 'std::iter::FromIterator' is included in the prelude starting in Edition 2021
= note: 'core::iter::FromIterator' is included in the prelude starting in Edition 2021
diff --git a/src/test/ui/suggestions/suggest_print_over_printf.rs b/src/test/ui/suggestions/suggest_print_over_printf.rs
new file mode 100644
index 000000000..124ddec50
--- /dev/null
+++ b/src/test/ui/suggestions/suggest_print_over_printf.rs
@@ -0,0 +1,8 @@
+// Suggest print macro when user erroneously uses printf
+
+fn main() {
+ let x = 4;
+ printf("%d", x);
+ //~^ ERROR cannot find function `printf` in this scope
+ //~| HELP you may have meant to use the `print` macro
+}
diff --git a/src/test/ui/suggestions/suggest_print_over_printf.stderr b/src/test/ui/suggestions/suggest_print_over_printf.stderr
new file mode 100644
index 000000000..1214bec16
--- /dev/null
+++ b/src/test/ui/suggestions/suggest_print_over_printf.stderr
@@ -0,0 +1,14 @@
+error[E0425]: cannot find function `printf` in this scope
+ --> $DIR/suggest_print_over_printf.rs:5:5
+ |
+LL | printf("%d", x);
+ | ^^^^^^ not found in this scope
+ |
+help: you may have meant to use the `print` macro
+ |
+LL | print!("%d", x);
+ | ~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/suggestions/try-removing-the-field.rs b/src/test/ui/suggestions/try-removing-the-field.rs
index 9d0573ca2..1b7289b22 100644
--- a/src/test/ui/suggestions/try-removing-the-field.rs
+++ b/src/test/ui/suggestions/try-removing-the-field.rs
@@ -14,4 +14,19 @@ fn use_foo(x: Foo) -> i32 {
return foo;
}
+// issue #105028, suggest removing the field only for shorthand
+fn use_match(x: Foo) {
+ match x {
+ Foo { foo: unused, .. } => { //~ WARNING unused variable
+ //~| help: if this is intentional, prefix it with an underscore
+ }
+ }
+
+ match x {
+ Foo { foo, .. } => { //~ WARNING unused variable
+ //~| help: try removing the field
+ }
+ }
+}
+
fn main() {}
diff --git a/src/test/ui/suggestions/try-removing-the-field.stderr b/src/test/ui/suggestions/try-removing-the-field.stderr
index 448a2c3d2..7a6013d4a 100644
--- a/src/test/ui/suggestions/try-removing-the-field.stderr
+++ b/src/test/ui/suggestions/try-removing-the-field.stderr
@@ -8,5 +8,19 @@ LL | let Foo { foo, bar, .. } = x;
|
= note: `#[warn(unused_variables)]` on by default
-warning: 1 warning emitted
+warning: unused variable: `unused`
+ --> $DIR/try-removing-the-field.rs:20:20
+ |
+LL | Foo { foo: unused, .. } => {
+ | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused`
+
+warning: unused variable: `foo`
+ --> $DIR/try-removing-the-field.rs:26:15
+ |
+LL | Foo { foo, .. } => {
+ | ^^^-
+ | |
+ | help: try removing the field
+
+warning: 3 warnings emitted
diff --git a/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs
new file mode 100644
index 000000000..c1a944562
--- /dev/null
+++ b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let _: f64 = 0..10; //~ ERROR mismatched types
+ let _: f64 = 1..; //~ ERROR mismatched types
+ let _: f64 = ..10; //~ ERROR mismatched types
+ let _: f64 = std::ops::Range { start: 0, end: 1 }; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr
new file mode 100644
index 000000000..773f1392a
--- /dev/null
+++ b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr
@@ -0,0 +1,59 @@
+error[E0308]: mismatched types
+ --> $DIR/unnecessary_dot_for_floating_point_literal.rs:2:18
+ |
+LL | let _: f64 = 0..10;
+ | --- ^^^^^ expected `f64`, found struct `std::ops::Range`
+ | |
+ | expected due to this
+ |
+ = note: expected type `f64`
+ found struct `std::ops::Range<{integer}>`
+help: remove the unnecessary `.` operator for a floating point literal
+ |
+LL | let _: f64 = 0.10;
+ | ~
+
+error[E0308]: mismatched types
+ --> $DIR/unnecessary_dot_for_floating_point_literal.rs:3:18
+ |
+LL | let _: f64 = 1..;
+ | --- ^^^ expected `f64`, found struct `RangeFrom`
+ | |
+ | expected due to this
+ |
+ = note: expected type `f64`
+ found struct `RangeFrom<{integer}>`
+help: remove the unnecessary `.` operator for a floating point literal
+ |
+LL | let _: f64 = 1.;
+ | ~
+
+error[E0308]: mismatched types
+ --> $DIR/unnecessary_dot_for_floating_point_literal.rs:4:18
+ |
+LL | let _: f64 = ..10;
+ | --- ^^^^ expected `f64`, found struct `RangeTo`
+ | |
+ | expected due to this
+ |
+ = note: expected type `f64`
+ found struct `RangeTo<{integer}>`
+help: remove the unnecessary `.` operator and add an integer part for a floating point literal
+ |
+LL | let _: f64 = 0.10;
+ | ~~
+
+error[E0308]: mismatched types
+ --> $DIR/unnecessary_dot_for_floating_point_literal.rs:5:18
+ |
+LL | let _: f64 = std::ops::Range { start: 0, end: 1 };
+ | --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `f64`, found struct `std::ops::Range`
+ | |
+ | expected due to this
+ |
+ = note: expected type `f64`
+ found struct `std::ops::Range<{integer}>`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/target-feature/invalid-attribute.stderr b/src/test/ui/target-feature/invalid-attribute.stderr
index 889ced975..a2adfc67f 100644
--- a/src/test/ui/target-feature/invalid-attribute.stderr
+++ b/src/test/ui/target-feature/invalid-attribute.stderr
@@ -4,36 +4,6 @@ error: malformed `target_feature` attribute input
LL | #[target_feature = "+sse2"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]`
-error: the feature named `foo` is not valid for this target
- --> $DIR/invalid-attribute.rs:19:18
- |
-LL | #[target_feature(enable = "foo")]
- | ^^^^^^^^^^^^^^ `foo` is not valid for this target
-
-error: malformed `target_feature` attribute input
- --> $DIR/invalid-attribute.rs:22:18
- |
-LL | #[target_feature(bar)]
- | ^^^ help: must be of the form: `enable = ".."`
-
-error: malformed `target_feature` attribute input
- --> $DIR/invalid-attribute.rs:24:18
- |
-LL | #[target_feature(disable = "baz")]
- | ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
-
-error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
- --> $DIR/invalid-attribute.rs:28:1
- |
-LL | #[target_feature(enable = "sse2")]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL | fn bar() {}
- | -------- not an `unsafe` function
- |
- = note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information
- = help: add `#![feature(target_feature_11)]` to the crate attributes to enable
-
error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:34:1
|
@@ -92,12 +62,6 @@ LL |
LL | trait Baz {}
| ------------ not a function definition
-error: cannot use `#[inline(always)]` with `#[target_feature]`
- --> $DIR/invalid-attribute.rs:67:1
- |
-LL | #[inline(always)]
- | ^^^^^^^^^^^^^^^^^
-
error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:85:5
|
@@ -119,6 +83,42 @@ LL |
LL | || {};
| ----- not a function definition
+error: the feature named `foo` is not valid for this target
+ --> $DIR/invalid-attribute.rs:19:18
+ |
+LL | #[target_feature(enable = "foo")]
+ | ^^^^^^^^^^^^^^ `foo` is not valid for this target
+
+error: malformed `target_feature` attribute input
+ --> $DIR/invalid-attribute.rs:22:18
+ |
+LL | #[target_feature(bar)]
+ | ^^^ help: must be of the form: `enable = ".."`
+
+error: malformed `target_feature` attribute input
+ --> $DIR/invalid-attribute.rs:24:18
+ |
+LL | #[target_feature(disable = "baz")]
+ | ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
+
+error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
+ --> $DIR/invalid-attribute.rs:28:1
+ |
+LL | #[target_feature(enable = "sse2")]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | fn bar() {}
+ | -------- not an `unsafe` function
+ |
+ = note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information
+ = help: add `#![feature(target_feature_11)]` to the crate attributes to enable
+
+error: cannot use `#[inline(always)]` with `#[target_feature]`
+ --> $DIR/invalid-attribute.rs:67:1
+ |
+LL | #[inline(always)]
+ | ^^^^^^^^^^^^^^^^^
+
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
--> $DIR/invalid-attribute.rs:77:5
|
diff --git a/src/test/ui/target-feature/tied-features-cli.one.stderr b/src/test/ui/target-feature/tied-features-cli.one.stderr
index 0cc901eec..b4b50d981 100644
--- a/src/test/ui/target-feature/tied-features-cli.one.stderr
+++ b/src/test/ui/target-feature/tied-features-cli.one.stderr
@@ -1,4 +1,4 @@
-error: target features paca, pacg must all be enabled or disabled together
+error: the target features paca, pacg must all be either enabled or disabled together
error: aborting due to previous error
diff --git a/src/test/ui/target-feature/tied-features-cli.three.stderr b/src/test/ui/target-feature/tied-features-cli.three.stderr
index 0cc901eec..b4b50d981 100644
--- a/src/test/ui/target-feature/tied-features-cli.three.stderr
+++ b/src/test/ui/target-feature/tied-features-cli.three.stderr
@@ -1,4 +1,4 @@
-error: target features paca, pacg must all be enabled or disabled together
+error: the target features paca, pacg must all be either enabled or disabled together
error: aborting due to previous error
diff --git a/src/test/ui/target-feature/tied-features-cli.two.stderr b/src/test/ui/target-feature/tied-features-cli.two.stderr
index 0cc901eec..b4b50d981 100644
--- a/src/test/ui/target-feature/tied-features-cli.two.stderr
+++ b/src/test/ui/target-feature/tied-features-cli.two.stderr
@@ -1,4 +1,4 @@
-error: target features paca, pacg must all be enabled or disabled together
+error: the target features paca, pacg must all be either enabled or disabled together
error: aborting due to previous error
diff --git a/src/test/ui/test-attrs/test-thread-capture.run.stdout b/src/test/ui/test-attrs/test-thread-capture.run.stdout
index c712a78af..513c8cf2a 100644
--- a/src/test/ui/test-attrs/test-thread-capture.run.stdout
+++ b/src/test/ui/test-attrs/test-thread-capture.run.stdout
@@ -10,7 +10,7 @@ fee
fie
foe
fum
-thread 'main' panicked at 'explicit panic', $DIR/test-thread-capture.rs:32:5
+thread 'thready_fail' panicked at 'explicit panic', $DIR/test-thread-capture.rs:32:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/src/test/ui/test-attrs/test-thread-nocapture.run.stderr b/src/test/ui/test-attrs/test-thread-nocapture.run.stderr
index 0a12a0528..8c905d1af 100644
--- a/src/test/ui/test-attrs/test-thread-nocapture.run.stderr
+++ b/src/test/ui/test-attrs/test-thread-nocapture.run.stderr
@@ -1,2 +1,2 @@
-thread 'main' panicked at 'explicit panic', $DIR/test-thread-nocapture.rs:32:5
+thread 'thready_fail' panicked at 'explicit panic', $DIR/test-thread-nocapture.rs:32:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/src/test/ui/threads-sendsync/mpsc_stress.rs b/src/test/ui/threads-sendsync/mpsc_stress.rs
index a889542fe..c2e1912de 100644
--- a/src/test/ui/threads-sendsync/mpsc_stress.rs
+++ b/src/test/ui/threads-sendsync/mpsc_stress.rs
@@ -64,9 +64,11 @@ fn shared_close_sender_does_not_lose_messages_iter() {
#[test]
fn shared_close_sender_does_not_lose_messages() {
- for _ in 0..10000 {
- shared_close_sender_does_not_lose_messages_iter();
- }
+ with_minimum_timer_resolution(|| {
+ for _ in 0..10000 {
+ shared_close_sender_does_not_lose_messages_iter();
+ }
+ });
}
@@ -96,17 +98,11 @@ fn concurrent_recv_timeout_and_upgrade_iter() {
#[test]
fn concurrent_recv_timeout_and_upgrade() {
- // FIXME: fix and enable
- if true { return }
-
- // at the moment of writing this test fails like this:
- // thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
- // left: `4561387584`,
- // right: `0`', libstd/sync/mpsc/shared.rs:253:13
-
- for _ in 0..10000 {
- concurrent_recv_timeout_and_upgrade_iter();
- }
+ with_minimum_timer_resolution(|| {
+ for _ in 0..10000 {
+ concurrent_recv_timeout_and_upgrade_iter();
+ }
+ });
}
@@ -159,7 +155,46 @@ fn concurrent_writes_iter() {
#[test]
fn concurrent_writes() {
- for _ in 0..100 {
- concurrent_writes_iter();
+ with_minimum_timer_resolution(|| {
+ for _ in 0..100 {
+ concurrent_writes_iter();
+ }
+ });
+}
+
+#[cfg(windows)]
+pub mod timeapi {
+ #![allow(non_snake_case)]
+ use std::ffi::c_uint;
+
+ pub const TIMERR_NOERROR: c_uint = 0;
+
+ #[link(name = "winmm")]
+ extern "system" {
+ pub fn timeBeginPeriod(uPeriod: c_uint) -> c_uint;
+ pub fn timeEndPeriod(uPeriod: c_uint) -> c_uint;
+ }
+}
+
+/// Window's minimum sleep time can be as much as 16ms.
+// This function evaluates the closure with this resolution
+// set as low as possible.
+///
+/// This takes the above test's duration from 10000*16/1000/60=2.67 minutes to ~16 seconds.
+fn with_minimum_timer_resolution(f: impl Fn()) {
+ #[cfg(windows)]
+ unsafe {
+ let ret = timeapi::timeBeginPeriod(1);
+ assert_eq!(ret, timeapi::TIMERR_NOERROR);
+
+ f();
+
+ let ret = timeapi::timeEndPeriod(1);
+ assert_eq!(ret, timeapi::TIMERR_NOERROR);
+ }
+
+ #[cfg(not(windows))]
+ {
+ f();
}
}
diff --git a/src/test/ui/track-diagnostics/track.rs b/src/test/ui/track-diagnostics/track.rs
new file mode 100644
index 000000000..61b9137ea
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track.rs
@@ -0,0 +1,11 @@
+// compile-flags: -Z track-diagnostics
+// error-pattern: created at
+
+// Normalize the emitted location so this doesn't need
+// updating everytime someone adds or removes a line.
+// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
+// normalize-stderr-test "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET"
+
+fn main() {
+ break rust
+}
diff --git a/src/test/ui/track-diagnostics/track.stderr b/src/test/ui/track-diagnostics/track.stderr
new file mode 100644
index 000000000..8256c1f5f
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track.stderr
@@ -0,0 +1,26 @@
+error[E0425]: cannot find value `rust` in this scope
+ --> $DIR/track.rs:LL:CC
+ |
+LL | break rust
+ | ^^^^ not found in this scope
+-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
+
+error[E0268]: `break` outside of a loop or labeled block
+ --> $DIR/track.rs:LL:CC
+ |
+LL | break rust
+ | ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
+-Ztrack-diagnostics: created at compiler/rustc_passes/src/loops.rs:LL:CC
+
+error: internal compiler error: It looks like you're trying to break rust; would you like some ICE?
+
+note: the compiler expectedly panicked. this is a feature.
+
+note: we would appreciate a joke overview: https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675
+
+note: rustc $VERSION running on $TARGET
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0268, E0425.
+For more information about an error, try `rustc --explain E0268`.
diff --git a/src/test/ui/track-diagnostics/track2.rs b/src/test/ui/track-diagnostics/track2.rs
new file mode 100644
index 000000000..dc105c61d
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track2.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Z track-diagnostics
+// error-pattern: created at
+
+// Normalize the emitted location so this doesn't need
+// updating everytime someone adds or removes a line.
+// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
+
+fn main() {
+ let _moved @ _from = String::from("foo");
+}
diff --git a/src/test/ui/track-diagnostics/track2.stderr b/src/test/ui/track-diagnostics/track2.stderr
new file mode 100644
index 000000000..fe13e5ef3
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track2.stderr
@@ -0,0 +1,18 @@
+error[E0382]: use of moved value
+ --> $DIR/track2.rs:LL:CC
+ |
+LL | let _moved @ _from = String::from("foo");
+ | ^^^^^^ ----- ------------------- move occurs because value has type `String`, which does not implement the `Copy` trait
+ | | |
+ | | value moved here
+ | value used here after move
+-Ztrack-diagnostics: created at compiler/rustc_borrowck/src/borrowck_errors.rs:LL:CC
+ |
+help: borrow this binding in the pattern to avoid moving the value
+ |
+LL | let ref _moved @ ref _from = String::from("foo");
+ | +++ +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/track-diagnostics/track3.rs b/src/test/ui/track-diagnostics/track3.rs
new file mode 100644
index 000000000..069923950
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track3.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Z track-diagnostics
+// error-pattern: created at
+
+// Normalize the emitted location so this doesn't need
+// updating everytime someone adds or removes a line.
+// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
+
+fn main() {
+ let _unimported = Blah { field: u8 };
+}
diff --git a/src/test/ui/track-diagnostics/track3.stderr b/src/test/ui/track-diagnostics/track3.stderr
new file mode 100644
index 000000000..dc468d7e8
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track3.stderr
@@ -0,0 +1,18 @@
+error[E0422]: cannot find struct, variant or union type `Blah` in this scope
+ --> $DIR/track3.rs:LL:CC
+ |
+LL | let _unimported = Blah { field: u8 };
+ | ^^^^ not found in this scope
+-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
+
+error[E0423]: expected value, found builtin type `u8`
+ --> $DIR/track3.rs:LL:CC
+ |
+LL | let _unimported = Blah { field: u8 };
+ | ^^ not a value
+-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0422, E0423.
+For more information about an error, try `rustc --explain E0422`.
diff --git a/src/test/ui/track-diagnostics/track4.rs b/src/test/ui/track-diagnostics/track4.rs
new file mode 100644
index 000000000..35eec799b
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track4.rs
@@ -0,0 +1,13 @@
+// compile-flags: -Z track-diagnostics
+// error-pattern: created at
+
+// Normalize the emitted location so this doesn't need
+// updating everytime someone adds or removes a line.
+// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
+
+pub onion {
+ Owo(u8),
+ Uwu(i8),
+}
+
+fn main() {}
diff --git a/src/test/ui/track-diagnostics/track4.stderr b/src/test/ui/track-diagnostics/track4.stderr
new file mode 100644
index 000000000..c4668444c
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track4.stderr
@@ -0,0 +1,14 @@
+error: missing `struct` for struct definition
+ --> $DIR/track4.rs:LL:CC
+ |
+LL | pub onion {
+ | ^
+-Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/diagnostics.rs:LL:CC
+ |
+help: add `struct` here to parse `onion` as a public struct
+ |
+LL | pub struct onion {
+ | ++++++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/track-diagnostics/track5.rs b/src/test/ui/track-diagnostics/track5.rs
new file mode 100644
index 000000000..c41d9424e
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track5.rs
@@ -0,0 +1,8 @@
+// compile-flags: -Z track-diagnostics
+// error-pattern: created at
+
+// Normalize the emitted location so this doesn't need
+// updating everytime someone adds or removes a line.
+// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
+
+}
diff --git a/src/test/ui/track-diagnostics/track5.stderr b/src/test/ui/track-diagnostics/track5.stderr
new file mode 100644
index 000000000..aa54f92b6
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track5.stderr
@@ -0,0 +1,9 @@
+error: unexpected closing delimiter: `}`
+ --> $DIR/track5.rs:LL:CC
+ |
+LL | }
+ | ^ unexpected closing delimiter
+-Ztrack-diagnostics: created at compiler/rustc_parse/src/lexer/tokentrees.rs:LL:CC
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/track-diagnostics/track6.rs b/src/test/ui/track-diagnostics/track6.rs
new file mode 100644
index 000000000..307e31018
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track6.rs
@@ -0,0 +1,14 @@
+// compile-flags: -Z track-diagnostics
+// error-pattern: created at
+
+
+
+pub trait Foo {
+ fn bar();
+}
+
+impl <T> Foo for T {
+ default fn bar() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/track-diagnostics/track6.stderr b/src/test/ui/track-diagnostics/track6.stderr
new file mode 100644
index 000000000..1c7537633
--- /dev/null
+++ b/src/test/ui/track-diagnostics/track6.stderr
@@ -0,0 +1,13 @@
+error[E0658]: specialization is unstable
+ --> $DIR/track6.rs:11:5
+ |
+LL | default fn bar() {}
+ | ^^^^^^^^^^^^^^^^^^^
+-Ztrack-diagnostics: created at $COMPILER_DIR/rustc_session/src/parse.rs:93:5
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: add `#![feature(specialization)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/trait-bounds/impl-bound-with-references-error.rs b/src/test/ui/trait-bounds/impl-bound-with-references-error.rs
new file mode 100644
index 000000000..e5d0a1aae
--- /dev/null
+++ b/src/test/ui/trait-bounds/impl-bound-with-references-error.rs
@@ -0,0 +1,20 @@
+// Regression test for #105138.
+// This test ensures that the compiler does not add note
+// for implementation of trait whose inner type is erroneous.
+
+pub enum LabelText {
+ Plain,
+}
+
+impl<T> From<T> for LabelText
+//~^ ERROR conflicting implementations of trait `From<LabelText>` for type `LabelText` [E0119]
+where
+ T: Into<Cow<'static, str>>,
+ //~^ ERROR cannot find type `Cow` in this scope [E0412]
+{
+ fn from(text: T) -> Self {
+ LabelText::Plain(text.into())
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/trait-bounds/impl-bound-with-references-error.stderr b/src/test/ui/trait-bounds/impl-bound-with-references-error.stderr
new file mode 100644
index 000000000..95fd6bd50
--- /dev/null
+++ b/src/test/ui/trait-bounds/impl-bound-with-references-error.stderr
@@ -0,0 +1,24 @@
+error[E0412]: cannot find type `Cow` in this scope
+ --> $DIR/impl-bound-with-references-error.rs:12:13
+ |
+LL | T: Into<Cow<'static, str>>,
+ | ^^^ not found in this scope
+ |
+help: consider importing this enum
+ |
+LL | use std::borrow::Cow;
+ |
+
+error[E0119]: conflicting implementations of trait `From<LabelText>` for type `LabelText`
+ --> $DIR/impl-bound-with-references-error.rs:9:1
+ |
+LL | impl<T> From<T> for LabelText
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: conflicting implementation in crate `core`:
+ - impl<T> From<T> for T;
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0412.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/src/test/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.rs b/src/test/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.rs
new file mode 100644
index 000000000..dcdbd0228
--- /dev/null
+++ b/src/test/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.rs
@@ -0,0 +1,38 @@
+trait Trait<T> {
+ fn foo<'a, K>(self, _: T, _: K) where T: 'a, K: 'a;
+}
+
+impl Trait<()> for () {
+ fn foo<'a, K>(self, _: (), _: K) where { //~ ERROR E0195
+ todo!();
+ }
+}
+
+struct State;
+
+trait Foo<T> {
+ fn foo<'a>(&self, state: &'a State) -> &'a T
+ where
+ T: 'a;
+}
+
+impl<F, T> Foo<T> for F
+where
+ F: Fn(&State) -> &T,
+{
+ fn foo<'a>(&self, state: &'a State) -> &'a T { //~ ERROR E0195
+ self(state)
+ }
+}
+
+trait Bar {
+ fn foo<'a>(&'a self) {}
+}
+
+impl Bar for () {
+ fn foo<'a: 'a>(&'a self) {} //~ ERROR E0195
+}
+
+fn main() {
+ ().foo((), ());
+}
diff --git a/src/test/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr b/src/test/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr
new file mode 100644
index 000000000..e26cb2216
--- /dev/null
+++ b/src/test/ui/trait-bounds/impl-missing-where-clause-lifetimes-from-trait.stderr
@@ -0,0 +1,36 @@
+error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+ --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:6:11
+ |
+LL | fn foo<'a, K>(self, _: T, _: K) where T: 'a, K: 'a;
+ | ------- -- -- this bound might be missing in the impl
+ | | |
+ | | this bound might be missing in the impl
+ | lifetimes in impl do not match this method in trait
+...
+LL | fn foo<'a, K>(self, _: (), _: K) where {
+ | ^^^^^^^ lifetimes do not match method in trait
+
+error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+ --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:23:11
+ |
+LL | fn foo<'a>(&self, state: &'a State) -> &'a T
+ | ---- lifetimes in impl do not match this method in trait
+LL | where
+LL | T: 'a;
+ | -- this bound might be missing in the impl
+...
+LL | fn foo<'a>(&self, state: &'a State) -> &'a T {
+ | ^^^^ lifetimes do not match method in trait
+
+error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+ --> $DIR/impl-missing-where-clause-lifetimes-from-trait.rs:33:11
+ |
+LL | fn foo<'a>(&'a self) {}
+ | ---- lifetimes in impl do not match this method in trait
+...
+LL | fn foo<'a: 'a>(&'a self) {}
+ | ^^^^^^^^ lifetimes do not match method in trait
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0195`.
diff --git a/src/test/ui/traits/alias/issue-83613.rs b/src/test/ui/traits/alias/issue-83613.rs
index 04320e720..2462e703a 100644
--- a/src/test/ui/traits/alias/issue-83613.rs
+++ b/src/test/ui/traits/alias/issue-83613.rs
@@ -9,5 +9,4 @@ trait AnotherTrait {}
impl<T: Send> AnotherTrait for T {}
impl AnotherTrait for OpaqueType {}
//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
-//~| ERROR cannot implement trait on type alias impl trait
fn main() {}
diff --git a/src/test/ui/traits/alias/issue-83613.stderr b/src/test/ui/traits/alias/issue-83613.stderr
index b9d931601..a78294da6 100644
--- a/src/test/ui/traits/alias/issue-83613.stderr
+++ b/src/test/ui/traits/alias/issue-83613.stderr
@@ -6,18 +6,6 @@ LL | impl<T: Send> AnotherTrait for T {}
LL | impl AnotherTrait for OpaqueType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
-error: cannot implement trait on type alias impl trait
- --> $DIR/issue-83613.rs:10:23
- |
-LL | impl AnotherTrait for OpaqueType {}
- | ^^^^^^^^^^
- |
-note: type alias impl trait defined here
- --> $DIR/issue-83613.rs:4:19
- |
-LL | type OpaqueType = impl OpaqueTrait;
- | ^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/traits/invalid_operator_trait.rs b/src/test/ui/traits/invalid_operator_trait.rs
new file mode 100644
index 000000000..7ea3b0d5b
--- /dev/null
+++ b/src/test/ui/traits/invalid_operator_trait.rs
@@ -0,0 +1,23 @@
+#![crate_type = "lib"]
+#![feature(lang_items)]
+#![feature(no_core)]
+#![no_core]
+
+#[lang="sized"]
+pub trait Sized {
+ // Empty.
+}
+
+#[lang = "add"]
+trait Add<RHS=Self> {
+ type Output;
+
+ fn add<Y>(self, _: RHS) -> Self::Output;
+ //~^ ERROR `add` must not have any generic parameters
+}
+
+#[allow(unreachable_code)]
+fn ice(a: usize) {
+ let r = loop {};
+ r = r + a;
+}
diff --git a/src/test/ui/traits/invalid_operator_trait.stderr b/src/test/ui/traits/invalid_operator_trait.stderr
new file mode 100644
index 000000000..8c6e36959
--- /dev/null
+++ b/src/test/ui/traits/invalid_operator_trait.stderr
@@ -0,0 +1,8 @@
+error: `add` must not have any generic parameters
+ --> $DIR/invalid_operator_trait.rs:15:5
+ |
+LL | fn add<Y>(self, _: RHS) -> Self::Output;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/traits/issue-102989.rs b/src/test/ui/traits/issue-102989.rs
index 62f95272f..216cd78e5 100644
--- a/src/test/ui/traits/issue-102989.rs
+++ b/src/test/ui/traits/issue-102989.rs
@@ -7,10 +7,8 @@ trait Sized { } //~ ERROR found duplicate lang item `sized`
fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
//~^ ERROR `self` parameter is only allowed in associated functions
//~| ERROR cannot find type `Struct` in this scope
- //~| ERROR mismatched types
let x = x << 1;
- //~^ ERROR the size for values of type `{integer}` cannot be known at compilation time
- //~| ERROR cannot find value `x` in this scope
+ //~^ ERROR cannot find value `x` in this scope
}
fn main() {}
diff --git a/src/test/ui/traits/issue-102989.stderr b/src/test/ui/traits/issue-102989.stderr
index efe1a2467..7d0098fe8 100644
--- a/src/test/ui/traits/issue-102989.stderr
+++ b/src/test/ui/traits/issue-102989.stderr
@@ -13,7 +13,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| ^^^^^^ not found in this scope
error[E0425]: cannot find value `x` in this scope
- --> $DIR/issue-102989.rs:11:13
+ --> $DIR/issue-102989.rs:10:13
|
LL | let x = x << 1;
| ^ help: a local variable with a similar name exists: `f`
@@ -28,32 +28,7 @@ LL | trait Sized { }
= note: first definition in `core` loaded from SYSROOT/libcore-*.rlib
= note: second definition in the local crate (`issue_102989`)
-error[E0277]: the size for values of type `{integer}` cannot be known at compilation time
- --> $DIR/issue-102989.rs:11:15
- |
-LL | let x = x << 1;
- | ^^ doesn't have a size known at compile-time
- |
- = help: the trait `std::marker::Sized` is not implemented for `{integer}`
-
-error[E0308]: mismatched types
- --> $DIR/issue-102989.rs:7:42
- |
-LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
- | ---------- ^^^^ expected `&u32`, found `()`
- | |
- | implicitly returns `()` as its body has no tail or `return` expression
- |
-note: consider returning one of these bindings
- --> $DIR/issue-102989.rs:7:30
- |
-LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
- | ^
-...
-LL | let x = x << 1;
- | ^
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
-Some errors have detailed explanations: E0152, E0277, E0308, E0412, E0425.
+Some errors have detailed explanations: E0152, E0412, E0425.
For more information about an error, try `rustc --explain E0152`.
diff --git a/src/test/ui/traits/issue-104322.rs b/src/test/ui/traits/issue-104322.rs
new file mode 100644
index 000000000..dcc27f1f0
--- /dev/null
+++ b/src/test/ui/traits/issue-104322.rs
@@ -0,0 +1,80 @@
+// build-pass
+//
+// Tests that overflows do not occur in certain situations
+// related to generic diesel code
+
+use mini_diesel::*;
+
+pub trait HandleDelete<K> {}
+
+pub fn handle_delete<D, R>()
+where
+ R: HasTable,
+ R::Table: HandleDelete<D> + 'static,
+{
+}
+
+impl<K, T> HandleDelete<K> for T
+where
+ T: Table + HasTable<Table = T> + 'static,
+ K: 'static,
+ &'static K: Identifiable<Table = T>,
+ T::PrimaryKey: EqAll<<&'static K as Identifiable>::Id>,
+ T::Query: FilterDsl<<T::PrimaryKey as EqAll<<&'static K as Identifiable>::Id>>::Output>,
+ Filter<T::Query, <T::PrimaryKey as EqAll<<&'static K as Identifiable>::Id>>::Output>:
+ IntoUpdateTarget<Table = T>,
+{
+}
+
+mod mini_diesel {
+ pub trait HasTable {
+ type Table: Table;
+ }
+
+ pub trait Identifiable: HasTable {
+ type Id;
+ }
+
+ pub trait EqAll<Rhs> {
+ type Output;
+ }
+
+ pub trait IntoUpdateTarget: HasTable {
+ type WhereClause;
+ }
+
+ pub trait Query {
+ type SqlType;
+ }
+
+ pub trait AsQuery {
+ type Query: Query;
+ }
+ impl<T: Query> AsQuery for T {
+ type Query = Self;
+ }
+
+ pub trait FilterDsl<Predicate> {
+ type Output;
+ }
+
+ impl<T, Predicate> FilterDsl<Predicate> for T
+ where
+ T: Table,
+ T::Query: FilterDsl<Predicate>,
+ {
+ type Output = Filter<T::Query, Predicate>;
+ }
+
+ pub trait QuerySource {
+ type FromClause;
+ }
+
+ pub trait Table: QuerySource + AsQuery + Sized {
+ type PrimaryKey;
+ }
+
+ pub type Filter<Source, Predicate> = <Source as FilterDsl<Predicate>>::Output;
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/issue-33140-hack-boundaries.stderr b/src/test/ui/traits/issue-33140-hack-boundaries.stderr
index 58286648d..80a502c63 100644
--- a/src/test/ui/traits/issue-33140-hack-boundaries.stderr
+++ b/src/test/ui/traits/issue-33140-hack-boundaries.stderr
@@ -1,12 +1,12 @@
-error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn std::marker::Send + 'static)`
+error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:18:1
|
LL | impl Trait1 for dyn Send {}
| ------------------------ first implementation here
LL | impl Trait1 for dyn Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
-error[E0751]: found both positive and negative implementation of trait `Trait2` for type `(dyn std::marker::Send + 'static)`:
+error[E0751]: found both positive and negative implementation of trait `Trait2` for type `(dyn Send + 'static)`:
--> $DIR/issue-33140-hack-boundaries.rs:25:1
|
LL | impl Trait2 for dyn Send {}
@@ -14,21 +14,21 @@ LL | impl Trait2 for dyn Send {}
LL | impl !Trait2 for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
-error[E0119]: conflicting implementations of trait `Trait3<(dyn std::marker::Sync + 'static)>` for type `(dyn std::marker::Send + 'static)`
+error[E0119]: conflicting implementations of trait `Trait3<(dyn Sync + 'static)>` for type `(dyn Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:32:1
|
LL | impl Trait3<dyn Sync> for dyn Send {}
| ---------------------------------- first implementation here
LL | impl Trait3<dyn Sync> for dyn Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
-error[E0119]: conflicting implementations of trait `Trait4a` for type `(dyn std::marker::Send + 'static)`
+error[E0119]: conflicting implementations of trait `Trait4a` for type `(dyn Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:39:1
|
LL | impl<T: ?Sized> Trait4a for T {}
| ----------------------------- first implementation here
LL | impl Trait4a for dyn Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
error[E0119]: conflicting implementations of trait `Trait4b` for type `()`
--> $DIR/issue-33140-hack-boundaries.rs:46:1
@@ -38,42 +38,42 @@ LL | impl Trait4b for () {}
LL | impl Trait4b for () {}
| ^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
-error[E0119]: conflicting implementations of trait `Trait4c` for type `(dyn Trait1 + std::marker::Send + 'static)`
+error[E0119]: conflicting implementations of trait `Trait4c` for type `(dyn Trait1 + Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:53:1
|
LL | impl Trait4c for dyn Trait1 + Send {}
| ---------------------------------- first implementation here
LL | impl Trait4c for dyn Trait1 + Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Trait1 + std::marker::Send + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Trait1 + Send + 'static)`
-error[E0119]: conflicting implementations of trait `Trait4d` for type `dyn std::marker::Send`
+error[E0119]: conflicting implementations of trait `Trait4d` for type `dyn Send`
--> $DIR/issue-33140-hack-boundaries.rs:60:1
|
LL | impl<'a> Trait4d for dyn Send + 'a {}
| ---------------------------------- first implementation here
LL | impl<'a> Trait4d for dyn Send + 'a {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `dyn std::marker::Send`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `dyn Send`
-error[E0119]: conflicting implementations of trait `Trait5` for type `(dyn std::marker::Send + 'static)`
+error[E0119]: conflicting implementations of trait `Trait5` for type `(dyn Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:67:1
|
LL | impl Trait5 for dyn Send {}
| ------------------------ first implementation here
LL | impl Trait5 for dyn Send where u32: Copy {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0119, E0751.
For more information about an error, try `rustc --explain E0119`.
Future incompatibility report: Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait0` for type `(dyn std::marker::Send + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait0` for type `(dyn Send + 'static)`: (E0119)
--> $DIR/issue-33140-hack-boundaries.rs:10:1
|
LL | impl Trait0 for dyn Send {}
| ------------------------ first implementation here
LL | impl Trait0 for dyn Send {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
diff --git a/src/test/ui/traits/issue-33140.stderr b/src/test/ui/traits/issue-33140.stderr
index 392c56a28..d31281f72 100644
--- a/src/test/ui/traits/issue-33140.stderr
+++ b/src/test/ui/traits/issue-33140.stderr
@@ -1,20 +1,20 @@
-error[E0119]: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`
+error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`
--> $DIR/issue-33140.rs:9:1
|
LL | impl Trait for dyn Send + Sync {
| ------------------------------ first implementation here
...
LL | impl Trait for dyn Sync + Send {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
-error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`
+error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn Send + Sync + 'static)`
--> $DIR/issue-33140.rs:22:1
|
LL | impl Trait2 for dyn Send + Sync {
| ------------------------------- first implementation here
...
LL | impl Trait2 for dyn Sync + Send + Sync {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
error[E0592]: duplicate definitions with name `abc`
--> $DIR/issue-33140.rs:29:5
diff --git a/src/test/ui/issues/issue-7013.rs b/src/test/ui/traits/issue-7013.rs
index 1fb01303c..1fb01303c 100644
--- a/src/test/ui/issues/issue-7013.rs
+++ b/src/test/ui/traits/issue-7013.rs
diff --git a/src/test/ui/issues/issue-7013.stderr b/src/test/ui/traits/issue-7013.stderr
index 4575f4dba..4575f4dba 100644
--- a/src/test/ui/issues/issue-7013.stderr
+++ b/src/test/ui/traits/issue-7013.stderr
diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr
index e210f11b3..b6a045855 100644
--- a/src/test/ui/traits/issue-77982.stderr
+++ b/src/test/ui/traits/issue-77982.stderr
@@ -46,12 +46,7 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(
| |
| required by a bound introduced by this call
|
- = note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`:
- - impl From<Ipv4Addr> for u32;
- - impl From<NonZeroU32> for u32;
- - impl From<bool> for u32;
- - impl From<char> for u32;
- and 3 more
+ = note: cannot satisfy `u32: From<_>`
help: try using a fully qualified path to specify the expected types
|
LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(<u32 as Into<T>>::into(0u32))).collect();
diff --git a/src/test/ui/traits/issue-79458.stderr b/src/test/ui/traits/issue-79458.stderr
index cf2e4edf9..08f7bbbf0 100644
--- a/src/test/ui/traits/issue-79458.stderr
+++ b/src/test/ui/traits/issue-79458.stderr
@@ -7,10 +7,7 @@ LL | struct Foo<'a, T> {
LL | bar: &'a mut T
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `&mut T`
|
- = help: the following other types implement trait `Clone`:
- &T
- *const T
- *mut T
+ = help: the trait `Clone` is implemented for `&T`
= note: `Clone` is implemented for `&T`, but not for `&mut T`
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/src/test/ui/traits/issue-82830.rs b/src/test/ui/traits/issue-82830.rs
index c8289b2e3..37bae2e90 100644
--- a/src/test/ui/traits/issue-82830.rs
+++ b/src/test/ui/traits/issue-82830.rs
@@ -1,10 +1,12 @@
+// check-pass
+
trait A<Y, N> {
type B;
}
type MaybeBox<T> = <T as A<T, Box<T>>>::B;
struct P {
- t: MaybeBox<P>, //~ ERROR: overflow evaluating the requirement `P: Sized`
+ t: MaybeBox<P>,
}
impl<Y, N> A<Y, N> for P {
diff --git a/src/test/ui/traits/issue-82830.stderr b/src/test/ui/traits/issue-82830.stderr
deleted file mode 100644
index 6a597a402..000000000
--- a/src/test/ui/traits/issue-82830.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0275]: overflow evaluating the requirement `P: Sized`
- --> $DIR/issue-82830.rs:7:8
- |
-LL | t: MaybeBox<P>,
- | ^^^^^^^^^^^
- |
-note: required for `P` to implement `A<P, Box<P>>`
- --> $DIR/issue-82830.rs:10:12
- |
-LL | impl<Y, N> A<Y, N> for P {
- | ^^^^^^^ ^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/traits/issue-91949-hangs-on-recursion.rs b/src/test/ui/traits/issue-91949-hangs-on-recursion.rs
index 499a64f28..6474b2b38 100644
--- a/src/test/ui/traits/issue-91949-hangs-on-recursion.rs
+++ b/src/test/ui/traits/issue-91949-hangs-on-recursion.rs
@@ -2,6 +2,7 @@
// compile-flags: -Zinline-mir=no
// error-pattern: overflow evaluating the requirement `(): Sized`
// error-pattern: function cannot return without recursing
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
// Regression test for #91949.
// This hanged *forever* on 1.56, fixed by #90423.
diff --git a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
index 61b6d4b08..1f18c5daf 100644
--- a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
+++ b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr
@@ -1,5 +1,5 @@
warning: function cannot return without recursing
- --> $DIR/issue-91949-hangs-on-recursion.rs:22:1
+ --> $DIR/issue-91949-hangs-on-recursion.rs:23:1
|
LL | / fn recurse<T>(elements: T) -> Vec<char>
LL | | where
@@ -17,7 +17,8 @@ error[E0275]: overflow evaluating the requirement `(): Sized`
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`)
= note: required for `std::iter::Empty<()>` to implement `Iterator`
= note: 171 redundant requirements hidden
- = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), std::iter::Empty<()>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>, [closure@$DIR/issue-91949-hangs-on-recursion.rs:26:45: 26:48]>>` to implement `Iterator`
+ = note: required for `IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<IteratorOfWrapped<(), Map<..., ...>>, ...>>, ...>>` to implement `Iterator`
+ = note: the full type name has been written to '$TEST_BUILD_DIR/traits/issue-91949-hangs-on-recursion/issue-91949-hangs-on-recursion.long-type-hash.txt'
error: aborting due to previous error; 1 warning emitted
diff --git a/src/test/ui/traits/item-privacy.stderr b/src/test/ui/traits/item-privacy.stderr
index 7f78b37ba..f137a298a 100644
--- a/src/test/ui/traits/item-privacy.stderr
+++ b/src/test/ui/traits/item-privacy.stderr
@@ -162,9 +162,12 @@ error[E0223]: ambiguous associated type
LL | let _: S::C;
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::C`
-error: associated type `A` is private
+error[E0624]: associated type `A` is private
--> $DIR/item-privacy.rs:119:12
|
+LL | type A = u8;
+ | ------ associated type defined here
+...
LL | let _: T::A;
| ^^^^ private associated type
diff --git a/src/test/ui/traits/negative-impls/eager-mono.rs b/src/test/ui/traits/negative-impls/eager-mono.rs
new file mode 100644
index 000000000..ce770376c
--- /dev/null
+++ b/src/test/ui/traits/negative-impls/eager-mono.rs
@@ -0,0 +1,12 @@
+// build-pass
+// compile-flags:-C link-dead-code=y
+
+#![feature(negative_impls)]
+
+trait Foo {
+ fn foo() {}
+}
+
+impl !Foo for () {}
+
+fn main() {}
diff --git a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr
index d7039e3db..a87acb1fb 100644
--- a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr
+++ b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr
@@ -1,4 +1,4 @@
-error[E0751]: found both positive and negative implementation of trait `std::clone::Clone` for type `&mut MyType<'_>`:
+error[E0751]: found both positive and negative implementation of trait `Clone` for type `&mut MyType<'_>`:
--> $DIR/pin-unsound-issue-66544-clone.rs:7:1
|
LL | impl<'a> Clone for &'a mut MyType<'a> {
diff --git a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr
index a0b62a8ba..9185e8f84 100644
--- a/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr
+++ b/src/test/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.stderr
@@ -1,4 +1,4 @@
-error[E0751]: found both positive and negative implementation of trait `std::ops::DerefMut` for type `&MyType<'_>`:
+error[E0751]: found both positive and negative implementation of trait `DerefMut` for type `&MyType<'_>`:
--> $DIR/pin-unsound-issue-66544-derefmut.rs:12:1
|
LL | impl<'a> DerefMut for &'a MyType<'a> {
diff --git a/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr b/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr
index 0af4df2ae..525401f9d 100644
--- a/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr
+++ b/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr
@@ -1,10 +1,10 @@
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:86:1
|
LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
| ------------------------------------------------------ first implementation here
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@@ -14,26 +14,26 @@ note: the lint level is defined here
LL | #![warn(order_dependent_trait_objects)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:89:1
|
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
| ------------------------------------------------------------- first implementation here
...
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:93:1
|
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
| ------------------------------------------------------ first implementation here
...
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@@ -41,13 +41,13 @@ LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
warning: 3 warnings emitted
Future incompatibility report: Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:86:1
|
LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
| ------------------------------------------------------ first implementation here
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@@ -58,14 +58,14 @@ LL | #![warn(order_dependent_trait_objects)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:89:1
|
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
| ------------------------------------------------------------- first implementation here
...
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
@@ -76,14 +76,14 @@ LL | #![warn(order_dependent_trait_objects)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
-warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
+warning: conflicting implementations of trait `Trait` for type `(dyn Send + Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:93:1
|
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
| ------------------------------------------------------ first implementation here
...
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Send + Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
diff --git a/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr b/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr
index 910c5e29d..e24ed695d 100644
--- a/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr
+++ b/src/test/ui/traits/overlap-not-permitted-for-builtin-trait.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `std::marker::Send` for type `MyStruct`
+error[E0119]: conflicting implementations of trait `Send` for type `MyStruct`
--> $DIR/overlap-not-permitted-for-builtin-trait.rs:7:1
|
LL | impl !Send for MyStruct {}
diff --git a/src/test/ui/traits/suggest-fully-qualified-closure.rs b/src/test/ui/traits/suggest-fully-qualified-closure.rs
new file mode 100644
index 000000000..c077921c0
--- /dev/null
+++ b/src/test/ui/traits/suggest-fully-qualified-closure.rs
@@ -0,0 +1,24 @@
+// check-fail
+// known-bug: #103705
+// normalize-stderr-test "\[closure@.*\]" -> "[closure@]"
+// normalize-stderr-test "\+* ~" -> "+++ ~"
+
+// The output of this currently suggests writing a closure in the qualified path.
+
+trait MyTrait<T> {
+ fn lol<F:FnOnce()>(&self, f:F) -> u16;
+}
+
+struct Qqq;
+
+impl MyTrait<u32> for Qqq{
+ fn lol<F:FnOnce()>(&self, _f:F) -> u16 { 5 }
+}
+impl MyTrait<u64> for Qqq{
+ fn lol<F:FnOnce()>(&self, _f:F) -> u16 { 6 }
+}
+
+fn main() {
+ let q = Qqq;
+ q.lol(||());
+}
diff --git a/src/test/ui/traits/suggest-fully-qualified-closure.stderr b/src/test/ui/traits/suggest-fully-qualified-closure.stderr
new file mode 100644
index 000000000..3df623c14
--- /dev/null
+++ b/src/test/ui/traits/suggest-fully-qualified-closure.stderr
@@ -0,0 +1,34 @@
+error[E0282]: type annotations needed
+ --> $DIR/suggest-fully-qualified-closure.rs:23:7
+ |
+LL | q.lol(||());
+ | ^^^
+ |
+help: try using a fully qualified path to specify the expected types
+ |
+LL | <Qqq as MyTrait<T>>::lol::<[closure@]>(&q, ||());
+ | +++ ~
+
+error[E0283]: type annotations needed
+ --> $DIR/suggest-fully-qualified-closure.rs:23:7
+ |
+LL | q.lol(||());
+ | ^^^
+ |
+note: multiple `impl`s satisfying `Qqq: MyTrait<_>` found
+ --> $DIR/suggest-fully-qualified-closure.rs:14:1
+ |
+LL | impl MyTrait<u32> for Qqq{
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | impl MyTrait<u64> for Qqq{
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: try using a fully qualified path to specify the expected types
+ |
+LL | <Qqq as MyTrait<T>>::lol::<[closure@]>(&q, ||());
+ | +++ ~
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0282, E0283.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/traits/trait-upcasting/basic.rs b/src/test/ui/traits/trait-upcasting/basic.rs
index 484a222bc..570ec5160 100644
--- a/src/test/ui/traits/trait-upcasting/basic.rs
+++ b/src/test/ui/traits/trait-upcasting/basic.rs
@@ -1,7 +1,6 @@
// run-pass
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 {
diff --git a/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs b/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs
index 8d0a9ef0a..eae5cf8d5 100644
--- a/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs
+++ b/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs
@@ -1,6 +1,5 @@
// run-pass
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo<T: Default + ToString>: Bar<i32> + Bar<T> {}
trait Bar<T: Default + ToString> {
diff --git a/src/test/ui/traits/trait-upcasting/diamond.rs b/src/test/ui/traits/trait-upcasting/diamond.rs
index e4e23c1a2..a4f81c464 100644
--- a/src/test/ui/traits/trait-upcasting/diamond.rs
+++ b/src/test/ui/traits/trait-upcasting/diamond.rs
@@ -1,7 +1,6 @@
// run-pass
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 {
diff --git a/src/test/ui/traits/trait-upcasting/invalid-upcast.rs b/src/test/ui/traits/trait-upcasting/invalid-upcast.rs
index 240224504..e634bbd5a 100644
--- a/src/test/ui/traits/trait-upcasting/invalid-upcast.rs
+++ b/src/test/ui/traits/trait-upcasting/invalid-upcast.rs
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo {
fn a(&self) -> i32 {
diff --git a/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr b/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr
index b4530ed0c..3aa21ee3d 100644
--- a/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr
+++ b/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:54:35
+ --> $DIR/invalid-upcast.rs:53:35
|
LL | let _: &dyn std::fmt::Debug = baz;
| -------------------- ^^^ expected trait `Debug`, found trait `Baz`
@@ -10,7 +10,7 @@ LL | let _: &dyn std::fmt::Debug = baz;
found reference `&dyn Baz`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:56:24
+ --> $DIR/invalid-upcast.rs:55:24
|
LL | let _: &dyn Send = baz;
| --------- ^^^ expected trait `Send`, found trait `Baz`
@@ -21,7 +21,7 @@ LL | let _: &dyn Send = baz;
found reference `&dyn Baz`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:58:24
+ --> $DIR/invalid-upcast.rs:57:24
|
LL | let _: &dyn Sync = baz;
| --------- ^^^ expected trait `Sync`, found trait `Baz`
@@ -32,7 +32,7 @@ LL | let _: &dyn Sync = baz;
found reference `&dyn Baz`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:61:25
+ --> $DIR/invalid-upcast.rs:60:25
|
LL | let bar: &dyn Bar = baz;
| -------- ^^^ expected trait `Bar`, found trait `Baz`
@@ -43,7 +43,7 @@ LL | let bar: &dyn Bar = baz;
found reference `&dyn Baz`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:63:35
+ --> $DIR/invalid-upcast.rs:62:35
|
LL | let _: &dyn std::fmt::Debug = bar;
| -------------------- ^^^ expected trait `Debug`, found trait `Bar`
@@ -54,7 +54,7 @@ LL | let _: &dyn std::fmt::Debug = bar;
found reference `&dyn Bar`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:65:24
+ --> $DIR/invalid-upcast.rs:64:24
|
LL | let _: &dyn Send = bar;
| --------- ^^^ expected trait `Send`, found trait `Bar`
@@ -65,7 +65,7 @@ LL | let _: &dyn Send = bar;
found reference `&dyn Bar`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:67:24
+ --> $DIR/invalid-upcast.rs:66:24
|
LL | let _: &dyn Sync = bar;
| --------- ^^^ expected trait `Sync`, found trait `Bar`
@@ -76,7 +76,7 @@ LL | let _: &dyn Sync = bar;
found reference `&dyn Bar`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:70:25
+ --> $DIR/invalid-upcast.rs:69:25
|
LL | let foo: &dyn Foo = baz;
| -------- ^^^ expected trait `Foo`, found trait `Baz`
@@ -87,7 +87,7 @@ LL | let foo: &dyn Foo = baz;
found reference `&dyn Baz`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:72:35
+ --> $DIR/invalid-upcast.rs:71:35
|
LL | let _: &dyn std::fmt::Debug = foo;
| -------------------- ^^^ expected trait `Debug`, found trait `Foo`
@@ -98,7 +98,7 @@ LL | let _: &dyn std::fmt::Debug = foo;
found reference `&dyn Foo`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:74:24
+ --> $DIR/invalid-upcast.rs:73:24
|
LL | let _: &dyn Send = foo;
| --------- ^^^ expected trait `Send`, found trait `Foo`
@@ -109,7 +109,7 @@ LL | let _: &dyn Send = foo;
found reference `&dyn Foo`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:76:24
+ --> $DIR/invalid-upcast.rs:75:24
|
LL | let _: &dyn Sync = foo;
| --------- ^^^ expected trait `Sync`, found trait `Foo`
@@ -120,7 +120,7 @@ LL | let _: &dyn Sync = foo;
found reference `&dyn Foo`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:79:25
+ --> $DIR/invalid-upcast.rs:78:25
|
LL | let foo: &dyn Foo = bar;
| -------- ^^^ expected trait `Foo`, found trait `Bar`
@@ -131,7 +131,7 @@ LL | let foo: &dyn Foo = bar;
found reference `&dyn Bar`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:81:35
+ --> $DIR/invalid-upcast.rs:80:35
|
LL | let _: &dyn std::fmt::Debug = foo;
| -------------------- ^^^ expected trait `Debug`, found trait `Foo`
@@ -142,7 +142,7 @@ LL | let _: &dyn std::fmt::Debug = foo;
found reference `&dyn Foo`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:83:24
+ --> $DIR/invalid-upcast.rs:82:24
|
LL | let _: &dyn Send = foo;
| --------- ^^^ expected trait `Send`, found trait `Foo`
@@ -153,7 +153,7 @@ LL | let _: &dyn Send = foo;
found reference `&dyn Foo`
error[E0308]: mismatched types
- --> $DIR/invalid-upcast.rs:85:24
+ --> $DIR/invalid-upcast.rs:84:24
|
LL | let _: &dyn Sync = foo;
| --------- ^^^ expected trait `Sync`, found trait `Foo`
diff --git a/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs
index 6d8800254..b672963ae 100644
--- a/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs
+++ b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs
@@ -1,6 +1,5 @@
// run-pass
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
struct Test {
func: Box<dyn FnMut() + 'static>,
diff --git a/src/test/ui/traits/trait-upcasting/lifetime.rs b/src/test/ui/traits/trait-upcasting/lifetime.rs
index f029a6f08..9825158c2 100644
--- a/src/test/ui/traits/trait-upcasting/lifetime.rs
+++ b/src/test/ui/traits/trait-upcasting/lifetime.rs
@@ -1,7 +1,6 @@
// run-pass
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 {
diff --git a/src/test/ui/traits/trait-upcasting/migrate-lint-deny.rs b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.rs
index c67251018..d62418756 100644
--- a/src/test/ui/traits/trait-upcasting/migrate-lint-deny.rs
+++ b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.rs
@@ -7,7 +7,11 @@ use core::ops::Deref;
// issue 89190
trait A {}
trait B: A {}
+
impl<'a> Deref for dyn 'a + B {
+ //~^ ERROR `(dyn B + 'a)` implements `Deref` with supertrait `A` as target
+ //~| WARN this was previously accepted by the compiler but is being phased out;
+
type Target = dyn A;
fn deref(&self) -> &Self::Target {
todo!()
@@ -18,8 +22,6 @@ fn take_a(_: &dyn A) {}
fn whoops(b: &dyn B) {
take_a(b)
- //~^ ERROR `dyn B` implements `Deref` with supertrait `(dyn A + 'static)` as output
- //~^^ WARN this was previously accepted by the compiler but is being phased out;
}
fn main() {}
diff --git a/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr
index 6c359b698..4533b1163 100644
--- a/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr
+++ b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr
@@ -1,8 +1,11 @@
-error: `dyn B` implements `Deref` with supertrait `(dyn A + 'static)` as output
- --> $DIR/migrate-lint-deny.rs:20:12
+error: `(dyn B + 'a)` implements `Deref` with supertrait `A` as target
+ --> $DIR/migrate-lint-deny.rs:11:1
|
-LL | take_a(b)
- | ^
+LL | impl<'a> Deref for dyn 'a + B {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | type Target = dyn A;
+ | -------------------- target type is set here
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460>
diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs
index 6986ad621..2e53a00a9 100644
--- a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs
+++ b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs
@@ -1,12 +1,11 @@
// check-fail
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Bar<T> {
fn bar(&self, _: T) {}
}
-trait Foo : Bar<i32> + Bar<u32> {
+trait Foo: Bar<i32> + Bar<u32> {
fn foo(&self, _: ()) {}
}
diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr
index 956481351..0ad18be03 100644
--- a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr
+++ b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/multiple-occurrence-ambiguousity.rs:21:26
+ --> $DIR/multiple-occurrence-ambiguousity.rs:20:26
|
LL | let t: &dyn Bar<_> = s;
| ----------- ^ expected trait `Bar`, found trait `Foo`
diff --git a/src/test/ui/traits/trait-upcasting/replace-vptr.rs b/src/test/ui/traits/trait-upcasting/replace-vptr.rs
index 1164e4361..9ccfc9306 100644
--- a/src/test/ui/traits/trait-upcasting/replace-vptr.rs
+++ b/src/test/ui/traits/trait-upcasting/replace-vptr.rs
@@ -1,7 +1,6 @@
// run-pass
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait A {
fn foo_a(&self);
diff --git a/src/test/ui/traits/trait-upcasting/struct.rs b/src/test/ui/traits/trait-upcasting/struct.rs
index 0f3cb285b..a3e416969 100644
--- a/src/test/ui/traits/trait-upcasting/struct.rs
+++ b/src/test/ui/traits/trait-upcasting/struct.rs
@@ -1,7 +1,6 @@
// run-pass
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
use std::rc::Rc;
use std::sync::Arc;
diff --git a/src/test/ui/traits/trait-upcasting/subtrait-method.rs b/src/test/ui/traits/trait-upcasting/subtrait-method.rs
index 3508e1528..136d15af0 100644
--- a/src/test/ui/traits/trait-upcasting/subtrait-method.rs
+++ b/src/test/ui/traits/trait-upcasting/subtrait-method.rs
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
fn a(&self) -> i32 {
diff --git a/src/test/ui/traits/trait-upcasting/subtrait-method.stderr b/src/test/ui/traits/trait-upcasting/subtrait-method.stderr
index af7a410f6..918159e84 100644
--- a/src/test/ui/traits/trait-upcasting/subtrait-method.stderr
+++ b/src/test/ui/traits/trait-upcasting/subtrait-method.stderr
@@ -1,64 +1,64 @@
error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope
- --> $DIR/subtrait-method.rs:56:9
+ --> $DIR/subtrait-method.rs:55:9
|
LL | bar.c();
| ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it
- --> $DIR/subtrait-method.rs:28:1
+ --> $DIR/subtrait-method.rs:27:1
|
LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
- --> $DIR/subtrait-method.rs:60:9
+ --> $DIR/subtrait-method.rs:59:9
|
LL | foo.b();
| ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Bar` defines an item `b`, perhaps you need to implement it
- --> $DIR/subtrait-method.rs:18:1
+ --> $DIR/subtrait-method.rs:17:1
|
LL | trait Bar: Foo {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
- --> $DIR/subtrait-method.rs:62:9
+ --> $DIR/subtrait-method.rs:61:9
|
LL | foo.c();
| ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it
- --> $DIR/subtrait-method.rs:28:1
+ --> $DIR/subtrait-method.rs:27:1
|
LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
- --> $DIR/subtrait-method.rs:66:9
+ --> $DIR/subtrait-method.rs:65:9
|
LL | foo.b();
| ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Bar` defines an item `b`, perhaps you need to implement it
- --> $DIR/subtrait-method.rs:18:1
+ --> $DIR/subtrait-method.rs:17:1
|
LL | trait Bar: Foo {
| ^^^^^^^^^^^^^^
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
- --> $DIR/subtrait-method.rs:68:9
+ --> $DIR/subtrait-method.rs:67:9
|
LL | foo.c();
| ^ help: there is a method with a similar name: `a`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Baz` defines an item `c`, perhaps you need to implement it
- --> $DIR/subtrait-method.rs:28:1
+ --> $DIR/subtrait-method.rs:27:1
|
LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
index 79ddedd41..6bc9f4a75 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo: Bar<i32> + Bar<u32> {}
trait Bar<T> {
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
index 398537211..fe269d8e9 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
@@ -1,5 +1,5 @@
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
- --> $DIR/type-checking-test-1.rs:17:13
+ --> $DIR/type-checking-test-1.rs:16:13
|
LL | let _ = x as &dyn Bar<_>; // Ambiguous
| ^^^^^^^^^^^^^^^^ invalid cast
@@ -10,7 +10,7 @@ LL | let _ = &x as &dyn Bar<_>; // Ambiguous
| +
error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
- --> $DIR/type-checking-test-1.rs:17:13
+ --> $DIR/type-checking-test-1.rs:16:13
|
LL | let _ = x as &dyn Bar<_>; // Ambiguous
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
index 32754c538..36b11dffd 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo<T>: Bar<i32> + Bar<T> {}
trait Bar<T> {
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
index 93c71f54e..ef007d5cb 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
@@ -1,5 +1,5 @@
error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>`
- --> $DIR/type-checking-test-2.rs:20:13
+ --> $DIR/type-checking-test-2.rs:19:13
|
LL | let _ = x as &dyn Bar<u32>; // Error
| ^^^^^^^^^^^^^^^^^^ invalid cast
@@ -10,7 +10,7 @@ LL | let _ = &x as &dyn Bar<u32>; // Error
| +
error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
- --> $DIR/type-checking-test-2.rs:20:13
+ --> $DIR/type-checking-test-2.rs:19:13
|
LL | let _ = x as &dyn Bar<u32>; // Error
| ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>`
@@ -18,7 +18,7 @@ LL | let _ = x as &dyn Bar<u32>; // Error
= note: required for the cast from `&dyn Foo<i32>` to the object type `dyn Bar<u32>`
error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
- --> $DIR/type-checking-test-2.rs:26:13
+ --> $DIR/type-checking-test-2.rs:25:13
|
LL | let a = x as &dyn Bar<_>; // Ambiguous
| ^^^^^^^^^^^^^^^^ invalid cast
@@ -29,7 +29,7 @@ LL | let a = &x as &dyn Bar<_>; // Ambiguous
| +
error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
- --> $DIR/type-checking-test-2.rs:26:13
+ --> $DIR/type-checking-test-2.rs:25:13
|
LL | let a = x as &dyn Bar<_>; // Ambiguous
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>`
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr
index e48ba709a..e6cb6a753 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr
@@ -1,22 +1,18 @@
error: lifetime may not live long enough
- --> $DIR/type-checking-test-3.rs:13:13
+ --> $DIR/type-checking-test-3.rs:11:13
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
LL | let _ = x as &dyn Bar<'a>; // Error
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
- |
- = help: consider replacing `'a` with `'static`
error: lifetime may not live long enough
- --> $DIR/type-checking-test-3.rs:18:13
+ --> $DIR/type-checking-test-3.rs:16:13
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) {
| -- lifetime `'a` defined here
LL | let _ = x as &dyn Bar<'static>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
- |
- = help: consider replacing `'a` with `'static`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
index b3aa2279a..b2db3a127 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo<'a>: Bar<'a> {}
trait Bar<'a> {}
@@ -10,12 +9,12 @@ fn test_correct(x: &dyn Foo<'static>) {
fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
let _ = x as &dyn Bar<'a>; // Error
- //~^ ERROR lifetime may not live long enough
+ //~^ ERROR lifetime may not live long enough
}
fn test_wrong2<'a>(x: &dyn Foo<'a>) {
let _ = x as &dyn Bar<'static>; // Error
- //~^ ERROR lifetime may not live long enough
+ //~^ ERROR lifetime may not live long enough
}
fn main() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr
index 5ad151b50..e6cb6a753 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/type-checking-test-3.rs:12:13
+ --> $DIR/type-checking-test-3.rs:11:13
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
@@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'a>; // Error
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/type-checking-test-3.rs:17:13
+ --> $DIR/type-checking-test-3.rs:16:13
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) {
| -- lifetime `'a` defined here
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr
index a3411f40a..8d506e580 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr
@@ -1,33 +1,52 @@
error: lifetime may not live long enough
- --> $DIR/type-checking-test-4.rs:17:13
+ --> $DIR/type-checking-test-4.rs:15:13
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
LL | let _ = x as &dyn Bar<'static, 'a>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
- |
- = help: consider replacing `'a` with `'static`
error: lifetime may not live long enough
- --> $DIR/type-checking-test-4.rs:22:13
+ --> $DIR/type-checking-test-4.rs:20:13
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
LL | let _ = x as &dyn Bar<'a, 'static>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
- |
- = help: consider replacing `'a` with `'static`
error: lifetime may not live long enough
- --> $DIR/type-checking-test-4.rs:29:5
+ --> $DIR/type-checking-test-4.rs:26:5
|
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
-...
+LL | let y = x as &dyn Bar<'_, '_>;
LL | y.get_b() // ERROR
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/type-checking-test-4.rs:31:5
+ |
+LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+ | -- lifetime `'a` defined here
+LL | <_ as Bar>::get_b(x) // ERROR
+ | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/type-checking-test-4.rs:36:5
+ |
+LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+ | -- lifetime `'a` defined here
+LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/type-checking-test-4.rs:44:5
|
- = help: consider replacing `'a` with `'static`
+LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+ | -- lifetime `'a` defined here
+...
+LL | z.get_b() // ERROR
+ | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
index 70ccc87fc..f40c48f0d 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
@@ -1,5 +1,4 @@
#![feature(trait_upcasting)]
-#![allow(incomplete_features)]
trait Foo<'a>: Bar<'a, 'a> {}
trait Bar<'a, 'b> {
@@ -14,28 +13,28 @@ fn test_correct(x: &dyn Foo<'static>) {
fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
let _ = x as &dyn Bar<'static, 'a>; // Error
- //~^ ERROR lifetime may not live long enough
+ //~^ ERROR lifetime may not live long enough
}
fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
let _ = x as &dyn Bar<'a, 'static>; // Error
- //~^ ERROR lifetime may not live long enough
+ //~^ ERROR lifetime may not live long enough
}
fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
let y = x as &dyn Bar<'_, '_>;
y.get_b() // ERROR
- //~^ ERROR lifetime may not live long enough
+ //~^ ERROR lifetime may not live long enough
}
fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
<_ as Bar>::get_b(x) // ERROR
- //~^ ERROR lifetime may not live long enough
+ //~^ ERROR lifetime may not live long enough
}
fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
<_ as Bar<'_, '_>>::get_b(x) // ERROR
- //~^ ERROR lifetime may not live long enough
+ //~^ ERROR lifetime may not live long enough
}
fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
@@ -43,7 +42,7 @@ fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
y.get_b(); // ERROR
let z = y;
z.get_b() // ERROR
- //~^ ERROR lifetime may not live long enough
+ //~^ ERROR lifetime may not live long enough
}
fn main() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
index 436129d0b..8d506e580 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/type-checking-test-4.rs:16:13
+ --> $DIR/type-checking-test-4.rs:15:13
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
@@ -7,7 +7,7 @@ LL | let _ = x as &dyn Bar<'static, 'a>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/type-checking-test-4.rs:21:13
+ --> $DIR/type-checking-test-4.rs:20:13
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
| -- lifetime `'a` defined here
@@ -15,7 +15,7 @@ LL | let _ = x as &dyn Bar<'a, 'static>; // Error
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/type-checking-test-4.rs:27:5
+ --> $DIR/type-checking-test-4.rs:26:5
|
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
@@ -24,7 +24,7 @@ LL | y.get_b() // ERROR
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/type-checking-test-4.rs:32:5
+ --> $DIR/type-checking-test-4.rs:31:5
|
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
@@ -32,7 +32,7 @@ LL | <_ as Bar>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/type-checking-test-4.rs:37:5
+ --> $DIR/type-checking-test-4.rs:36:5
|
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
@@ -40,7 +40,7 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/type-checking-test-4.rs:45:5
+ --> $DIR/type-checking-test-4.rs:44:5
|
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| -- lifetime `'a` defined here
diff --git a/src/test/ui/transmutability/arrays/issue-103783-array-length.rs b/src/test/ui/transmutability/arrays/issue-103783-array-length.rs
new file mode 100644
index 000000000..cb36e539e
--- /dev/null
+++ b/src/test/ui/transmutability/arrays/issue-103783-array-length.rs
@@ -0,0 +1,24 @@
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code)]
+
+mod assert {
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
+ pub struct Context;
+
+ pub fn is_maybe_transmutable<Src, Dst>()
+ where
+ Dst: BikeshedIntrinsicFrom<
+ Src,
+ Context,
+ { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
+ >,
+ {
+ }
+}
+
+fn test() {
+ type NaughtyLenArray = [u32; 3.14159]; //~ ERROR mismatched types
+ type JustUnit = ();
+ assert::is_maybe_transmutable::<JustUnit, NaughtyLenArray>();
+}
diff --git a/src/test/ui/transmutability/arrays/issue-103783-array-length.stderr b/src/test/ui/transmutability/arrays/issue-103783-array-length.stderr
new file mode 100644
index 000000000..37774c59e
--- /dev/null
+++ b/src/test/ui/transmutability/arrays/issue-103783-array-length.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-103783-array-length.rs:21:34
+ |
+LL | type NaughtyLenArray = [u32; 3.14159];
+ | ^^^^^^^ expected `usize`, found floating-point number
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/transmute/transmute-padding-ice.rs b/src/test/ui/transmute/transmute-padding-ice.rs
new file mode 100644
index 000000000..a1be7075a
--- /dev/null
+++ b/src/test/ui/transmute/transmute-padding-ice.rs
@@ -0,0 +1,29 @@
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code)]
+
+mod assert {
+ use std::mem::{Assume, BikeshedIntrinsicFrom};
+ pub struct Context;
+
+ pub fn is_maybe_transmutable<Src, Dst>()
+ where
+ Dst: BikeshedIntrinsicFrom<
+ Src,
+ Context,
+ { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
+ >,
+ {
+ }
+}
+
+fn test() {
+ #[repr(C, align(2))]
+ struct A(u8, u8);
+
+ #[repr(C)]
+ struct B(u8, u8);
+
+ assert::is_maybe_transmutable::<B, A>();
+ //~^ ERROR cannot be safely transmuted
+}
diff --git a/src/test/ui/transmute/transmute-padding-ice.stderr b/src/test/ui/transmute/transmute-padding-ice.stderr
new file mode 100644
index 000000000..c9233890f
--- /dev/null
+++ b/src/test/ui/transmute/transmute-padding-ice.stderr
@@ -0,0 +1,24 @@
+error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`.
+ --> $DIR/transmute-padding-ice.rs:27:40
+ |
+LL | assert::is_maybe_transmutable::<B, A>();
+ | ^ `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`.
+ |
+ = help: the trait `BikeshedIntrinsicFrom<B, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `A`
+note: required by a bound in `is_maybe_transmutable`
+ --> $DIR/transmute-padding-ice.rs:11:14
+ |
+LL | pub fn is_maybe_transmutable<Src, Dst>()
+ | --------------------- required by a bound in this
+LL | where
+LL | Dst: BikeshedIntrinsicFrom<
+ | ______________^
+LL | | Src,
+LL | | Context,
+LL | | { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
+LL | | >,
+ | |_________^ required by this bound in `is_maybe_transmutable`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr b/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr
index c9f2a3ed9..f738b03ee 100644
--- a/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr
+++ b/src/test/ui/try-block/try-block-maybe-bad-lifetime.stderr
@@ -23,6 +23,10 @@ LL | println!("{}", x);
| ^ value borrowed here after move
|
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | ::std::mem::drop(x.clone());
+ | ++++++++
error[E0506]: cannot assign to `i` because it is borrowed
--> $DIR/try-block-maybe-bad-lifetime.rs:40:9
diff --git a/src/test/ui/try-trait/bad-interconversion.stderr b/src/test/ui/try-trait/bad-interconversion.stderr
index 419a86bf3..a49630adb 100644
--- a/src/test/ui/try-trait/bad-interconversion.stderr
+++ b/src/test/ui/try-trait/bad-interconversion.stderr
@@ -8,15 +8,8 @@ LL | Ok(Err(123_i32)?)
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `From<T>`:
- <f32 as From<i16>>
- <f32 as From<i8>>
- <f32 as From<u16>>
- <f32 as From<u8>>
- <f64 as From<f32>>
- <f64 as From<i16>>
- <f64 as From<i32>>
- <f64 as From<i8>>
- and 68 others
+ <u8 as From<NonZeroU8>>
+ <u8 as From<bool>>
= note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
index 15d15f2f4..6870b9d7d 100644
--- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
@@ -2,7 +2,7 @@ error[E0533]: expected unit struct, unit variant or constant, found tuple varian
--> $DIR/incorrect-variant-form-through-Self-issue-58006.rs:8:13
|
LL | Self::A => (),
- | ^^^^^^^
+ | ^^^^^^^ not a unit struct, unit variant or constant
error: aborting due to previous error
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs
index e4abb96b4..5ed7988e4 100644
--- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs
@@ -6,7 +6,7 @@ type Alias = Enum;
fn main() {
Alias::Braced;
- //~^ ERROR expected unit struct, unit variant or constant, found struct variant `Alias::Braced` [E0533]
+ //~^ ERROR expected value, found struct variant `Alias::Braced` [E0533]
let Alias::Braced = panic!();
//~^ ERROR expected unit struct, unit variant or constant, found struct variant `Alias::Braced` [E0533]
let Alias::Braced(..) = panic!();
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
index 8f3180a86..c9ac99ede 100644
--- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
@@ -1,20 +1,20 @@
-error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced`
+error[E0533]: expected value, found struct variant `Alias::Braced`
--> $DIR/incorrect-variant-form-through-alias-caught.rs:8:5
|
LL | Alias::Braced;
- | ^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^ not a value
error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced`
--> $DIR/incorrect-variant-form-through-alias-caught.rs:10:9
|
LL | let Alias::Braced = panic!();
- | ^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^ not a unit struct, unit variant or constant
error[E0164]: expected tuple struct or tuple variant, found struct variant `Alias::Braced`
--> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9
|
LL | let Alias::Braced(..) = panic!();
- | ^^^^^^^^^^^^^^^^^ not a tuple variant or struct
+ | ^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
error[E0618]: expected function, found enum variant `Alias::Unit`
--> $DIR/incorrect-variant-form-through-alias-caught.rs:15:5
@@ -37,7 +37,7 @@ error[E0164]: expected tuple struct or tuple variant, found unit variant `Alias:
--> $DIR/incorrect-variant-form-through-alias-caught.rs:17:9
|
LL | let Alias::Unit() = panic!();
- | ^^^^^^^^^^^^^ not a tuple variant or struct
+ | ^^^^^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to 5 previous errors
diff --git a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr
index 4775e6882..576fc6a4f 100644
--- a/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr
+++ b/src/test/ui/type-alias-enum-variants/self-in-enum-definition.stderr
@@ -14,6 +14,46 @@ note: ...which requires const-evaluating + checking `Alpha::V3::{constant#0}`...
|
LL | V3 = Self::V1 {} as u8 + 2,
| ^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires caching mir of `Alpha::V3::{constant#0}` for CTFE...
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires elaborating drops for `Alpha::V3::{constant#0}`...
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires borrow-checking `Alpha::V3::{constant#0}`...
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires processing MIR for `Alpha::V3::{constant#0}`...
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const checking `Alpha::V3::{constant#0}`...
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires preparing `Alpha::V3::{constant#0}` for borrow checking...
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires unsafety-checking `Alpha::V3::{constant#0}`...
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires building MIR for `Alpha::V3::{constant#0}`...
+ --> $DIR/self-in-enum-definition.rs:5:10
+ |
+LL | V3 = Self::V1 {} as u8 + 2,
+ | ^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing layout of `Alpha`...
= note: ...which again requires simplifying constant for the type system `Alpha::V3::{constant#0}`, completing the cycle
note: cycle used when collecting item types in top-level module
diff --git a/src/test/ui/type-alias-impl-trait/coherence.rs b/src/test/ui/type-alias-impl-trait/coherence.rs
index 98ac215ad..077a31494 100644
--- a/src/test/ui/type-alias-impl-trait/coherence.rs
+++ b/src/test/ui/type-alias-impl-trait/coherence.rs
@@ -12,6 +12,6 @@ fn use_alias<T>(val: T) -> AliasOfForeignType<T> {
}
impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
-//~^ ERROR cannot implement trait on type alias impl trait
+//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/coherence.stderr b/src/test/ui/type-alias-impl-trait/coherence.stderr
index 3ce25d94f..c923eb08a 100644
--- a/src/test/ui/type-alias-impl-trait/coherence.stderr
+++ b/src/test/ui/type-alias-impl-trait/coherence.stderr
@@ -1,14 +1,14 @@
-error: cannot implement trait on type alias impl trait
- --> $DIR/coherence.rs:14:41
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+ --> $DIR/coherence.rs:14:1
|
LL | impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
- | ^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------
+ | | |
+ | | `AliasOfForeignType<T>` is not defined in the current crate
+ | impl doesn't use only types from inside the current crate
|
-note: type alias impl trait defined here
- --> $DIR/coherence.rs:9:30
- |
-LL | type AliasOfForeignType<T> = impl LocalTrait;
- | ^^^^^^^^^^^^^^^
+ = note: define and implement a trait or new type instead
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0117`.
diff --git a/src/test/ui/type-alias-impl-trait/coherence_generalization.rs b/src/test/ui/type-alias-impl-trait/coherence_generalization.rs
new file mode 100644
index 000000000..5c9ad9498
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/coherence_generalization.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+trait Trait {}
+type Opaque<T> = impl Sized;
+fn foo<T>() -> Opaque<T> {
+ ()
+}
+
+impl<T, V> Trait for (T, V, V, u32) {}
+impl<U, V> Trait for (Opaque<U>, V, i32, V) {}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs b/src/test/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs
new file mode 100644
index 000000000..0efbd1c2b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+trait Foo {
+ type Assoc;
+}
+
+impl Foo for i32 {
+ type Assoc = u32;
+}
+type ImplTrait = impl Sized;
+fn constrain() -> ImplTrait {
+ 1u64
+}
+impl Foo for i64 {
+ type Assoc = ImplTrait;
+}
+
+trait Bar<T> {}
+
+impl<T: Foo> Bar<<T as Foo>::Assoc> for T {}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs b/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs
new file mode 100644
index 000000000..3f1a9d12b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs
@@ -0,0 +1,33 @@
+#![feature(type_alias_impl_trait)]
+
+trait Foo {}
+impl Foo for () {}
+impl Foo for i32 {}
+
+type Bar<T: Foo> = impl std::fmt::Debug;
+fn defining_use<T: Foo>() -> Bar<T> {
+ 42
+}
+
+trait Bop {}
+
+impl Bop for Bar<()> {}
+
+// If the hidden type is the same, this is effectively a second impl for the same type.
+impl Bop for Bar<i32> {}
+//~^ ERROR conflicting implementations
+
+type Barr = impl std::fmt::Debug;
+fn defining_use2() -> Barr {
+ 42
+}
+
+// Even completely different opaque types must conflict.
+impl Bop for Barr {}
+//~^ ERROR conflicting implementations
+
+// And obviously the hidden type must conflict, too.
+impl Bop for i32 {}
+//~^ ERROR conflicting implementations
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr b/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr
new file mode 100644
index 000000000..aaf75cc3d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr
@@ -0,0 +1,30 @@
+error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
+ --> $DIR/impl_trait_for_same_tait.rs:17:1
+ |
+LL | impl Bop for Bar<()> {}
+ | -------------------- first implementation here
+...
+LL | impl Bop for Bar<i32> {}
+ | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
+
+error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
+ --> $DIR/impl_trait_for_same_tait.rs:26:1
+ |
+LL | impl Bop for Bar<()> {}
+ | -------------------- first implementation here
+...
+LL | impl Bop for Barr {}
+ | ^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
+
+error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
+ --> $DIR/impl_trait_for_same_tait.rs:30:1
+ |
+LL | impl Bop for Bar<()> {}
+ | -------------------- first implementation here
+...
+LL | impl Bop for i32 {}
+ | ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/type-alias-impl-trait/impl_trait_for_tait.rs b/src/test/ui/type-alias-impl-trait/impl_trait_for_tait.rs
new file mode 100644
index 000000000..9f32c5d88
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/impl_trait_for_tait.rs
@@ -0,0 +1,21 @@
+// compile-flags: --crate-type=lib
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+type Alias = impl Sized;
+
+fn constrain() -> Alias {
+ 1i32
+}
+
+trait HideIt {
+ type Assoc;
+}
+
+impl HideIt for () {
+ type Assoc = Alias;
+}
+
+pub trait Yay {}
+
+impl Yay for <() as HideIt>::Assoc {}
diff --git a/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs b/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs
new file mode 100644
index 000000000..8ec20acef
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs
@@ -0,0 +1,19 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+pub trait Yay { }
+impl Yay for Foo { }
+
+fn foo() {
+ is_yay::<u32>(); //~ ERROR: the trait bound `u32: Yay` is not satisfied
+ is_debug::<u32>(); // OK
+ is_yay::<Foo>(); // OK
+ is_debug::<Foo>(); // OK
+}
+
+fn is_yay<T: Yay>() { }
+fn is_debug<T: Debug>() { }
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr b/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr
new file mode 100644
index 000000000..1c83105a1
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `u32: Yay` is not satisfied
+ --> $DIR/impl_trait_for_tait_bound.rs:10:14
+ |
+LL | is_yay::<u32>();
+ | ^^^ the trait `Yay` is not implemented for `u32`
+ |
+ = help: the trait `Yay` is implemented for `Foo`
+note: required by a bound in `is_yay`
+ --> $DIR/impl_trait_for_tait_bound.rs:16:14
+ |
+LL | fn is_yay<T: Yay>() { }
+ | ^^^ required by this bound in `is_yay`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs b/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs
new file mode 100644
index 000000000..a4b8c2d19
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs
@@ -0,0 +1,16 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+
+pub trait Yay { }
+impl Yay for u32 { }
+
+fn foo() {
+ is_yay::<Foo>(); //~ ERROR: the trait bound `Foo: Yay` is not satisfied
+}
+
+fn is_yay<T: Yay>() { }
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr b/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr
new file mode 100644
index 000000000..a6440f02c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `Foo: Yay` is not satisfied
+ --> $DIR/impl_trait_for_tait_bound2.rs:11:14
+ |
+LL | is_yay::<Foo>();
+ | ^^^ the trait `Yay` is not implemented for `Foo`
+ |
+ = help: the trait `Yay` is implemented for `u32`
+note: required by a bound in `is_yay`
+ --> $DIR/impl_trait_for_tait_bound2.rs:14:14
+ |
+LL | fn is_yay<T: Yay>() { }
+ | ^^^ required by this bound in `is_yay`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
new file mode 100644
index 000000000..ee9bce15d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait Callable {
+ type Output;
+ fn call() -> Self::Output;
+}
+
+impl<'a> Callable for &'a () {
+ type Output = impl Sized;
+ fn call() -> Self::Output {}
+}
+
+fn test<'a>() -> impl Sized {
+ <&'a () as Callable>::call()
+}
+
+fn want_static<T: 'static>(_: T) {}
+
+fn test2<'a>() {
+ want_static(<&'a () as Callable>::call());
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs
new file mode 100644
index 000000000..ae21a9134
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs
@@ -0,0 +1,38 @@
+#![feature(type_alias_impl_trait)]
+
+trait Callable {
+ type Output;
+ fn call(x: Self) -> Self::Output;
+}
+
+trait PlusOne {
+ fn plus_one(&mut self);
+}
+
+impl<'a> PlusOne for &'a mut i32 {
+ fn plus_one(&mut self) {
+ **self += 1;
+ }
+}
+
+impl<T: PlusOne> Callable for T {
+ type Output = impl PlusOne;
+ fn call(t: T) -> Self::Output { t }
+}
+
+fn test<'a>(y: &'a mut i32) -> impl PlusOne {
+ <&'a mut i32 as Callable>::call(y)
+ //~^ ERROR hidden type for `impl PlusOne` captures lifetime that does not appear in bounds
+}
+
+fn main() {
+ let mut z = 42;
+ let mut thing = test(&mut z);
+ let mut thing2 = test(&mut z);
+ thing.plus_one();
+ assert_eq!(z, 43);
+ thing2.plus_one();
+ assert_eq!(z, 44);
+ thing.plus_one();
+ assert_eq!(z, 45);
+}
diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr
new file mode 100644
index 000000000..0ed8a703b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr
@@ -0,0 +1,16 @@
+error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds
+ --> $DIR/imply_bounds_from_bounds_param.rs:24:5
+ |
+LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne {
+ | -- hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here
+LL | <&'a mut i32 as Callable>::call(y)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound
+ |
+LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a {
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
index 067ed7ea1..cad3e0f66 100644
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
@@ -1,7 +1,6 @@
+// check-pass
// Regression test for issue #57611
// Ensures that we don't ICE
-// FIXME: This should compile, but it currently doesn't
-// known-bug: unknown
#![feature(trait_alias)]
#![feature(type_alias_impl_trait)]
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
deleted file mode 100644
index 6344f114a..000000000
--- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error[E0308]: mismatched types
- --> $DIR/issue-57611-trait-alias.rs:21:9
- |
-LL | |x| x
- | ^^^^^ one type is more general than the other
- |
- = note: expected trait `for<'a> Fn<(&'a X,)>`
- found trait `Fn<(&X,)>`
-note: this closure does not fulfill the lifetime requirements
- --> $DIR/issue-57611-trait-alias.rs:21:9
- |
-LL | |x| x
- | ^^^
-
-error: implementation of `FnOnce` is not general enough
- --> $DIR/issue-57611-trait-alias.rs:21:9
- |
-LL | |x| x
- | ^^^^^ implementation of `FnOnce` is not general enough
- |
- = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
- = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.rs b/src/test/ui/type-alias-impl-trait/issue-65384.rs
index 9a119c4d2..9a9b2269f 100644
--- a/src/test/ui/type-alias-impl-trait/issue-65384.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-65384.rs
@@ -8,7 +8,7 @@ impl MyTrait for () {}
type Bar = impl MyTrait;
impl MyTrait for Bar {}
-//~^ ERROR: cannot implement trait on type alias impl trait
+//~^ ERROR: conflicting implementations of trait `MyTrait` for type `()`
fn bazr() -> Bar { }
diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.stderr b/src/test/ui/type-alias-impl-trait/issue-65384.stderr
index 41bcea27e..f6692ae32 100644
--- a/src/test/ui/type-alias-impl-trait/issue-65384.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-65384.stderr
@@ -1,14 +1,12 @@
-error: cannot implement trait on type alias impl trait
- --> $DIR/issue-65384.rs:10:18
+error[E0119]: conflicting implementations of trait `MyTrait` for type `()`
+ --> $DIR/issue-65384.rs:10:1
|
+LL | impl MyTrait for () {}
+ | ------------------- first implementation here
+...
LL | impl MyTrait for Bar {}
- | ^^^
- |
-note: type alias impl trait defined here
- --> $DIR/issue-65384.rs:8:12
- |
-LL | type Bar = impl MyTrait;
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
index fb56cc54d..b97e444c6 100644
--- a/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
@@ -1,6 +1,8 @@
// Regression test for issue #76202
// Tests that we don't ICE when we have a trait impl on a TAIT.
+// check-pass
+
#![feature(type_alias_impl_trait)]
trait Dummy {}
@@ -14,7 +16,12 @@ trait Test {
}
impl Test for F {
- //~^ ERROR cannot implement trait
+ fn test(self) {}
+}
+
+// Ok because `i32` does not implement `Dummy`,
+// so it can't possibly be the hidden type of `F`.
+impl Test for i32 {
fn test(self) {}
}
diff --git a/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr
deleted file mode 100644
index 2d4a6854a..000000000
--- a/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: cannot implement trait on type alias impl trait
- --> $DIR/issue-76202-trait-impl-for-tait.rs:16:15
- |
-LL | impl Test for F {
- | ^
- |
-note: type alias impl trait defined here
- --> $DIR/issue-76202-trait-impl-for-tait.rs:9:10
- |
-LL | type F = impl Dummy;
- | ^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs
index fa25d8f76..2ba4befea 100644
--- a/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs
@@ -1,6 +1,8 @@
// Regression test for issues #84660 and #86411: both are variations on #76202.
// Tests that we don't ICE when we have an opaque type appearing anywhere in an impl header.
+// check-pass
+
#![feature(type_alias_impl_trait)]
trait Foo {}
@@ -12,7 +14,7 @@ trait TraitArg<T> {
fn f();
}
-impl TraitArg<Bar> for () { //~ ERROR cannot implement trait
+impl TraitArg<Bar> for () {
fn f() {
println!("ho");
}
diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr
deleted file mode 100644
index bb70d07be..000000000
--- a/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: cannot implement trait on type alias impl trait
- --> $DIR/issue-84660-trait-impl-for-tait.rs:15:15
- |
-LL | impl TraitArg<Bar> for () {
- | ^^^
- |
-note: type alias impl trait defined here
- --> $DIR/issue-84660-trait-impl-for-tait.rs:8:12
- |
-LL | type Bar = impl Foo;
- | ^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
index f12d1b6d9..48d4b0c96 100644
--- a/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
@@ -13,14 +13,14 @@ trait Trait<T, In> {
fn convert(i: In) -> Self::Out;
}
-impl<In, Out> Trait<Bar, In> for Out { //~ ERROR cannot implement trait
+impl<In, Out> Trait<Bar, In> for Out {
type Out = Out;
fn convert(_i: In) -> Self::Out {
unreachable!();
}
}
-impl<In, Out> Trait<(), In> for Out {
+impl<In, Out> Trait<(), In> for Out { //~ ERROR conflicting implementations of trait `Trait<Bar, _>`
type Out = In;
fn convert(i: In) -> Self::Out {
i
diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr
index f2d600fb4..6a75e1bd2 100644
--- a/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr
@@ -1,14 +1,12 @@
-error: cannot implement trait on type alias impl trait
- --> $DIR/issue-84660-unsoundness.rs:16:21
+error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
+ --> $DIR/issue-84660-unsoundness.rs:23:1
|
LL | impl<In, Out> Trait<Bar, In> for Out {
- | ^^^
- |
-note: type alias impl trait defined here
- --> $DIR/issue-84660-unsoundness.rs:8:12
- |
-LL | type Bar = impl Foo;
- | ^^^^^^^^
+ | ------------------------------------ first implementation here
+...
+LL | impl<In, Out> Trait<(), In> for Out {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.rs b/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.rs
index 428194058..01d1f5db1 100644
--- a/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.rs
+++ b/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.rs
@@ -2,6 +2,6 @@
type Opaque<'a, T> = impl Sized;
fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
-//~^ ERROR: non-defining opaque type use in defining scope
+//~^ ERROR: hidden type for `Opaque<'a, T>` captures lifetime that does not appear in bounds
fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
index df2b3ed19..65a0af0d2 100644
--- a/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
+++ b/src/test/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
@@ -1,8 +1,11 @@
-error: non-defining opaque type use in defining scope
+error[E0700]: hidden type for `Opaque<'a, T>` captures lifetime that does not appear in bounds
--> $DIR/missing_lifetime_bound.rs:4:47
|
LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
- | ^ lifetime `'a` is part of concrete type but not used in parameter list of the `impl Trait` type alias
+ | -- ^
+ | |
+ | hidden type `&'a i32` captures the lifetime `'a` as defined here
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs
index ebf3a99bb..b0ebdd1bf 100644
--- a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs
@@ -4,11 +4,11 @@
use std::fmt::Debug;
type FooX = impl Debug;
+//~^ ERROR unconstrained opaque type
trait Foo<A> { }
impl Foo<FooX> for () { }
-//~^ cannot implement trait on type alias impl trait
fn foo() -> impl Foo<FooX> {
()
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr
index 4a3fb1673..b1d947a9c 100644
--- a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr
@@ -1,14 +1,10 @@
-error: cannot implement trait on type alias impl trait
- --> $DIR/nested-tait-inference3.rs:10:10
- |
-LL | impl Foo<FooX> for () { }
- | ^^^^
- |
-note: type alias impl trait defined here
+error: unconstrained opaque type
--> $DIR/nested-tait-inference3.rs:6:13
|
LL | type FooX = impl Debug;
| ^^^^^^^^^^
+ |
+ = note: `FooX` must be used in combination with a concrete type within the same module
error: aborting due to previous error
diff --git a/src/test/ui/type-alias-impl-trait/self-referential-2.stderr b/src/test/ui/type-alias-impl-trait/self-referential-2.stderr
index 2b505d307..c2cf70687 100644
--- a/src/test/ui/type-alias-impl-trait/self-referential-2.stderr
+++ b/src/test/ui/type-alias-impl-trait/self-referential-2.stderr
@@ -7,16 +7,7 @@ LL | 42_i32
| ------ return type was inferred to be `i32` here
|
= help: the trait `PartialEq<Foo>` is not implemented for `i32`
- = help: the following other types implement trait `PartialEq<Rhs>`:
- f32
- f64
- i128
- i16
- i32
- i64
- i8
- isize
- and 6 others
+ = help: the trait `PartialEq` is implemented for `i32`
error: aborting due to previous error
diff --git a/src/test/ui/type-alias-impl-trait/self-referential-4.stderr b/src/test/ui/type-alias-impl-trait/self-referential-4.stderr
index 27880f792..98c762e3d 100644
--- a/src/test/ui/type-alias-impl-trait/self-referential-4.stderr
+++ b/src/test/ui/type-alias-impl-trait/self-referential-4.stderr
@@ -7,16 +7,7 @@ LL | i
| - return type was inferred to be `&i32` here
|
= help: the trait `PartialEq<Bar<'b, 'static>>` is not implemented for `&i32`
- = help: the following other types implement trait `PartialEq<Rhs>`:
- f32
- f64
- i128
- i16
- i32
- i64
- i8
- isize
- and 6 others
+ = help: the trait `PartialEq` is implemented for `i32`
error[E0277]: can't compare `&i32` with `Foo<'static, 'b>`
--> $DIR/self-referential-4.rs:11:31
@@ -27,16 +18,7 @@ LL | i
| - return type was inferred to be `&i32` here
|
= help: the trait `PartialEq<Foo<'static, 'b>>` is not implemented for `&i32`
- = help: the following other types implement trait `PartialEq<Rhs>`:
- f32
- f64
- i128
- i16
- i32
- i64
- i8
- isize
- and 6 others
+ = help: the trait `PartialEq` is implemented for `i32`
error[E0277]: can't compare `&i32` with `Moo<'static, 'a>`
--> $DIR/self-referential-4.rs:17:31
@@ -47,16 +29,7 @@ LL | i
| - return type was inferred to be `&i32` here
|
= help: the trait `PartialEq<Moo<'static, 'a>>` is not implemented for `&i32`
- = help: the following other types implement trait `PartialEq<Rhs>`:
- f32
- f64
- i128
- i16
- i32
- i64
- i8
- isize
- and 6 others
+ = help: the trait `PartialEq` is implemented for `i32`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/type-alias-impl-trait/self-referential.stderr b/src/test/ui/type-alias-impl-trait/self-referential.stderr
index 97d510f68..aff489d70 100644
--- a/src/test/ui/type-alias-impl-trait/self-referential.stderr
+++ b/src/test/ui/type-alias-impl-trait/self-referential.stderr
@@ -8,16 +8,7 @@ LL | i
| - return type was inferred to be `&i32` here
|
= help: the trait `PartialEq<Bar<'b, 'a>>` is not implemented for `&i32`
- = help: the following other types implement trait `PartialEq<Rhs>`:
- f32
- f64
- i128
- i16
- i32
- i64
- i8
- isize
- and 6 others
+ = help: the trait `PartialEq` is implemented for `i32`
error[E0277]: can't compare `&i32` with `(i32, &i32)`
--> $DIR/self-referential.rs:12:31
@@ -29,16 +20,7 @@ LL | (42, i)
| ------- return type was inferred to be `(i32, &i32)` here
|
= help: the trait `PartialEq<(i32, &i32)>` is not implemented for `&i32`
- = help: the following other types implement trait `PartialEq<Rhs>`:
- f32
- f64
- i128
- i16
- i32
- i64
- i8
- isize
- and 6 others
+ = help: the trait `PartialEq` is implemented for `i32`
error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})`
--> $DIR/self-referential.rs:19:31
@@ -50,16 +32,7 @@ LL | (42, i)
| ------- return type was inferred to be `(i32, &i32)` here
|
= help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0})>` is not implemented for `&i32`
- = help: the following other types implement trait `PartialEq<Rhs>`:
- f32
- f64
- i128
- i16
- i32
- i64
- i8
- isize
- and 6 others
+ = help: the trait `PartialEq` is implemented for `i32`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/type-alias-impl-trait/self_implication.rs b/src/test/ui/type-alias-impl-trait/self_implication.rs
new file mode 100644
index 000000000..4e805ee30
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/self_implication.rs
@@ -0,0 +1,38 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+fn foo() {
+ struct Foo<'a> {
+ x: &'a mut u8,
+ }
+ impl<'a> Foo<'a> {
+ fn foo(&self) -> impl Sized {}
+ }
+ // use site
+ let mut x = 5;
+ let y = Foo { x: &mut x };
+ let z = y.foo();
+ let _a = &x; // invalidate the `&'a mut`in `y`
+ let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live
+}
+
+fn bar() {
+ struct Foo<'a> {
+ x: &'a mut u8,
+ }
+
+ // desugared
+ type FooX<'a> = impl Sized;
+ impl<'a> Foo<'a> {
+ fn foo(&self) -> FooX<'a> {}
+ }
+
+ // use site
+ let mut x = 5;
+ let y = Foo { x: &mut x };
+ let z = y.foo();
+ let _a = &x; // invalidate the `&'a mut`in `y`
+ let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live
+}
+
+fn main() {}
diff --git a/src/test/ui/type/issue-103271.rs b/src/test/ui/type/issue-103271.rs
new file mode 100644
index 000000000..7cd76286a
--- /dev/null
+++ b/src/test/ui/type/issue-103271.rs
@@ -0,0 +1,18 @@
+fn main() {
+ let iter_fun = <&[u32]>::iter;
+ //~^ ERROR no function or associated item named `iter` found for reference `&[u32]` in the current scope [E0599]
+ //~| function or associated item not found in `&[u32]`
+ //~| HELP the function `iter` is implemented on `[u32]`
+ for item in iter_fun(&[1,1]) {
+ let x: &u32 = item;
+ assert_eq!(x, &1);
+ }
+ let iter_fun2 = <(&[u32])>::iter;
+ //~^ no function or associated item named `iter` found for reference `&[u32]` in the current scope [E0599]
+ //~| function or associated item not found in `&[u32]`
+ //~| HELP the function `iter` is implemented on `[u32]`
+ for item2 in iter_fun2(&[1,1]) {
+ let x: &u32 = item2;
+ assert_eq!(x, &1);
+ }
+}
diff --git a/src/test/ui/type/issue-103271.stderr b/src/test/ui/type/issue-103271.stderr
new file mode 100644
index 000000000..f4dac51b2
--- /dev/null
+++ b/src/test/ui/type/issue-103271.stderr
@@ -0,0 +1,25 @@
+error[E0599]: no function or associated item named `iter` found for reference `&[u32]` in the current scope
+ --> $DIR/issue-103271.rs:2:30
+ |
+LL | let iter_fun = <&[u32]>::iter;
+ | ^^^^ function or associated item not found in `&[u32]`
+ |
+help: the function `iter` is implemented on `[u32]`
+ |
+LL | let iter_fun = <[u32]>::iter;
+ | ~~~~~
+
+error[E0599]: no function or associated item named `iter` found for reference `&[u32]` in the current scope
+ --> $DIR/issue-103271.rs:10:33
+ |
+LL | let iter_fun2 = <(&[u32])>::iter;
+ | ^^^^ function or associated item not found in `&[u32]`
+ |
+help: the function `iter` is implemented on `[u32]`
+ |
+LL | let iter_fun2 = <([u32])>::iter;
+ | ~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/type/issue-94187-verbose-type-name.rs b/src/test/ui/type/issue-94187-verbose-type-name.rs
index 902ef5ade..3713a32eb 100644
--- a/src/test/ui/type/issue-94187-verbose-type-name.rs
+++ b/src/test/ui/type/issue-94187-verbose-type-name.rs
@@ -1,13 +1,16 @@
-// Check to insure that the output of `std::any::type_name` does not change based on -Zverbose
-// when printing constants
+// Check to insure that the output of `std::any::type_name` does not change based on `-Zverbose`
// run-pass
// edition: 2018
// revisions: normal verbose
// [verbose]compile-flags:-Zverbose
-struct Wrapper<const VALUE: usize>;
+use std::any::type_name;
fn main() {
- assert_eq!(std::any::type_name::<[u32; 0]>(), "[u32; 0]");
- assert_eq!(std::any::type_name::<Wrapper<0>>(), "issue_94187_verbose_type_name::Wrapper<0>");
+ assert_eq!(type_name::<[u32; 0]>(), "[u32; 0]");
+
+ struct Wrapper<const VALUE: usize>;
+ assert_eq!(type_name::<Wrapper<0>>(), "issue_94187_verbose_type_name::main::Wrapper<0>");
+
+ assert_eq!(type_name::<dyn Fn(u32) -> u32>(), "dyn core::ops::function::Fn(u32) -> u32");
}
diff --git a/src/test/ui/type/type-ascription-soundness.rs b/src/test/ui/type/type-ascription-soundness.rs
index d583fc213..08316cdcd 100644
--- a/src/test/ui/type/type-ascription-soundness.rs
+++ b/src/test/ui/type/type-ascription-soundness.rs
@@ -4,10 +4,10 @@
fn main() {
let arr = &[1u8, 2, 3];
- let ref x = arr: &[u8]; //~ ERROR mismatched types
- let ref mut x = arr: &[u8]; //~ ERROR mismatched types
- match arr: &[u8] { //~ ERROR mismatched types
+ let ref x = type_ascribe!(arr, &[u8]); //~ ERROR mismatched types
+ let ref mut x = type_ascribe!(arr, &[u8]); //~ ERROR mismatched types
+ match type_ascribe!(arr, &[u8]) { //~ ERROR mismatched types
ref x => {}
}
- let _len = (arr: &[u8]).len(); //~ ERROR mismatched types
+ let _len = type_ascribe!(arr, &[u8]).len(); //~ ERROR mismatched types
}
diff --git a/src/test/ui/type/type-ascription-soundness.stderr b/src/test/ui/type/type-ascription-soundness.stderr
index 6ed940823..522d5b2e3 100644
--- a/src/test/ui/type/type-ascription-soundness.stderr
+++ b/src/test/ui/type/type-ascription-soundness.stderr
@@ -1,35 +1,35 @@
error[E0308]: mismatched types
- --> $DIR/type-ascription-soundness.rs:7:17
+ --> $DIR/type-ascription-soundness.rs:7:31
|
-LL | let ref x = arr: &[u8];
- | ^^^ expected slice `[u8]`, found array `[u8; 3]`
+LL | let ref x = type_ascribe!(arr, &[u8]);
+ | ^^^ expected slice `[u8]`, found array `[u8; 3]`
|
= note: expected reference `&[u8]`
found reference `&[u8; 3]`
error[E0308]: mismatched types
- --> $DIR/type-ascription-soundness.rs:8:21
+ --> $DIR/type-ascription-soundness.rs:8:35
|
-LL | let ref mut x = arr: &[u8];
- | ^^^ expected slice `[u8]`, found array `[u8; 3]`
+LL | let ref mut x = type_ascribe!(arr, &[u8]);
+ | ^^^ expected slice `[u8]`, found array `[u8; 3]`
|
= note: expected reference `&[u8]`
found reference `&[u8; 3]`
error[E0308]: mismatched types
- --> $DIR/type-ascription-soundness.rs:9:11
+ --> $DIR/type-ascription-soundness.rs:9:25
|
-LL | match arr: &[u8] {
- | ^^^ expected slice `[u8]`, found array `[u8; 3]`
+LL | match type_ascribe!(arr, &[u8]) {
+ | ^^^ expected slice `[u8]`, found array `[u8; 3]`
|
= note: expected reference `&[u8]`
found reference `&[u8; 3]`
error[E0308]: mismatched types
- --> $DIR/type-ascription-soundness.rs:12:17
+ --> $DIR/type-ascription-soundness.rs:12:30
|
-LL | let _len = (arr: &[u8]).len();
- | ^^^ expected slice `[u8]`, found array `[u8; 3]`
+LL | let _len = type_ascribe!(arr, &[u8]).len();
+ | ^^^ expected slice `[u8]`, found array `[u8; 3]`
|
= note: expected reference `&[u8]`
found reference `&[u8; 3]`
diff --git a/src/test/ui/type/type-ascription.rs b/src/test/ui/type/type-ascription.rs
index 7adb07442..e4a4c89d0 100644
--- a/src/test/ui/type/type-ascription.rs
+++ b/src/test/ui/type/type-ascription.rs
@@ -8,32 +8,32 @@
use std::mem;
-const C1: u8 = 10: u8;
-const C2: [u8; 1: usize] = [1];
+const C1: u8 = type_ascribe!(10, u8);
+const C2: [u8; type_ascribe!(1, usize)] = [1];
struct S {
a: u8
}
fn main() {
- assert_eq!(C1.into(): i32, 10);
+ assert_eq!(type_ascribe!(C1.into(), i32), 10);
assert_eq!(C2[0], 1);
- let s = S { a: 10: u8 };
+ let s = S { a: type_ascribe!(10, u8) };
let arr = &[1u8, 2, 3];
- let mut v = arr.iter().cloned().collect(): Vec<_>;
+ let mut v = type_ascribe!(arr.iter().cloned().collect(), Vec<_>);
v.push(4);
assert_eq!(v, [1, 2, 3, 4]);
- let a = 1: u8;
- let b = a.into(): u16;
- assert_eq!(v[a.into(): usize], 2);
+ let a = type_ascribe!(1, u8);
+ let b = type_ascribe!(a.into(), u16);
+ assert_eq!(v[type_ascribe!(a.into(), usize)], 2);
assert_eq!(mem::size_of_val(&a), 1);
assert_eq!(mem::size_of_val(&b), 2);
- assert_eq!(b, 1: u16);
+ assert_eq!(b, type_ascribe!(1, u16));
let mut v = Vec::new();
- v: Vec<u8> = vec![1, 2, 3]; // Place expression type ascription
+ type_ascribe!(v, Vec<u8>) = vec![1, 2, 3]; // Place expression type ascription
assert_eq!(v, [1u8, 2, 3]);
}
diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr
index cf77c057d..9ba63ffe9 100644
--- a/src/test/ui/type/type-check-defaults.stderr
+++ b/src/test/ui/type/type-check-defaults.stderr
@@ -66,15 +66,10 @@ LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
|
= help: the trait `Add<u8>` is not implemented for `i32`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
<&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&i32 as Add<&i32>>
+ <i32 as Add<&i32>>
+ <i32 as Add>
error: aborting due to 7 previous errors
diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs
index f37f093d9..caf5bade5 100644
--- a/src/test/ui/type/type-dependent-def-issue-49241.rs
+++ b/src/test/ui/type/type-dependent-def-issue-49241.rs
@@ -2,5 +2,5 @@ fn main() {
let v = vec![0];
const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant
let s: [u32; l] = v.into_iter().collect();
- //~^ERROR evaluation of constant value failed
+ //~^ constant
}
diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr
index 02f267c6c..af16a6e8f 100644
--- a/src/test/ui/type/type-dependent-def-issue-49241.stderr
+++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr
@@ -6,13 +6,12 @@ LL | const l: usize = v.count();
| |
| help: consider using `let` instead of `const`: `let l`
-error[E0080]: evaluation of constant value failed
+note: erroneous constant used
--> $DIR/type-dependent-def-issue-49241.rs:4:18
|
LL | let s: [u32; l] = v.into_iter().collect();
- | ^ referenced constant has errors
+ | ^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-Some errors have detailed explanations: E0080, E0435.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0435`.
diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs
index ce6fdf811..b3c127474 100644
--- a/src/test/ui/type_length_limit.rs
+++ b/src/test/ui/type_length_limit.rs
@@ -7,7 +7,7 @@
// The exact type depends on optimizations, so disable them.
#![allow(dead_code)]
-#![type_length_limit="4"]
+#![type_length_limit="8"]
macro_rules! link {
($id:ident, $t:ty) => {
@@ -15,14 +15,19 @@ macro_rules! link {
}
}
+link! { A1, B1 }
+link! { B1, C1 }
+link! { C1, D1 }
+link! { D1, E1 }
+link! { E1, A }
link! { A, B }
link! { B, C }
link! { C, D }
link! { D, E }
link! { E, F }
-link! { F, G }
+link! { F, G<Option<i32>, Option<i32>> }
-pub struct G;
+pub struct G<T, K>(std::marker::PhantomData::<(T, K)>);
fn main() {
drop::<Option<A>>(None);
diff --git a/src/test/ui/type_length_limit.stderr b/src/test/ui/type_length_limit.stderr
index 84ac48b1e..ff4874669 100644
--- a/src/test/ui/type_length_limit.stderr
+++ b/src/test/ui/type_length_limit.stderr
@@ -1,20 +1,11 @@
-error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((...,....., ...), ..., ...), ..., ...)>>`
+error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((..., ..., ...), ..., ...), ..., ...), ..., ...)>>`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | pub fn drop<T>(_x: T) {}
| ^^^^^^^^^^^^^^^^^^^^^
|
- = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
+ = help: consider adding a `#![type_length_limit="10"]` attribute to your crate
= note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
-error: reached the type-length limit while instantiating `<[closure@std::rt::lang_start<()...e<()>>::call_once - shim(vtable)`
- --> $SRC_DIR/core/src/ops/function.rs:LL:COL
- |
-LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = help: consider adding a `#![type_length_limit="8"]` attribute to your crate
- = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt'
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
diff --git a/src/test/ui/typeck/issue-103899.rs b/src/test/ui/typeck/issue-103899.rs
new file mode 100644
index 000000000..ac9e4c716
--- /dev/null
+++ b/src/test/ui/typeck/issue-103899.rs
@@ -0,0 +1,30 @@
+// check-fail
+// failure-status: 101
+// dont-check-compiler-stderr
+// known-bug: #103899
+
+trait BaseWithAssoc {
+ type Assoc;
+}
+
+trait WrapperWithAssoc {
+ type BaseAssoc: BaseWithAssoc;
+}
+
+struct Wrapper<B> {
+ inner: B,
+}
+
+struct ProjectToBase<T: BaseWithAssoc> {
+ data_type_h: T::Assoc,
+}
+
+struct DoubleProject<L: WrapperWithAssoc> {
+ buffer: Wrapper<ProjectToBase<L::BaseAssoc>>,
+}
+
+fn trigger<L: WrapperWithAssoc<BaseAssoc = ()>>() -> DoubleProject<L> {
+ loop {}
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/issue-104510-ice.rs b/src/test/ui/typeck/issue-104510-ice.rs
new file mode 100644
index 000000000..157bdf07e
--- /dev/null
+++ b/src/test/ui/typeck/issue-104510-ice.rs
@@ -0,0 +1,16 @@
+// needs-asm-support
+// only-x86_64
+
+struct W<T: ?Sized>(Oops);
+//~^ ERROR cannot find type `Oops` in this scope
+
+unsafe fn test() {
+ let j = W(());
+ let pointer = &j as *const _;
+ core::arch::asm!(
+ "nop",
+ in("eax") pointer,
+ );
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/issue-104510-ice.stderr b/src/test/ui/typeck/issue-104510-ice.stderr
new file mode 100644
index 000000000..ddb510ef0
--- /dev/null
+++ b/src/test/ui/typeck/issue-104510-ice.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `Oops` in this scope
+ --> $DIR/issue-104510-ice.rs:4:21
+ |
+LL | struct W<T: ?Sized>(Oops);
+ | ^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/typeck/issue-104513-ice.rs b/src/test/ui/typeck/issue-104513-ice.rs
new file mode 100644
index 000000000..bcac0fa1e
--- /dev/null
+++ b/src/test/ui/typeck/issue-104513-ice.rs
@@ -0,0 +1,6 @@
+struct S;
+fn f() {
+ let _: S<impl Oops> = S; //~ ERROR cannot find trait `Oops` in this scope
+ //~^ ERROR `impl Trait` only allowed in function and inherent method return types
+}
+fn main() {}
diff --git a/src/test/ui/typeck/issue-104513-ice.stderr b/src/test/ui/typeck/issue-104513-ice.stderr
new file mode 100644
index 000000000..2b3b1b9ef
--- /dev/null
+++ b/src/test/ui/typeck/issue-104513-ice.stderr
@@ -0,0 +1,18 @@
+error[E0405]: cannot find trait `Oops` in this scope
+ --> $DIR/issue-104513-ice.rs:3:19
+ |
+LL | fn f() {
+ | - help: you might be missing a type parameter: `<Oops>`
+LL | let _: S<impl Oops> = S;
+ | ^^^^ not found in this scope
+
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
+ --> $DIR/issue-104513-ice.rs:3:14
+ |
+LL | let _: S<impl Oops> = S;
+ | ^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0405, E0562.
+For more information about an error, try `rustc --explain E0405`.
diff --git a/src/test/ui/issues/issue-10969.rs b/src/test/ui/typeck/issue-10969.rs
index 0b78fc1bb..0b78fc1bb 100644
--- a/src/test/ui/issues/issue-10969.rs
+++ b/src/test/ui/typeck/issue-10969.rs
diff --git a/src/test/ui/issues/issue-10969.stderr b/src/test/ui/typeck/issue-10969.stderr
index f64b61aae..f64b61aae 100644
--- a/src/test/ui/issues/issue-10969.stderr
+++ b/src/test/ui/typeck/issue-10969.stderr
diff --git a/src/test/ui/issues/issue-50687-ice-on-borrow.rs b/src/test/ui/typeck/issue-50687-ice-on-borrow.rs
index 7a8a12c2a..7a8a12c2a 100644
--- a/src/test/ui/issues/issue-50687-ice-on-borrow.rs
+++ b/src/test/ui/typeck/issue-50687-ice-on-borrow.rs
diff --git a/src/test/ui/issues/issue-50687-ice-on-borrow.stderr b/src/test/ui/typeck/issue-50687-ice-on-borrow.stderr
index e6a0edac4..e6a0edac4 100644
--- a/src/test/ui/issues/issue-50687-ice-on-borrow.stderr
+++ b/src/test/ui/typeck/issue-50687-ice-on-borrow.stderr
diff --git a/src/test/ui/typeck/issue-81293.stderr b/src/test/ui/typeck/issue-81293.stderr
index 9658288ac..6976be711 100644
--- a/src/test/ui/typeck/issue-81293.stderr
+++ b/src/test/ui/typeck/issue-81293.stderr
@@ -21,15 +21,10 @@ LL | a = c + b * 5;
|
= help: the trait `Add<u16>` is not implemented for `usize`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
- <&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&'a usize as Add<usize>>
+ <&usize as Add<&usize>>
+ <usize as Add<&usize>>
+ <usize as Add>
error: aborting due to 3 previous errors
diff --git a/src/test/ui/typeck/issue-83693.stderr b/src/test/ui/typeck/issue-83693.stderr
index 0d8bbf1ce..1e45c2d35 100644
--- a/src/test/ui/typeck/issue-83693.stderr
+++ b/src/test/ui/typeck/issue-83693.stderr
@@ -6,8 +6,8 @@ LL | impl F {
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
-LL | pub trait Fn<Args>: FnMut<Args> {
- | ------------------------------- similarly named trait `Fn` defined here
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | -------------------------------------- similarly named trait `Fn` defined here
error[E0412]: cannot find type `TestResult` in this scope
--> $DIR/issue-83693.rs:9:22
diff --git a/src/test/ui/typeck/issue-91267.rs b/src/test/ui/typeck/issue-91267.rs
index f5a37e9cb..4e39cfab5 100644
--- a/src/test/ui/typeck/issue-91267.rs
+++ b/src/test/ui/typeck/issue-91267.rs
@@ -1,5 +1,7 @@
+#![feature(type_ascription)]
+
fn main() {
- 0: u8<e<5>=e>
+ type_ascribe!(0, u8<e<5>=e>)
//~^ ERROR: cannot find type `e` in this scope [E0412]
//~| ERROR: associated type bindings are not allowed here [E0229]
//~| ERROR: mismatched types [E0308]
diff --git a/src/test/ui/typeck/issue-91267.stderr b/src/test/ui/typeck/issue-91267.stderr
index aac00b9b6..72acd9c67 100644
--- a/src/test/ui/typeck/issue-91267.stderr
+++ b/src/test/ui/typeck/issue-91267.stderr
@@ -1,25 +1,22 @@
error[E0412]: cannot find type `e` in this scope
- --> $DIR/issue-91267.rs:2:16
+ --> $DIR/issue-91267.rs:4:30
|
-LL | 0: u8<e<5>=e>
- | ^
- | |
- | not found in this scope
- | help: maybe you meant to write an assignment here: `let e`
+LL | type_ascribe!(0, u8<e<5>=e>)
+ | ^ not found in this scope
error[E0229]: associated type bindings are not allowed here
- --> $DIR/issue-91267.rs:2:11
+ --> $DIR/issue-91267.rs:4:25
|
-LL | 0: u8<e<5>=e>
- | ^^^^^^ associated type not allowed here
+LL | type_ascribe!(0, u8<e<5>=e>)
+ | ^^^^^^ associated type not allowed here
error[E0308]: mismatched types
- --> $DIR/issue-91267.rs:2:5
+ --> $DIR/issue-91267.rs:4:5
|
LL | fn main() {
| - expected `()` because of default return type
-LL | 0: u8<e<5>=e>
- | ^^^^^^^^^^^^^ expected `()`, found `u8`
+LL | type_ascribe!(0, u8<e<5>=e>)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `u8`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.rs b/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.rs
new file mode 100644
index 000000000..fb56b3944
--- /dev/null
+++ b/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let page_size = page_size::get();
+ //~^ ERROR failed to resolve: use of undeclared crate or module `page_size`
+}
diff --git a/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.stderr b/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.stderr
new file mode 100644
index 000000000..b01e30be5
--- /dev/null
+++ b/src/test/ui/typeck/path-to-method-sugg-unresolved-expr.stderr
@@ -0,0 +1,9 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `page_size`
+ --> $DIR/path-to-method-sugg-unresolved-expr.rs:2:21
+ |
+LL | let page_size = page_size::get();
+ | ^^^^^^^^^ use of undeclared crate or module `page_size`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/issues/issue-29184.rs b/src/test/ui/typeof/issue-29184.rs
index c77e364c3..c77e364c3 100644
--- a/src/test/ui/issues/issue-29184.rs
+++ b/src/test/ui/typeof/issue-29184.rs
diff --git a/src/test/ui/issues/issue-29184.stderr b/src/test/ui/typeof/issue-29184.stderr
index 75b6c64f2..75b6c64f2 100644
--- a/src/test/ui/issues/issue-29184.stderr
+++ b/src/test/ui/typeof/issue-29184.stderr
diff --git a/src/test/ui/issues/issue-42060.rs b/src/test/ui/typeof/issue-42060.rs
index 1740b2383..1740b2383 100644
--- a/src/test/ui/issues/issue-42060.rs
+++ b/src/test/ui/typeof/issue-42060.rs
diff --git a/src/test/ui/issues/issue-42060.stderr b/src/test/ui/typeof/issue-42060.stderr
index effcbe4d7..effcbe4d7 100644
--- a/src/test/ui/issues/issue-42060.stderr
+++ b/src/test/ui/typeof/issue-42060.stderr
diff --git a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr
index eaab6ff3d..ed56e1cf9 100644
--- a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr
+++ b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr
@@ -8,15 +8,10 @@ LL | <i32 as Add<u32>>::add(1, 2);
|
= help: the trait `Add<u32>` is not implemented for `i32`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
<&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&i32 as Add<&i32>>
+ <i32 as Add<&i32>>
+ <i32 as Add>
error[E0308]: mismatched types
--> $DIR/ufcs-qpath-self-mismatch.rs:7:28
@@ -62,15 +57,10 @@ LL | <i32 as Add<u32>>::add(1, 2);
|
= help: the trait `Add<u32>` is not implemented for `i32`
= help: the following other types implement trait `Add<Rhs>`:
- <&'a f32 as Add<f32>>
- <&'a f64 as Add<f64>>
- <&'a i128 as Add<i128>>
- <&'a i16 as Add<i16>>
<&'a i32 as Add<i32>>
- <&'a i64 as Add<i64>>
- <&'a i8 as Add<i8>>
- <&'a isize as Add<isize>>
- and 48 others
+ <&i32 as Add<&i32>>
+ <i32 as Add<&i32>>
+ <i32 as Add>
error: aborting due to 4 previous errors
diff --git a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs
index 925463d6d..d2e486002 100644
--- a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs
+++ b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.rs
@@ -1,8 +1,8 @@
#![feature(unboxed_closures)]
fn a<F: Fn<usize>>(f: F) {}
+//~^ ERROR type parameter to bare `Fn` trait must be a tuple
fn main() {
a(|_: usize| {});
- //~^ ERROR mismatched types
}
diff --git a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
index 9a24fb8c2..1c18eb0fc 100644
--- a/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
+++ b/src/test/ui/unboxed-closures/non-tupled-arg-mismatch.stderr
@@ -1,17 +1,15 @@
-error[E0308]: mismatched types
- --> $DIR/non-tupled-arg-mismatch.rs:6:5
- |
-LL | a(|_: usize| {});
- | ^ types differ
- |
- = note: expected trait `Fn<usize>`
- found trait `Fn<(usize,)>`
-note: required by a bound in `a`
+error[E0059]: type parameter to bare `Fn` trait must be a tuple
--> $DIR/non-tupled-arg-mismatch.rs:3:9
|
LL | fn a<F: Fn<usize>>(f: F) {}
- | ^^^^^^^^^ required by this bound in `a`
+ | ^^^^^^^^^ the trait `Tuple` is not implemented for `usize`
+ |
+note: required by a bound in `Fn`
+ --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+ |
+LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
+ | ^^^^^ required by this bound in `Fn`
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0059`.
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.rs b/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.rs
index ed8d72114..7377359b6 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.rs
+++ b/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.rs
@@ -1,12 +1,12 @@
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, tuple_trait)]
// Tests that we can't move out of an unboxed closure environment
// if the upvar is captured by ref or the closure takes self by
// reference.
-fn to_fn<A,F:Fn<A>>(f: F) -> F { f }
-fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
-fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
+fn to_fn<A:std::marker::Tuple,F:Fn<A>>(f: F) -> F { f }
+fn to_fn_mut<A:std::marker::Tuple,F:FnMut<A>>(f: F) -> F { f }
+fn to_fn_once<A:std::marker::Tuple,F:FnOnce<A>>(f: F) -> F { f }
fn main() {
// By-ref cases
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs
index 57e6d3065..c57312b43 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs
+++ b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs
@@ -2,12 +2,12 @@
// as `mut` through a closure. Also test that we CAN mutate a moved copy,
// unless this is a `Fn` closure. Issue #16749.
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, tuple_trait)]
use std::mem;
-fn to_fn<A,F:Fn<A>>(f: F) -> F { f }
-fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
+fn to_fn<A:std::marker::Tuple,F:Fn<A>>(f: F) -> F { f }
+fn to_fn_mut<A:std::marker::Tuple,F:FnMut<A>>(f: F) -> F { f }
fn a() {
let n = 0;
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr
index d6e74b5b8..26f97b519 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr
@@ -28,8 +28,8 @@ LL | n += 1;
error[E0594]: cannot assign to `n`, as it is a captured variable in a `Fn` closure
--> $DIR/unboxed-closures-mutate-upvar.rs:53:9
|
-LL | fn to_fn<A,F:Fn<A>>(f: F) -> F { f }
- | - change this to accept `FnMut` instead of `Fn`
+LL | fn to_fn<A:std::marker::Tuple,F:Fn<A>>(f: F) -> F { f }
+ | - change this to accept `FnMut` instead of `Fn`
...
LL | let mut f = to_fn(move || {
| ----- ------- in this closure
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs
index 0e727b11c..7289d9322 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs
+++ b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs
@@ -1,6 +1,6 @@
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, tuple_trait)]
-fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
+fn to_fn_mut<A:std::marker::Tuple,F:FnMut<A>>(f: F) -> F { f }
fn main() {
let mut_ = to_fn_mut(|x| x);
diff --git a/src/test/ui/underscore-ident-matcher.stderr b/src/test/ui/underscore-ident-matcher.stderr
index 241c3d3d8..b0e4d88f6 100644
--- a/src/test/ui/underscore-ident-matcher.stderr
+++ b/src/test/ui/underscore-ident-matcher.stderr
@@ -6,6 +6,12 @@ LL | macro_rules! identity {
...
LL | let identity!(_) = 10;
| ^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$i:ident`
+ --> $DIR/underscore-ident-matcher.rs:2:6
+ |
+LL | ($i: ident) => (
+ | ^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/union/union-move.mirunsafeck.stderr b/src/test/ui/union/union-move.mirunsafeck.stderr
index 53050cf53..6381ae874 100644
--- a/src/test/ui/union/union-move.mirunsafeck.stderr
+++ b/src/test/ui/union/union-move.mirunsafeck.stderr
@@ -8,6 +8,14 @@ LL | move_out(x.f1_nocopy);
| ----------- value moved here
LL | move_out(x.f2_nocopy);
| ^^^^^^^^^^^ value used here after move
+ |
+note: consider changing this parameter type in function `move_out` to borrow instead if owning the value isn't necessary
+ --> $DIR/union-move.rs:10:19
+ |
+LL | fn move_out<T>(x: T) {}
+ | -------- ^ this parameter takes ownership of the value
+ | |
+ | in this function
error[E0382]: use of moved value: `x`
--> $DIR/union-move.rs:45:18
@@ -19,6 +27,14 @@ LL | move_out(x.f2_nocopy);
| ----------- value moved here
LL | move_out(x.f3_copy);
| ^^^^^^^^^ value used here after move
+ |
+note: consider changing this parameter type in function `move_out` to borrow instead if owning the value isn't necessary
+ --> $DIR/union-move.rs:10:19
+ |
+LL | fn move_out<T>(x: T) {}
+ | -------- ^ this parameter takes ownership of the value
+ | |
+ | in this function
error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait
--> $DIR/union-move.rs:52:18
diff --git a/src/test/ui/union/union-move.thirunsafeck.stderr b/src/test/ui/union/union-move.thirunsafeck.stderr
index 53050cf53..6381ae874 100644
--- a/src/test/ui/union/union-move.thirunsafeck.stderr
+++ b/src/test/ui/union/union-move.thirunsafeck.stderr
@@ -8,6 +8,14 @@ LL | move_out(x.f1_nocopy);
| ----------- value moved here
LL | move_out(x.f2_nocopy);
| ^^^^^^^^^^^ value used here after move
+ |
+note: consider changing this parameter type in function `move_out` to borrow instead if owning the value isn't necessary
+ --> $DIR/union-move.rs:10:19
+ |
+LL | fn move_out<T>(x: T) {}
+ | -------- ^ this parameter takes ownership of the value
+ | |
+ | in this function
error[E0382]: use of moved value: `x`
--> $DIR/union-move.rs:45:18
@@ -19,6 +27,14 @@ LL | move_out(x.f2_nocopy);
| ----------- value moved here
LL | move_out(x.f3_copy);
| ^^^^^^^^^ value used here after move
+ |
+note: consider changing this parameter type in function `move_out` to borrow instead if owning the value isn't necessary
+ --> $DIR/union-move.rs:10:19
+ |
+LL | fn move_out<T>(x: T) {}
+ | -------- ^ this parameter takes ownership of the value
+ | |
+ | in this function
error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait
--> $DIR/union-move.rs:52:18
diff --git a/src/test/ui/unop-move-semantics.stderr b/src/test/ui/unop-move-semantics.stderr
index 65d866c71..d52a92b88 100644
--- a/src/test/ui/unop-move-semantics.stderr
+++ b/src/test/ui/unop-move-semantics.stderr
@@ -14,6 +14,10 @@ note: calling this operator moves the left-hand side
|
LL | fn not(self) -> Self::Output;
| ^^^^
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | !x.clone();
+ | ++++++++
help: consider further restricting this bound
|
LL | fn move_then_borrow<T: Not<Output=T> + Clone + Copy>(x: T) {
diff --git a/src/test/ui/unsafe/unsafe-not-inherited.rs b/src/test/ui/unsafe/unsafe-not-inherited.rs
new file mode 100644
index 000000000..6d797caa0
--- /dev/null
+++ b/src/test/ui/unsafe/unsafe-not-inherited.rs
@@ -0,0 +1,26 @@
+#![allow(unused, dead_code)]
+
+static mut FOO: u64 = 0;
+
+fn static_mod() {
+ unsafe {static BAR: u64 = FOO;}
+ //~^ ERROR: use of mutable static is unsafe
+ //~| NOTE: use of mutable static
+ //~| NOTE: mutable statics can be mutated by multiple threads
+ //~| NOTE: items do not inherit unsafety
+}
+
+unsafe fn unsafe_call() {}
+fn foo() {
+ unsafe {
+ //~^ NOTE: items do not inherit unsafety
+ fn bar() {
+ unsafe_call();
+ //~^ ERROR: call to unsafe function
+ //~| NOTE: call to unsafe function
+ //~| NOTE: consult the function's documentation
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/unsafe/unsafe-not-inherited.stderr b/src/test/ui/unsafe/unsafe-not-inherited.stderr
new file mode 100644
index 000000000..3bc5ca5c9
--- /dev/null
+++ b/src/test/ui/unsafe/unsafe-not-inherited.stderr
@@ -0,0 +1,24 @@
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-not-inherited.rs:6:31
+ |
+LL | unsafe {static BAR: u64 = FOO;}
+ | ------ ^^^ use of mutable static
+ | |
+ | items do not inherit unsafety from separate enclosing items
+ |
+ = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-not-inherited.rs:18:13
+ |
+LL | unsafe {
+ | ------ items do not inherit unsafety from separate enclosing items
+...
+LL | unsafe_call();
+ | ^^^^^^^^^^^^^ call to unsafe function
+ |
+ = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsized-locals/borrow-after-move.stderr b/src/test/ui/unsized-locals/borrow-after-move.stderr
index 28ae1c068..d8bffd4f9 100644
--- a/src/test/ui/unsized-locals/borrow-after-move.stderr
+++ b/src/test/ui/unsized-locals/borrow-after-move.stderr
@@ -28,6 +28,14 @@ LL | drop_unsized(y);
...
LL | println!("{}", &y);
| ^^ value borrowed here after move
+ |
+note: consider changing this parameter type in function `drop_unsized` to borrow instead if owning the value isn't necessary
+ --> $DIR/borrow-after-move.rs:14:31
+ |
+LL | fn drop_unsized<T: ?Sized>(_: T) {}
+ | ------------ ^ this parameter takes ownership of the value
+ | |
+ | in this function
error[E0382]: borrow of moved value: `x`
--> $DIR/borrow-after-move.rs:31:24
@@ -66,6 +74,11 @@ LL | x.foo();
| - value moved here
LL | println!("{}", &x);
| ^^ value borrowed here after move
+ |
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | x.clone().foo();
+ | ++++++++
error: aborting due to 5 previous errors; 1 warning emitted
diff --git a/src/test/ui/unsized-locals/double-move.stderr b/src/test/ui/unsized-locals/double-move.stderr
index dfae6cc75..715348181 100644
--- a/src/test/ui/unsized-locals/double-move.stderr
+++ b/src/test/ui/unsized-locals/double-move.stderr
@@ -16,6 +16,14 @@ LL | drop_unsized(y);
| - value moved here
LL | drop_unsized(y);
| ^ value used here after move
+ |
+note: consider changing this parameter type in function `drop_unsized` to borrow instead if owning the value isn't necessary
+ --> $DIR/double-move.rs:14:31
+ |
+LL | fn drop_unsized<T: ?Sized>(_: T) {}
+ | ------------ ^ this parameter takes ownership of the value
+ | |
+ | in this function
error[E0382]: use of moved value: `x`
--> $DIR/double-move.rs:27:22
diff --git a/src/test/ui/use/use-after-move-based-on-type.stderr b/src/test/ui/use/use-after-move-based-on-type.stderr
index 445f14d65..7b4d24549 100644
--- a/src/test/ui/use/use-after-move-based-on-type.stderr
+++ b/src/test/ui/use/use-after-move-based-on-type.stderr
@@ -9,6 +9,10 @@ LL | println!("{}", x);
| ^ value borrowed here after move
|
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider cloning the value if the performance cost is acceptable
+ |
+LL | let _y = x.clone();
+ | ++++++++
error: aborting due to previous error
diff --git a/src/test/ui/use/use-after-move-implicity-coerced-object.stderr b/src/test/ui/use/use-after-move-implicity-coerced-object.stderr
index 26804216d..dfa0c0483 100644
--- a/src/test/ui/use/use-after-move-implicity-coerced-object.stderr
+++ b/src/test/ui/use/use-after-move-implicity-coerced-object.stderr
@@ -9,6 +9,14 @@ LL | l.push(n);
LL |
LL | let x = n.to_string();
| ^^^^^^^^^^^^^ value borrowed here after move
+ |
+note: consider changing this parameter type in method `push` to borrow instead if owning the value isn't necessary
+ --> $DIR/use-after-move-implicity-coerced-object.rs:17:27
+ |
+LL | fn push(&mut self, n: Box<dyn ToString + 'static>) {
+ | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this parameter takes ownership of the value
+ | |
+ | in this method
error: aborting due to previous error
diff --git a/src/test/ui/use/use-crate-self.rs b/src/test/ui/use/use-crate-self.rs
new file mode 100644
index 000000000..65ab94814
--- /dev/null
+++ b/src/test/ui/use/use-crate-self.rs
@@ -0,0 +1,4 @@
+use crate::{self};
+ //~^ ERROR crate root imports need to be explicitly named: `use crate as name;`
+
+fn main() {}
diff --git a/src/test/ui/use/use-crate-self.stderr b/src/test/ui/use/use-crate-self.stderr
new file mode 100644
index 000000000..dd4036bff
--- /dev/null
+++ b/src/test/ui/use/use-crate-self.stderr
@@ -0,0 +1,8 @@
+error: crate root imports need to be explicitly named: `use crate as name;`
+ --> $DIR/use-crate-self.rs:1:13
+ |
+LL | use crate::{self};
+ | ^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/weird-exprs.rs b/src/test/ui/weird-exprs.rs
index 4066bcf3b..d65703ef5 100644
--- a/src/test/ui/weird-exprs.rs
+++ b/src/test/ui/weird-exprs.rs
@@ -8,6 +8,7 @@
#![allow(unreachable_code)]
#![allow(unused_braces, unused_must_use, unused_parens)]
#![allow(uncommon_codepoints, confusable_idents)]
+#![allow(unreachable_patterns)]
#![recursion_limit = "256"]
@@ -194,6 +195,15 @@ fn bathroom_stall() {
assert_eq!(i, 13);
}
+fn closure_matching() {
+ let x = |_| Some(1);
+ let (|x| x) = match x(..) {
+ |_| Some(2) => |_| Some(3),
+ |_| _ => unreachable!(),
+ };
+ assert!(matches!(x(..), |_| Some(4)));
+}
+
pub fn main() {
strange();
funny();
@@ -216,4 +226,5 @@ pub fn main() {
ðšŒðš˜ðš—ðšðš’ðš—ðšžðšŽ();
function();
bathroom_stall();
+ closure_matching();
}
diff --git a/src/test/ui/where-clauses/higher-ranked-fn-type.rs b/src/test/ui/where-clauses/higher-ranked-fn-type.rs
index ab6edde4e..c19e75eb7 100644
--- a/src/test/ui/where-clauses/higher-ranked-fn-type.rs
+++ b/src/test/ui/where-clauses/higher-ranked-fn-type.rs
@@ -19,7 +19,7 @@ where
{
called()
//[quiet]~^ ERROR the trait bound `for<'b> fn(&'b ()): Foo` is not satisfied
- //[verbose]~^^ ERROR the trait bound `for<'b> fn(&ReLateBound(
+ //[verbose]~^^ ERROR the trait bound `for<Region(
}
fn main() {}
diff --git a/src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr b/src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
index 24660ec35..268cef6e2 100644
--- a/src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
+++ b/src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `for<'b> fn(&ReLateBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[1209]::called::'b), 'b) }) ()): Foo` is not satisfied
+error[E0277]: the trait bound `for<Region(BrNamed(DefId(0:6 ~ higher_ranked_fn_type[1209]::called::'b), 'b))> fn(&ReLateBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[1209]::called::'b), 'b) }) ()): Foo` is not satisfied
--> $DIR/higher-ranked-fn-type.rs:20:5
|
LL | called()
- | ^^^^^^ the trait `for<'b> Foo` is not implemented for `fn(&ReLateBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[1209]::called::'b), 'b) }) ())`
+ | ^^^^^^ the trait `for<Region(BrNamed(DefId(0:6 ~ higher_ranked_fn_type[1209]::called::'b), 'b))> Foo` is not implemented for `fn(&ReLateBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[1209]::called::'b), 'b) }) ())`
|
note: required by a bound in `called`
--> $DIR/higher-ranked-fn-type.rs:12:25
diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md
index 44c96f31d..9d30c5541 100644
--- a/src/tools/build-manifest/README.md
+++ b/src/tools/build-manifest/README.md
@@ -1,7 +1,16 @@
# build-manifest
-This tool generates the manifests uploaded to static.rust-lang.org and used by
-rustup. The tool is invoked by the bootstrap tool.
+This tool generates the manifests uploaded to static.rust-lang.org and used by rustup.
+You can see a full list of all manifests at <https://static.rust-lang.org/manifests.txt>.
+This listing is updated by <https://github.com/rust-lang/generate-manifest-list> every 7 days.
+
+This gets called by `promote-release` <https://github.com/rust-lang/promote-release> via `x.py dist hash-and-sign`.
+
+## Adding a new component
+
+1. Add a new `Step` to `dist.rs`. This should usually be named after the filename of the uploaded tarball. See https://github.com/rust-lang/rust/pull/101799/files#diff-2c56335faa24486df09ba392d8900c57e2fac4633e1f7038469bcf9ed3feb871 for an example.
+ a. If appropriate, call `tarball.is_preview(true)` for the component.
+2. Add a new `PkgType` to build-manifest. Fix all the compile errors as appropriate.
## Testing changes locally
@@ -9,19 +18,16 @@ In order to test the changes locally you need to have a valid dist directory
available locally. If you don't want to build all the compiler, you can easily
create one from the nightly artifacts with:
-```
-#!/bin/bash
-for cmpn in rust rustc rust-std rust-docs cargo; do
- wget https://static.rust-lang.org/dist/${cmpn}-nightly-x86_64-unknown-linux-gnu.tar.gz
+```sh
+for component in rust rustc rust-std rust-docs cargo; do
+ wget -P build/dist https://static.rust-lang.org/dist/${component}-nightly-x86_64-unknown-linux-gnu.tar.gz
done
```
-Then, you can generate the manifest and all the packages from `path/to/dist` to
-`path/to/output` with:
+Then, you can generate the manifest and all the packages from `build/dist` to
+`build/manifest` with:
+```sh
+mkdir -p build/manifest
+cargo +nightly run --release -p build-manifest build/dist build/manifest 1970-01-01 http://example.com nightly
```
-$ cargo +nightly run path/to/dist path/to/output 1970-01-01 http://example.com CHANNEL
-```
-
-Remember to replace `CHANNEL` with the channel you produced dist artifacts of
-and `VERSION` with the current Rust version.
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index b0006cb90..0551e835b 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -1,8 +1,4 @@
-//! Build a dist manifest, hash and sign everything.
-//! This gets called by `promote-release`
-//! (https://github.com/rust-lang/rust-central-station/tree/master/promote-release)
-//! via `x.py dist hash-and-sign`; the cmdline arguments are set up
-//! by rustbuild (in `src/bootstrap/dist.rs`).
+#![doc = include_str!("../README.md")]
mod checksum;
mod manifest;
@@ -64,6 +60,7 @@ static TARGETS: &[&str] = &[
"aarch64-unknown-none",
"aarch64-unknown-none-softfloat",
"aarch64-unknown-redox",
+ "aarch64-unknown-uefi",
"arm-linux-androideabi",
"arm-unknown-linux-gnueabi",
"arm-unknown-linux-gnueabihf",
@@ -99,6 +96,7 @@ static TARGETS: &[&str] = &[
"i686-unknown-freebsd",
"i686-unknown-linux-gnu",
"i686-unknown-linux-musl",
+ "i686-unknown-uefi",
"m68k-unknown-linux-gnu",
"mips-unknown-linux-gnu",
"mips-unknown-linux-musl",
@@ -155,6 +153,7 @@ static TARGETS: &[&str] = &[
"x86_64-unknown-none",
"x86_64-unknown-redox",
"x86_64-unknown-hermit",
+ "x86_64-unknown-uefi",
];
/// This allows the manifest to contain rust-docs for hosts that don't build
@@ -184,7 +183,7 @@ static PKG_INSTALLERS: &[&str] = &["x86_64-apple-darwin", "aarch64-apple-darwin"
static MINGW: &[&str] = &["i686-pc-windows-gnu", "x86_64-pc-windows-gnu"];
-static NIGHTLY_ONLY_COMPONENTS: &[&str] = &["miri-preview", "rust-docs-json-preview"];
+static NIGHTLY_ONLY_COMPONENTS: &[PkgType] = &[PkgType::Miri, PkgType::JsonDocs];
macro_rules! t {
($e:expr) => {
@@ -287,28 +286,9 @@ impl Builder {
}
fn add_packages_to(&mut self, manifest: &mut Manifest) {
- macro_rules! package {
- ($name:expr, $targets:expr) => {
- self.package($name, &mut manifest.pkg, $targets, &[])
- };
+ for pkg in PkgType::all() {
+ self.package(pkg, &mut manifest.pkg);
}
- package!("rustc", HOSTS);
- package!("rustc-dev", HOSTS);
- package!("reproducible-artifacts", HOSTS);
- package!("rustc-docs", HOSTS);
- package!("cargo", HOSTS);
- package!("rust-mingw", MINGW);
- package!("rust-std", TARGETS);
- self.package("rust-docs", &mut manifest.pkg, HOSTS, DOCS_FALLBACK);
- self.package("rust-docs-json-preview", &mut manifest.pkg, HOSTS, DOCS_FALLBACK);
- package!("rust-src", &["*"]);
- package!("rls-preview", HOSTS);
- package!("rust-analyzer-preview", HOSTS);
- package!("clippy-preview", HOSTS);
- package!("miri-preview", HOSTS);
- package!("rustfmt-preview", HOSTS);
- package!("rust-analysis", TARGETS);
- package!("llvm-tools-preview", TARGETS);
}
fn add_artifacts_to(&mut self, manifest: &mut Manifest) {
@@ -333,44 +313,28 @@ impl Builder {
}
fn add_profiles_to(&mut self, manifest: &mut Manifest) {
- let mut profile = |name, pkgs| self.profile(name, &mut manifest.profiles, pkgs);
- profile("minimal", &["rustc", "cargo", "rust-std", "rust-mingw"]);
- profile(
- "default",
- &[
- "rustc",
- "cargo",
- "rust-std",
- "rust-mingw",
- "rust-docs",
- "rustfmt-preview",
- "clippy-preview",
- ],
- );
- profile(
- "complete",
- &[
- "rustc",
- "cargo",
- "rust-std",
- "rust-mingw",
- "rust-docs",
- "rustfmt-preview",
- "clippy-preview",
- "rls-preview",
- "rust-analyzer-preview",
- "rust-src",
- "llvm-tools-preview",
- "rust-analysis",
- "miri-preview",
- ],
- );
+ use PkgType::*;
+
+ let mut profile = |name, pkgs: &_| self.profile(name, &mut manifest.profiles, pkgs);
+
+ // Use a Vec here to make sure we don't exclude any components in an earlier profile.
+ let minimal = vec![Rustc, Cargo, RustStd, RustMingw];
+ profile("minimal", &minimal);
+
+ let mut default = minimal;
+ default.extend([HtmlDocs, Rustfmt, Clippy]);
+ profile("default", &default);
+
+ // NOTE: this profile is effectively deprecated; do not add new components to it.
+ let mut complete = default;
+ complete.extend([Rls, RustAnalyzer, RustSrc, LlvmTools, RustAnalysis, Miri]);
+ profile("complete", &complete);
// The compiler libraries are not stable for end users, and they're also huge, so we only
// `rustc-dev` for nightly users, and only in the "complete" profile. It's still possible
// for users to install the additional component manually, if needed.
if self.versions.channel() == "nightly" {
- self.extend_profile("complete", &mut manifest.profiles, &["rustc-dev"]);
+ self.extend_profile("complete", &mut manifest.profiles, &[RustcDev]);
// Do not include the rustc-docs component for now, as it causes
// conflicts with the rust-docs component when installed. See
// #75833.
@@ -382,12 +346,11 @@ impl Builder {
let mut rename = |from: &str, to: &str| {
manifest.renames.insert(from.to_owned(), Rename { to: to.to_owned() })
};
- rename("rls", "rls-preview");
- rename("rustfmt", "rustfmt-preview");
- rename("clippy", "clippy-preview");
- rename("miri", "miri-preview");
- rename("rust-docs-json", "rust-docs-json-preview");
- rename("rust-analyzer", "rust-analyzer-preview");
+ for pkg in PkgType::all() {
+ if pkg.is_preview() {
+ rename(pkg.tarball_component_name(), &pkg.manifest_component_name());
+ }
+ }
}
fn rust_package(&mut self, manifest: &Manifest) -> Package {
@@ -419,42 +382,52 @@ impl Builder {
let mut components = Vec::new();
let mut extensions = Vec::new();
- let host_component = |pkg| Component::from_str(pkg, host);
-
- // rustc/rust-std/cargo/docs are all required,
- // and so is rust-mingw if it's available for the target.
- components.extend(vec![
- host_component("rustc"),
- host_component("rust-std"),
- host_component("cargo"),
- host_component("rust-docs"),
- ]);
- if host.contains("pc-windows-gnu") {
- components.push(host_component("rust-mingw"));
- }
+ let host_component = |pkg: &_| Component::from_pkg(pkg, host);
- // Tools are always present in the manifest,
- // but might be marked as unavailable if they weren't built.
- extensions.extend(vec![
- host_component("clippy-preview"),
- host_component("miri-preview"),
- host_component("rls-preview"),
- host_component("rust-analyzer-preview"),
- host_component("rustfmt-preview"),
- host_component("llvm-tools-preview"),
- host_component("rust-analysis"),
- host_component("rust-docs-json-preview"),
- ]);
-
- extensions.extend(
- TARGETS
- .iter()
- .filter(|&&target| target != host)
- .map(|target| Component::from_str("rust-std", target)),
- );
- extensions.extend(HOSTS.iter().map(|target| Component::from_str("rustc-dev", target)));
- extensions.extend(HOSTS.iter().map(|target| Component::from_str("rustc-docs", target)));
- extensions.push(Component::from_str("rust-src", "*"));
+ for pkg in PkgType::all() {
+ match pkg {
+ // rustc/rust-std/cargo/docs are all required
+ PkgType::Rustc | PkgType::Cargo | PkgType::HtmlDocs => {
+ components.push(host_component(pkg));
+ }
+ PkgType::RustStd => {
+ components.push(host_component(pkg));
+ extensions.extend(
+ TARGETS
+ .iter()
+ .filter(|&&target| target != host)
+ .map(|target| Component::from_pkg(pkg, target)),
+ );
+ }
+ // so is rust-mingw if it's available for the target
+ PkgType::RustMingw => {
+ if host.contains("pc-windows-gnu") {
+ components.push(host_component(pkg));
+ }
+ }
+ // Tools are always present in the manifest,
+ // but might be marked as unavailable if they weren't built.
+ PkgType::Clippy
+ | PkgType::Miri
+ | PkgType::Rls
+ | PkgType::RustAnalyzer
+ | PkgType::Rustfmt
+ | PkgType::LlvmTools
+ | PkgType::RustAnalysis
+ | PkgType::JsonDocs => {
+ extensions.push(host_component(pkg));
+ }
+ PkgType::RustcDev | PkgType::RustcDocs => {
+ extensions.extend(HOSTS.iter().map(|target| Component::from_pkg(pkg, target)));
+ }
+ PkgType::RustSrc => {
+ extensions.push(Component::from_pkg(pkg, "*"));
+ }
+ PkgType::Rust => {}
+ // NOTE: this is intentional, these artifacts aren't intended to be used with rustup
+ PkgType::ReproducibleArtifacts => {}
+ }
+ }
// If the components/extensions don't actually exist for this
// particular host/target combination then nix it entirely from our
@@ -481,43 +454,44 @@ impl Builder {
&mut self,
profile_name: &str,
dst: &mut BTreeMap<String, Vec<String>>,
- pkgs: &[&str],
+ pkgs: &[PkgType],
) {
- dst.insert(profile_name.to_owned(), pkgs.iter().map(|s| (*s).to_owned()).collect());
+ dst.insert(
+ profile_name.to_owned(),
+ pkgs.iter().map(|s| s.manifest_component_name()).collect(),
+ );
}
fn extend_profile(
&mut self,
profile_name: &str,
dst: &mut BTreeMap<String, Vec<String>>,
- pkgs: &[&str],
+ pkgs: &[PkgType],
) {
dst.get_mut(profile_name)
.expect("existing profile")
- .extend(pkgs.iter().map(|s| (*s).to_owned()));
+ .extend(pkgs.iter().map(|s| s.manifest_component_name()));
}
- fn package(
- &mut self,
- pkgname: &str,
- dst: &mut BTreeMap<String, Package>,
- targets: &[&str],
- fallback: &[(&str, &str)],
- ) {
- let version_info = self
- .versions
- .version(&PkgType::from_component(pkgname))
- .expect("failed to load package version");
+ fn package(&mut self, pkg: &PkgType, dst: &mut BTreeMap<String, Package>) {
+ if *pkg == PkgType::Rust {
+ // This is handled specially by `rust_package` later.
+ // Order is important, so don't call `rust_package` here.
+ return;
+ }
+
+ let fallback = if pkg.use_docs_fallback() { DOCS_FALLBACK } else { &[] };
+ let version_info = self.versions.version(&pkg).expect("failed to load package version");
let mut is_present = version_info.present;
// Never ship nightly-only components for other trains.
- if self.versions.channel() != "nightly" && NIGHTLY_ONLY_COMPONENTS.contains(&pkgname) {
+ if self.versions.channel() != "nightly" && NIGHTLY_ONLY_COMPONENTS.contains(&pkg) {
is_present = false; // Pretend the component is entirely missing.
}
macro_rules! tarball_name {
($target_name:expr) => {
- self.versions.tarball_name(&PkgType::from_component(pkgname), $target_name).unwrap()
+ self.versions.tarball_name(pkg, $target_name).unwrap()
};
}
let mut target_from_compressed_tar = |target_name| {
@@ -546,7 +520,8 @@ impl Builder {
Target::unavailable()
};
- let targets = targets
+ let targets = pkg
+ .targets()
.iter()
.map(|name| {
let target = if is_present {
@@ -561,7 +536,7 @@ impl Builder {
.collect();
dst.insert(
- pkgname.to_string(),
+ pkg.manifest_component_name(),
Package {
version: version_info.version.unwrap_or_default(),
git_commit_hash: version_info.git_commit,
diff --git a/src/tools/build-manifest/src/manifest.rs b/src/tools/build-manifest/src/manifest.rs
index 547c270d8..a9f19d8e5 100644
--- a/src/tools/build-manifest/src/manifest.rs
+++ b/src/tools/build-manifest/src/manifest.rs
@@ -1,3 +1,4 @@
+use crate::versions::PkgType;
use crate::Builder;
use serde::{Serialize, Serializer};
use std::collections::BTreeMap;
@@ -116,8 +117,8 @@ pub(crate) struct Component {
}
impl Component {
- pub(crate) fn from_str(pkg: &str, target: &str) -> Self {
- Self { pkg: pkg.to_string(), target: target.to_string() }
+ pub(crate) fn from_pkg(pkg: &PkgType, target: &str) -> Self {
+ Self { pkg: pkg.manifest_component_name(), target: target.to_string() }
}
}
diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs
index 0186194a4..dde9745af 100644
--- a/src/tools/build-manifest/src/versions.rs
+++ b/src/tools/build-manifest/src/versions.rs
@@ -8,55 +8,63 @@ use tar::Archive;
const DEFAULT_TARGET: &str = "x86_64-unknown-linux-gnu";
-#[derive(Debug, Hash, Eq, PartialEq, Clone)]
-pub(crate) enum PkgType {
- Rust,
- RustSrc,
- Rustc,
- Cargo,
- Rls,
- RustAnalyzer,
- Clippy,
- Rustfmt,
- LlvmTools,
- Miri,
- JsonDocs,
- Other(String),
-}
+macro_rules! pkg_type {
+ ( $($variant:ident = $component:literal $(; preview = true $(@$is_preview:tt)? )? ),+ $(,)? ) => {
+ #[derive(Debug, Hash, Eq, PartialEq, Clone)]
+ pub(crate) enum PkgType {
+ $($variant,)+
+ }
-impl PkgType {
- pub(crate) fn from_component(component: &str) -> Self {
- match component {
- "rust" => PkgType::Rust,
- "rust-src" => PkgType::RustSrc,
- "rustc" => PkgType::Rustc,
- "cargo" => PkgType::Cargo,
- "rls" | "rls-preview" => PkgType::Rls,
- "rust-analyzer" | "rust-analyzer-preview" => PkgType::RustAnalyzer,
- "clippy" | "clippy-preview" => PkgType::Clippy,
- "rustfmt" | "rustfmt-preview" => PkgType::Rustfmt,
- "llvm-tools" | "llvm-tools-preview" => PkgType::LlvmTools,
- "miri" | "miri-preview" => PkgType::Miri,
- "rust-docs-json" | "rust-docs-json-preview" => PkgType::JsonDocs,
- other => PkgType::Other(other.into()),
+ impl PkgType {
+ pub(crate) fn is_preview(&self) -> bool {
+ match self {
+ $( $( $($is_preview)? PkgType::$variant => true, )? )+
+ _ => false,
+ }
+ }
+
+ /// First part of the tarball name.
+ pub(crate) fn tarball_component_name(&self) -> &str {
+ match self {
+ $( PkgType::$variant => $component,)+
+ }
+ }
+
+ pub(crate) fn all() -> &'static [PkgType] {
+ &[ $(PkgType::$variant),+ ]
+ }
}
}
+}
- /// First part of the tarball name.
- fn tarball_component_name(&self) -> &str {
- match self {
- PkgType::Rust => "rust",
- PkgType::RustSrc => "rust-src",
- PkgType::Rustc => "rustc",
- PkgType::Cargo => "cargo",
- PkgType::Rls => "rls",
- PkgType::RustAnalyzer => "rust-analyzer",
- PkgType::Clippy => "clippy",
- PkgType::Rustfmt => "rustfmt",
- PkgType::LlvmTools => "llvm-tools",
- PkgType::Miri => "miri",
- PkgType::JsonDocs => "rust-docs-json",
- PkgType::Other(component) => component,
+pkg_type! {
+ Rust = "rust",
+ RustSrc = "rust-src",
+ Rustc = "rustc",
+ RustcDev = "rustc-dev",
+ RustcDocs = "rustc-docs",
+ ReproducibleArtifacts = "reproducible-artifacts",
+ RustMingw = "rust-mingw",
+ RustStd = "rust-std",
+ Cargo = "cargo",
+ HtmlDocs = "rust-docs",
+ RustAnalysis = "rust-analysis",
+ Rls = "rls"; preview = true,
+ RustAnalyzer = "rust-analyzer"; preview = true,
+ Clippy = "clippy"; preview = true,
+ Rustfmt = "rustfmt"; preview = true,
+ LlvmTools = "llvm-tools"; preview = true,
+ Miri = "miri"; preview = true,
+ JsonDocs = "rust-docs-json"; preview = true,
+}
+
+impl PkgType {
+ /// Component name in the manifest. In particular, this includes the `-preview` suffix where appropriate.
+ pub(crate) fn manifest_component_name(&self) -> String {
+ if self.is_preview() {
+ format!("{}-preview", self.tarball_component_name())
+ } else {
+ self.tarball_component_name().to_string()
}
}
@@ -73,10 +81,42 @@ impl PkgType {
PkgType::Miri => false,
PkgType::Rust => true,
+ PkgType::RustStd => true,
PkgType::RustSrc => true,
PkgType::Rustc => true,
PkgType::JsonDocs => true,
- PkgType::Other(_) => true,
+ PkgType::HtmlDocs => true,
+ PkgType::RustcDev => true,
+ PkgType::RustcDocs => true,
+ PkgType::ReproducibleArtifacts => true,
+ PkgType::RustMingw => true,
+ PkgType::RustAnalysis => true,
+ }
+ }
+
+ pub(crate) fn targets(&self) -> &[&str] {
+ use crate::{HOSTS, MINGW, TARGETS};
+ use PkgType::*;
+
+ match self {
+ Rust => HOSTS, // doesn't matter in practice, but return something to avoid panicking
+ Rustc => HOSTS,
+ RustcDev => HOSTS,
+ ReproducibleArtifacts => HOSTS,
+ RustcDocs => HOSTS,
+ Cargo => HOSTS,
+ RustMingw => MINGW,
+ RustStd => TARGETS,
+ HtmlDocs => HOSTS,
+ JsonDocs => HOSTS,
+ RustSrc => &["*"],
+ Rls => HOSTS,
+ RustAnalyzer => HOSTS,
+ Clippy => HOSTS,
+ Miri => HOSTS,
+ Rustfmt => HOSTS,
+ RustAnalysis => TARGETS,
+ LlvmTools => TARGETS,
}
}
@@ -84,6 +124,14 @@ impl PkgType {
fn target_independent(&self) -> bool {
*self == PkgType::RustSrc
}
+
+ /// Whether to package these target-specific docs for another similar target.
+ pub(crate) fn use_docs_fallback(&self) -> bool {
+ match self {
+ PkgType::JsonDocs | PkgType::HtmlDocs => true,
+ _ => false,
+ }
+ }
}
#[derive(Debug, Default, Clone)]
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 2d7bda27e..23912bb3e 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -4,13 +4,157 @@ All notable changes to this project will be documented in this file.
See [Changelog Update](book/src/development/infrastructure/changelog_update.md) if you want to update this
document.
-## Unreleased / In Rust Nightly
+## Unreleased / Beta / In Rust Nightly
-[3c7e7dbc...master](https://github.com/rust-lang/rust-clippy/compare/3c7e7dbc...master)
+[b52fb523...master](https://github.com/rust-lang/rust-clippy/compare/b52fb523...master)
+
+## Rust 1.65
+
+Current stable, released 2022-11-03
+
+[3c7e7dbc...b52fb523](https://github.com/rust-lang/rust-clippy/compare/3c7e7dbc...b52fb523)
+
+### Important Changes
+
+* Clippy now has an `--explain <LINT>` command to show the lint description in the console
+ [#8952](https://github.com/rust-lang/rust-clippy/pull/8952)
+
+### New Lints
+
+* [`unused_peekable`]
+ [#9258](https://github.com/rust-lang/rust-clippy/pull/9258)
+* [`collapsible_str_replace`]
+ [#9269](https://github.com/rust-lang/rust-clippy/pull/9269)
+* [`manual_string_new`]
+ [#9295](https://github.com/rust-lang/rust-clippy/pull/9295)
+* [`iter_on_empty_collections`]
+ [#9187](https://github.com/rust-lang/rust-clippy/pull/9187)
+* [`iter_on_single_items`]
+ [#9187](https://github.com/rust-lang/rust-clippy/pull/9187)
+* [`bool_to_int_with_if`]
+ [#9412](https://github.com/rust-lang/rust-clippy/pull/9412)
+* [`multi_assignments`]
+ [#9379](https://github.com/rust-lang/rust-clippy/pull/9379)
+* [`result_large_err`]
+ [#9373](https://github.com/rust-lang/rust-clippy/pull/9373)
+* [`partialeq_to_none`]
+ [#9288](https://github.com/rust-lang/rust-clippy/pull/9288)
+* [`suspicious_to_owned`]
+ [#8984](https://github.com/rust-lang/rust-clippy/pull/8984)
+* [`cast_slice_from_raw_parts`]
+ [#9247](https://github.com/rust-lang/rust-clippy/pull/9247)
+* [`manual_instant_elapsed`]
+ [#9264](https://github.com/rust-lang/rust-clippy/pull/9264)
+
+### Moves and Deprecations
+
+* Moved [`significant_drop_in_scrutinee`] to `nursery` (now allow-by-default)
+ [#9302](https://github.com/rust-lang/rust-clippy/pull/9302)
+* Rename `logic_bug` to [`overly_complex_bool_expr`]
+ [#9306](https://github.com/rust-lang/rust-clippy/pull/9306)
+* Rename `arithmetic` to [`arithmetic_side_effects`]
+ [#9443](https://github.com/rust-lang/rust-clippy/pull/9443)
+* Moved [`only_used_in_recursion`] to complexity (now warn-by-default)
+ [#8804](https://github.com/rust-lang/rust-clippy/pull/8804)
+* Moved [`assertions_on_result_states`] to restriction (now allow-by-default)
+ [#9273](https://github.com/rust-lang/rust-clippy/pull/9273)
+* Renamed `blacklisted_name` to [`disallowed_names`]
+ [#8974](https://github.com/rust-lang/rust-clippy/pull/8974)
+
+### Enhancements
+
+* [`option_if_let_else`]: Now also checks for match expressions
+ [#8696](https://github.com/rust-lang/rust-clippy/pull/8696)
+* [`explicit_auto_deref`]: Now lints on implicit returns in closures
+ [#9126](https://github.com/rust-lang/rust-clippy/pull/9126)
+* [`needless_borrow`]: Now considers trait implementations
+ [#9136](https://github.com/rust-lang/rust-clippy/pull/9136)
+* [`suboptimal_flops`], [`imprecise_flops`]: Now lint on constant expressions
+ [#9404](https://github.com/rust-lang/rust-clippy/pull/9404)
+* [`if_let_mutex`]: Now detects mutex behind references and warns about deadlocks
+ [#9318](https://github.com/rust-lang/rust-clippy/pull/9318)
+
+### False Positive Fixes
+
+* [`unit_arg`] [`default_trait_access`] [`missing_docs_in_private_items`]: No longer
+ trigger in code generated from proc-macros
+ [#8694](https://github.com/rust-lang/rust-clippy/pull/8694)
+* [`unwrap_used`]: Now lints uses of `unwrap_err`
+ [#9338](https://github.com/rust-lang/rust-clippy/pull/9338)
+* [`expect_used`]: Now lints uses of `expect_err`
+ [#9338](https://github.com/rust-lang/rust-clippy/pull/9338)
+* [`transmute_undefined_repr`]: Now longer lints if the first field is compatible
+ with the other type
+ [#9287](https://github.com/rust-lang/rust-clippy/pull/9287)
+* [`unnecessary_to_owned`]: No longer lints, if type change cased errors in
+ the caller function
+ [#9424](https://github.com/rust-lang/rust-clippy/pull/9424)
+* [`match_like_matches_macro`]: No longer lints, if there are comments inside the
+ match expression
+ [#9276](https://github.com/rust-lang/rust-clippy/pull/9276)
+* [`partialeq_to_none`]: No longer trigger in code generated from macros
+ [#9389](https://github.com/rust-lang/rust-clippy/pull/9389)
+* [`arithmetic_side_effects`]: No longer lints expressions that only use literals
+ [#9365](https://github.com/rust-lang/rust-clippy/pull/9365)
+* [`explicit_auto_deref`]: Now ignores references on block expressions when the type
+ is `Sized`, on `dyn Trait` returns and when the suggestion is non-trivial
+ [#9126](https://github.com/rust-lang/rust-clippy/pull/9126)
+* [`trait_duplication_in_bounds`]: Now better tracks bounds to avoid false positives
+ [#9167](https://github.com/rust-lang/rust-clippy/pull/9167)
+* [`format_in_format_args`]: Now suggests cases where the result is formatted again
+ [#9349](https://github.com/rust-lang/rust-clippy/pull/9349)
+* [`only_used_in_recursion`]: No longer lints on function without recursions and
+ takes external functions into account
+ [#8804](https://github.com/rust-lang/rust-clippy/pull/8804)
+* [`missing_const_for_fn`]: No longer lints in proc-macros
+ [#9308](https://github.com/rust-lang/rust-clippy/pull/9308)
+* [`non_ascii_literal`]: Allow non-ascii comments in tests and make sure `#[allow]`
+ attributes work in tests
+ [#9327](https://github.com/rust-lang/rust-clippy/pull/9327)
+* [`question_mark`]: No longer lint `if let`s with subpatterns
+ [#9348](https://github.com/rust-lang/rust-clippy/pull/9348)
+* [`needless_collect`]: No longer lints in loops
+ [#8992](https://github.com/rust-lang/rust-clippy/pull/8992)
+* [`mut_mutex_lock`]: No longer lints if the mutex is behind an immutable reference
+ [#9418](https://github.com/rust-lang/rust-clippy/pull/9418)
+* [`needless_return`]: Now ignores returns with arguments
+ [#9381](https://github.com/rust-lang/rust-clippy/pull/9381)
+* [`range_plus_one`], [`range_minus_one`]: Now ignores code with macros
+ [#9446](https://github.com/rust-lang/rust-clippy/pull/9446)
+* [`assertions_on_result_states`]: No longer lints on the unit type
+ [#9273](https://github.com/rust-lang/rust-clippy/pull/9273)
+
+### Suggestion Fixes/Improvements
+
+* [`unwrap_or_else_default`]: Now suggests `unwrap_or_default()` for empty strings
+ [#9421](https://github.com/rust-lang/rust-clippy/pull/9421)
+* [`if_then_some_else_none`]: Now also suggests `bool::then_some`
+ [#9289](https://github.com/rust-lang/rust-clippy/pull/9289)
+* [`redundant_closure_call`]: The suggestion now works for async closures
+ [#9053](https://github.com/rust-lang/rust-clippy/pull/9053)
+* [`suboptimal_flops`]: Now suggests parenthesis when they are required
+ [#9394](https://github.com/rust-lang/rust-clippy/pull/9394)
+* [`case_sensitive_file_extension_comparisons`]: Now suggests `map_or(..)` instead of `map(..).unwrap_or`
+ [#9341](https://github.com/rust-lang/rust-clippy/pull/9341)
+* Deprecated configuration values can now be updated automatically
+ [#9252](https://github.com/rust-lang/rust-clippy/pull/9252)
+* [`or_fun_call`]: Now suggest `Entry::or_default` for `Entry::or_insert(Default::default())`
+ [#9342](https://github.com/rust-lang/rust-clippy/pull/9342)
+* [`unwrap_used`]: Only suggests `expect` if [`expect_used`] is allowed
+ [#9223](https://github.com/rust-lang/rust-clippy/pull/9223)
+
+### ICE Fixes
+
+* Fix ICE in [`useless_format`] for literals
+ [#9406](https://github.com/rust-lang/rust-clippy/pull/9406)
+* Fix infinite loop in [`vec_init_then_push`]
+ [#9441](https://github.com/rust-lang/rust-clippy/pull/9441)
+* Fix ICE when reading literals with weird proc-macro spans
+ [#9303](https://github.com/rust-lang/rust-clippy/pull/9303)
## Rust 1.64
-Current stable, released 2022-09-22
+Released 2022-09-22
[d7b5cbf0...3c7e7dbc](https://github.com/rust-lang/rust-clippy/compare/d7b5cbf0...3c7e7dbc)
@@ -3903,6 +4047,7 @@ Released 2018-09-13
[`format_push_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_push_string
[`from_iter_instead_of_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_iter_instead_of_collect
[`from_over_into`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into
+[`from_raw_with_void_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_raw_with_void_ptr
[`from_str_radix_10`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_str_radix_10
[`future_not_send`]: https://rust-lang.github.io/rust-clippy/master/index.html#future_not_send
[`get_first`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_first
@@ -3978,6 +4123,7 @@ Released 2018-09-13
[`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero
[`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
[`let_underscore_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop
+[`let_underscore_future`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_future
[`let_underscore_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_lock
[`let_underscore_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_must_use
[`let_unit_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value
@@ -3996,6 +4142,8 @@ Released 2018-09-13
[`manual_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find_map
[`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten
[`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed
+[`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check
+[`manual_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
[`manual_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_map
[`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy
[`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive
@@ -4040,6 +4188,7 @@ Released 2018-09-13
[`misaligned_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#misaligned_transmute
[`mismatched_target_os`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatched_target_os
[`mismatching_type_param_order`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatching_type_param_order
+[`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_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
@@ -4198,6 +4347,8 @@ Released 2018-09-13
[`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push
[`same_name_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_name_method
[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some
+[`seek_from_current`]: https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current
+[`seek_to_start_instead_of_rewind`]: https://rust-lang.github.io/rust-clippy/master/index.html#seek_to_start_instead_of_rewind
[`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment
[`self_named_constructors`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_constructors
[`self_named_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_module_files
@@ -4247,6 +4398,7 @@ Released 2018-09-13
[`suspicious_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_splitn
[`suspicious_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_to_owned
[`suspicious_unary_op_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_unary_op_formatting
+[`suspicious_xor_used_as_pow`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_xor_used_as_pow
[`swap_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#swap_ptr_to_ref
[`tabs_in_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#tabs_in_doc_comments
[`temporary_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_assignment
@@ -4277,6 +4429,7 @@ Released 2018-09-13
[`try_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#try_err
[`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity
[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds
+[`unchecked_duration_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction
[`undocumented_unsafe_blocks`]: https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks
[`undropped_manually_drops`]: https://rust-lang.github.io/rust-clippy/master/index.html#undropped_manually_drops
[`unicode_not_nfc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unicode_not_nfc
@@ -4298,6 +4451,8 @@ Released 2018-09-13
[`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
+[`unnecessary_safety_comment`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_comment
+[`unnecessary_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc
[`unnecessary_self_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_self_imports
[`unnecessary_sort_by`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_sort_by
[`unnecessary_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned
diff --git a/src/tools/clippy/CODE_OF_CONDUCT.md b/src/tools/clippy/CODE_OF_CONDUCT.md
index dec13e44a..e3708bc48 100644
--- a/src/tools/clippy/CODE_OF_CONDUCT.md
+++ b/src/tools/clippy/CODE_OF_CONDUCT.md
@@ -1,70 +1,3 @@
# The Rust Code of Conduct
-A version of this document [can be found online](https://www.rust-lang.org/conduct.html).
-
-## Conduct
-
-**Contact**: [rust-mods@rust-lang.org](mailto:rust-mods@rust-lang.org)
-
-* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience,
- gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age,
- religion, nationality, or other similar characteristic.
-* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and
- welcoming environment for all.
-* Please be kind and courteous. There's no need to be mean or rude.
-* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and
- numerous costs. There is seldom a right answer.
-* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and
- see how it works.
-* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We
- interpret the term "harassment" as including the definition in the <a href="http://citizencodeofconduct.org/">Citizen
- Code of Conduct</a>; if you have any lack of clarity about what might be included in that concept, please read their
- definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups.
-* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or
- made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation
- team][mod_team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a
- safe place for you and we've got your back.
-* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome.
-
-## Moderation
-
-
-These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation,
-please contact the [Rust moderation team][mod_team].
-
-1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks,
- are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.)
-2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed.
-3. Moderators will first respond to such remarks with a warning.
-4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off.
-5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded.
-6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended
- party a genuine apology.
-7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a
- different moderator, **in private**. Complaints about bans in-channel are not allowed.
-8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate
- situation, they should expect less leeway than others.
-
-In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically
-unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly
-if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can
-drive people away from the community entirely.
-
-And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was
-they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good
-there was something you could've communicated better — remember that it's your responsibility to make your fellow
-Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about
-cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their
-trust.
-
-The enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust,
-#rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo);
-GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org
-(users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the
-maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider
-explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.
-
-*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the
-[Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).*
-
-[mod_team]: https://www.rust-lang.org/team.html#Moderation-team
+The Code of Conduct for this repository [can be found online](https://www.rust-lang.org/conduct.html).
diff --git a/src/tools/clippy/CONTRIBUTING.md b/src/tools/clippy/CONTRIBUTING.md
index 85f94a74a..3158080d2 100644
--- a/src/tools/clippy/CONTRIBUTING.md
+++ b/src/tools/clippy/CONTRIBUTING.md
@@ -23,6 +23,7 @@ All contributors are expected to follow the [Rust Code of Conduct].
- [Issue and PR triage](#issue-and-pr-triage)
- [Bors and Homu](#bors-and-homu)
- [Contributions](#contributions)
+ - [License](#license)
[Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/clippy
[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct
@@ -245,6 +246,38 @@ Contributions to Clippy should be made in the form of GitHub pull requests. Each
be reviewed by a core contributor (someone with permission to land patches) and either landed in the
main tree or given feedback for changes that would be required.
+All PRs should include a `changelog` entry with a short comment explaining the change. The rule of thumb is basically,
+"what do you believe is important from an outsider's perspective?" Often, PRs are only related to a single property of a
+lint, and then it's good to mention that one. Otherwise, it's better to include too much detail than too little.
+
+Clippy's [changelog] is created from these comments. Every release, someone gets all commits from bors with a
+`changelog: XYZ` entry and combines them into the changelog. This is a manual process.
+
+Examples:
+- New lint
+ ```
+ changelog: new lint: [`missing_trait_methods`]
+ ```
+- False positive fix
+ ```
+ changelog: Fix [`unused_peekable`] false positive when peeked in a closure or called as `f(&mut peekable)`
+ ```
+- Purely internal change
+ ```
+ changelog: none
+ ```
+
+Note this it is fine for a PR to include multiple `changelog` entries, e.g.:
+```
+changelog: Something 1
+changelog: Something 2
+changelog: Something 3
+```
+
+[changelog]: CHANGELOG.md
+
+## License
+
All code in this repository is under the [Apache-2.0] or the [MIT] license.
<!-- adapted from https://github.com/servo/servo/blob/master/CONTRIBUTING.md -->
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 60200a88b..fe425a2fb 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "clippy"
-version = "0.1.66"
+version = "0.1.67"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"
diff --git a/src/tools/clippy/README.md b/src/tools/clippy/README.md
index a8a6b86d2..81254ba8b 100644
--- a/src/tools/clippy/README.md
+++ b/src/tools/clippy/README.md
@@ -1,6 +1,6 @@
# Clippy
-[![Clippy Test](https://github.com/rust-lang/rust-clippy/workflows/Clippy%20Test/badge.svg?branch=auto&event=push)](https://github.com/rust-lang/rust-clippy/actions?query=workflow%3A%22Clippy+Test%22+event%3Apush+branch%3Aauto)
+[![Clippy Test](https://github.com/rust-lang/rust-clippy/workflows/Clippy%20Test%20(bors)/badge.svg?branch=auto&event=push)](https://github.com/rust-lang/rust-clippy/actions?query=workflow%3A%22Clippy+Test+(bors)%22+event%3Apush+branch%3Aauto)
[![License: MIT OR Apache-2.0](https://img.shields.io/crates/l/clippy.svg)](#license)
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
@@ -197,19 +197,13 @@ disallowed-names = ["toto", "tata", "titi"]
cognitive-complexity-threshold = 30
```
-See the [list of lints](https://rust-lang.github.io/rust-clippy/master/index.html) for more information about which
-lints can be configured and the meaning of the variables.
+See the [list of configurable lints](https://rust-lang.github.io/rust-clippy/master/index.html#Configuration),
+the lint descriptions contain the names and meanings of these configuration variables.
> **Note**
>
> `clippy.toml` or `.clippy.toml` cannot be used to allow/deny lints.
-> **Note**
->
-> Configuration changes will not apply for code that has already been compiled and cached under `./target/`;
-> for example, adding a new string to `doc-valid-idents` may still result in Clippy flagging that string. To be sure
-> that any configuration changes are applied, you may want to run `cargo clean` and re-compile your crate from scratch.
-
To deactivate the “for further information visit *lint-link*†message you can
define the `CLIPPY_DISABLE_DOCS_LINKS` environment variable.
@@ -230,7 +224,7 @@ in the `Cargo.toml` can be used.
rust-version = "1.30"
```
-The MSRV can also be specified as an inner attribute, like below.
+The MSRV can also be specified as an attribute, like below.
```rust
#![feature(custom_inner_attributes)]
diff --git a/src/tools/clippy/book/src/SUMMARY.md b/src/tools/clippy/book/src/SUMMARY.md
index 0b945faf9..1f0b8db28 100644
--- a/src/tools/clippy/book/src/SUMMARY.md
+++ b/src/tools/clippy/book/src/SUMMARY.md
@@ -21,3 +21,4 @@
- [The Clippy Book](development/infrastructure/book.md)
- [Proposals](development/proposals/README.md)
- [Roadmap 2021](development/proposals/roadmap-2021.md)
+ - [Syntax Tree Patterns](development/proposals/syntax-tree-patterns.md)
diff --git a/src/tools/clippy/book/src/configuration.md b/src/tools/clippy/book/src/configuration.md
index 77f1d2e87..430ff8b73 100644
--- a/src/tools/clippy/book/src/configuration.md
+++ b/src/tools/clippy/book/src/configuration.md
@@ -11,8 +11,8 @@ disallowed-names = ["toto", "tata", "titi"]
cognitive-complexity-threshold = 30
```
-See the [list of lints](https://rust-lang.github.io/rust-clippy/master/index.html) for more information about which
-lints can be configured and the meaning of the variables.
+See the [list of configurable lints](https://rust-lang.github.io/rust-clippy/master/index.html#Configuration),
+the lint descriptions contain the names and meanings of these configuration variables.
To deactivate the "for further information visit *lint-link*" message you can define the `CLIPPY_DISABLE_DOCS_LINKS`
environment variable.
@@ -72,7 +72,7 @@ minimum supported Rust version (MSRV) in the clippy configuration file.
msrv = "1.30.0"
```
-The MSRV can also be specified as an inner attribute, like below.
+The MSRV can also be specified as an attribute, like below.
```rust
#![feature(custom_inner_attributes)]
diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md
index 3c3f368a5..8b4eee8c9 100644
--- a/src/tools/clippy/book/src/development/adding_lints.md
+++ b/src/tools/clippy/book/src/development/adding_lints.md
@@ -443,27 +443,27 @@ value is passed to the constructor in `clippy_lints/lib.rs`.
```rust
pub struct ManualStrip {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl ManualStrip {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
```
The project's MSRV can then be matched against the feature MSRV in the LintPass
-using the `meets_msrv` utility function.
+using the `Msrv::meets` method.
``` rust
-if !meets_msrv(self.msrv, msrvs::STR_STRIP_PREFIX) {
+if !self.msrv.meets(msrvs::STR_STRIP_PREFIX) {
return;
}
```
-The project's MSRV can also be specified as an inner attribute, which overrides
+The project's MSRV can also be specified as an attribute, which overrides
the value from `clippy.toml`. This can be accounted for using the
`extract_msrv_attr!(LintContext)` macro and passing
`LateContext`/`EarlyContext`.
@@ -483,19 +483,15 @@ have a case for the version below the MSRV and one with the same contents but
for the MSRV version itself.
```rust
-#![feature(custom_inner_attributes)]
-
...
+#[clippy::msrv = "1.44"]
fn msrv_1_44() {
- #![clippy::msrv = "1.44"]
-
/* something that would trigger the lint */
}
+#[clippy::msrv = "1.45"]
fn msrv_1_45() {
- #![clippy::msrv = "1.45"]
-
/* something that would trigger the lint */
}
```
diff --git a/src/tools/clippy/book/src/development/proposals/syntax-tree-patterns.md b/src/tools/clippy/book/src/development/proposals/syntax-tree-patterns.md
new file mode 100644
index 000000000..c5587c4bf
--- /dev/null
+++ b/src/tools/clippy/book/src/development/proposals/syntax-tree-patterns.md
@@ -0,0 +1,986 @@
+- Feature Name: syntax-tree-patterns
+- Start Date: 2019-03-12
+- RFC PR: [#3875](https://github.com/rust-lang/rust-clippy/pull/3875)
+
+# Summary
+
+Introduce a domain-specific language (similar to regular expressions) that
+allows to describe lints using *syntax tree patterns*.
+
+
+# Motivation
+
+Finding parts of a syntax tree (AST, HIR, ...) that have certain properties
+(e.g. "*an if that has a block as its condition*") is a major task when writing
+lints. For non-trivial lints, it often requires nested pattern matching of AST /
+HIR nodes. For example, testing that an expression is a boolean literal requires
+the following checks:
+
+```rust
+if let ast::ExprKind::Lit(lit) = &expr.node {
+ if let ast::LitKind::Bool(_) = &lit.node {
+ ...
+ }
+}
+```
+
+Writing this kind of matching code quickly becomes a complex task and the
+resulting code is often hard to comprehend. The code below shows a simplified
+version of the pattern matching required by the `collapsible_if` lint:
+
+```rust
+// simplified version of the collapsible_if lint
+if let ast::ExprKind::If(check, then, None) = &expr.node {
+ if then.stmts.len() == 1 {
+ if let ast::StmtKind::Expr(inner) | ast::StmtKind::Semi(inner) = &then.stmts[0].node {
+ if let ast::ExprKind::If(check_inner, content, None) = &inner.node {
+ ...
+ }
+ }
+ }
+}
+```
+
+The `if_chain` macro can improve readability by flattening the nested if
+statements, but the resulting code is still quite hard to read:
+
+```rust
+// simplified version of the collapsible_if lint
+if_chain! {
+ if let ast::ExprKind::If(check, then, None) = &expr.node;
+ if then.stmts.len() == 1;
+ if let ast::StmtKind::Expr(inner) | ast::StmtKind::Semi(inner) = &then.stmts[0].node;
+ if let ast::ExprKind::If(check_inner, content, None) = &inner.node;
+ then {
+ ...
+ }
+}
+```
+
+The code above matches if expressions that contain only another if expression
+(where both ifs don't have an else branch). While it's easy to explain what the
+lint does, it's hard to see that from looking at the code samples above.
+
+Following the motivation above, the first goal this RFC is to **simplify writing
+and reading lints**.
+
+The second part of the motivation is clippy's dependence on unstable
+compiler-internal data structures. Clippy lints are currently written against
+the compiler's AST / HIR which means that even small changes in these data
+structures might break a lot of lints. The second goal of this RFC is to **make
+lints independant of the compiler's AST / HIR data structures**.
+
+# Approach
+
+A lot of complexity in writing lints currently seems to come from having to
+manually implement the matching logic (see code samples above). It's an
+imparative style that describes *how* to match a syntax tree node instead of
+specifying *what* should be matched against declaratively. In other areas, it's
+common to use declarative patterns to describe desired information and let the
+implementation do the actual matching. A well-known example of this approach are
+[regular expressions](https://en.wikipedia.org/wiki/Regular_expression). Instead
+of writing code that detects certain character sequences, one can describe a
+search pattern using a domain-specific language and search for matches using
+that pattern. The advantage of using a declarative domain-specific language is
+that its limited domain (e.g. matching character sequences in the case of
+regular expressions) allows to express entities in that domain in a very natural
+and expressive way.
+
+While regular expressions are very useful when searching for patterns in flat
+character sequences, they cannot easily be applied to hierarchical data
+structures like syntax trees. This RFC therefore proposes a pattern matching
+system that is inspired by regular expressions and designed for hierarchical
+syntax trees.
+
+# Guide-level explanation
+
+This proposal adds a `pattern!` macro that can be used to specify a syntax tree
+pattern to search for. A simple pattern is shown below:
+
+```rust
+pattern!{
+ my_pattern: Expr =
+ Lit(Bool(false))
+}
+```
+
+This macro call defines a pattern named `my_pattern` that can be matched against
+an `Expr` syntax tree node. The actual pattern (`Lit(Bool(false))` in this case)
+defines which syntax trees should match the pattern. This pattern matches
+expressions that are boolean literals with value `false`.
+
+The pattern can then be used to implement lints in the following way:
+
+```rust
+...
+
+impl EarlyLintPass for MyAwesomeLint {
+ fn check_expr(&mut self, cx: &EarlyContext, expr: &syntax::ast::Expr) {
+
+ if my_pattern(expr).is_some() {
+ cx.span_lint(
+ MY_AWESOME_LINT,
+ expr.span,
+ "This is a match for a simple pattern. Well done!",
+ );
+ }
+
+ }
+}
+```
+
+The `pattern!` macro call expands to a function `my_pattern` that expects a
+syntax tree expression as its argument and returns an `Option` that indicates
+whether the pattern matched.
+
+> Note: The result type is explained in more detail in [a later
+> section](#the-result-type). For now, it's enough to know that the result is
+> `Some` if the pattern matched and `None` otherwise.
+
+## Pattern syntax
+
+The following examples demonstate the pattern syntax:
+
+
+#### Any (`_`)
+
+The simplest pattern is the any pattern. It matches anything and is therefore
+similar to regex's `*`.
+
+```rust
+pattern!{
+ // matches any expression
+ my_pattern: Expr =
+ _
+}
+```
+
+#### Node (`<node-name>(<args>)`)
+
+Nodes are used to match a specific variant of an AST node. A node has a name and
+a number of arguments that depends on the node type. For example, the `Lit` node
+has a single argument that describes the type of the literal. As another
+example, the `If` node has three arguments describing the if's condition, then
+block and else block.
+
+```rust
+pattern!{
+ // matches any expression that is a literal
+ my_pattern: Expr =
+ Lit(_)
+}
+
+pattern!{
+ // matches any expression that is a boolean literal
+ my_pattern: Expr =
+ Lit(Bool(_))
+}
+
+pattern!{
+ // matches if expressions that have a boolean literal in their condition
+ // Note: The `_?` syntax here means that the else branch is optional and can be anything.
+ // This is discussed in more detail in the section `Repetition`.
+ my_pattern: Expr =
+ If( Lit(Bool(_)) , _, _?)
+}
+```
+
+
+#### Literal (`<lit>`)
+
+A pattern can also contain Rust literals. These literals match themselves.
+
+```rust
+pattern!{
+ // matches the boolean literal false
+ my_pattern: Expr =
+ Lit(Bool(false))
+}
+
+pattern!{
+ // matches the character literal 'x'
+ my_pattern: Expr =
+ Lit(Char('x'))
+}
+```
+
+#### Alternations (`a | b`)
+
+```rust
+pattern!{
+ // matches if the literal is a boolean or integer literal
+ my_pattern: Lit =
+ Bool(_) | Int(_)
+}
+
+pattern!{
+ // matches if the expression is a char literal with value 'x' or 'y'
+ my_pattern: Expr =
+ Lit( Char('x' | 'y') )
+}
+```
+
+#### Empty (`()`)
+
+The empty pattern represents an empty sequence or the `None` variant of an
+optional.
+
+```rust
+pattern!{
+ // matches if the expression is an empty array
+ my_pattern: Expr =
+ Array( () )
+}
+
+pattern!{
+ // matches if expressions that don't have an else clause
+ my_pattern: Expr =
+ If(_, _, ())
+}
+```
+
+#### Sequence (`<a> <b>`)
+
+```rust
+pattern!{
+ // matches the array [true, false]
+ my_pattern: Expr =
+ Array( Lit(Bool(true)) Lit(Bool(false)) )
+}
+```
+
+#### Repetition (`<a>*`, `<a>+`, `<a>?`, `<a>{n}`, `<a>{n,m}`, `<a>{n,}`)
+
+Elements may be repeated. The syntax for specifying repetitions is identical to
+[regex's syntax](https://docs.rs/regex/1.1.2/regex/#repetitions).
+
+```rust
+pattern!{
+ // matches arrays that contain 2 'x's as their last or second-last elements
+ // Examples:
+ // ['x', 'x'] match
+ // ['x', 'x', 'y'] match
+ // ['a', 'b', 'c', 'x', 'x', 'y'] match
+ // ['x', 'x', 'y', 'z'] no match
+ my_pattern: Expr =
+ Array( _* Lit(Char('x')){2} _? )
+}
+
+pattern!{
+ // matches if expressions that **may or may not** have an else block
+ // Attn: `If(_, _, _)` matches only ifs that **have** an else block
+ //
+ // | if with else block | if witout else block
+ // If(_, _, _) | match | no match
+ // If(_, _, _?) | match | match
+ // If(_, _, ()) | no match | match
+ my_pattern: Expr =
+ If(_, _, _?)
+}
+```
+
+#### Named submatch (`<a>#<name>`)
+
+```rust
+pattern!{
+ // matches character literals and gives the literal the name foo
+ my_pattern: Expr =
+ Lit(Char(_)#foo)
+}
+
+pattern!{
+ // matches character literals and gives the char the name bar
+ my_pattern: Expr =
+ Lit(Char(_#bar))
+}
+
+pattern!{
+ // matches character literals and gives the expression the name baz
+ my_pattern: Expr =
+ Lit(Char(_))#baz
+}
+```
+
+The reason for using named submatches is described in the section [The result
+type](#the-result-type).
+
+### Summary
+
+The following table gives an summary of the pattern syntax:
+
+| Syntax | Concept | Examples |
+|-------------------------|------------------|--------------------------------------------|
+|`_` | Any | `_` |
+|`<node-name>(<args>)` | Node | `Lit(Bool(true))`, `If(_, _, _)` |
+|`<lit>` | Literal | `'x'`, `false`, `101` |
+|`<a> \| <b>` | Alternation | `Char(_) \| Bool(_)` |
+|`()` | Empty | `Array( () )` |
+|`<a> <b>` | Sequence | `Tuple( Lit(Bool(_)) Lit(Int(_)) Lit(_) )` |
+|`<a>*` <br> `<a>+` <br> `<a>?` <br> `<a>{n}` <br> `<a>{n,m}` <br> `<a>{n,}` | Repetition <br> <br> <br> <br> <br><br> | `Array( _* )`, <br> `Block( Semi(_)+ )`, <br> `If(_, _, Block(_)?)`, <br> `Array( Lit(_){10} )`, <br> `Lit(_){5,10}`, <br> `Lit(Bool(_)){10,}` |
+|`<a>#<name>` | Named submatch | `Lit(Int(_))#foo` `Lit(Int(_#bar))` |
+
+
+## The result type
+
+A lot of lints require checks that go beyond what the pattern syntax described
+above can express. For example, a lint might want to check whether a node was
+created as part of a macro expansion or whether there's no comment above a node.
+Another example would be a lint that wants to match two nodes that have the same
+value (as needed by lints like `almost_swapped`). Instead of allowing users to
+write these checks into the pattern directly (which might make patterns hard to
+read), the proposed solution allows users to assign names to parts of a pattern
+expression. When matching a pattern against a syntax tree node, the return value
+will contain references to all nodes that were matched by these named
+subpatterns. This is similar to capture groups in regular expressions.
+
+For example, given the following pattern
+
+```rust
+pattern!{
+ // matches character literals
+ my_pattern: Expr =
+ Lit(Char(_#val_inner)#val)#val_outer
+}
+```
+
+one could get references to the nodes that matched the subpatterns in the
+following way:
+
+```rust
+...
+fn check_expr(expr: &syntax::ast::Expr) {
+ if let Some(result) = my_pattern(expr) {
+ result.val_inner // type: &char
+ result.val // type: &syntax::ast::Lit
+ result.val_outer // type: &syntax::ast::Expr
+ }
+}
+```
+
+The types in the `result` struct depend on the pattern. For example, the
+following pattern
+
+```rust
+pattern!{
+ // matches arrays of character literals
+ my_pattern_seq: Expr =
+ Array( Lit(_)*#foo )
+}
+```
+
+matches arrays that consist of any number of literal expressions. Because those
+expressions are named `foo`, the result struct contains a `foo` attribute which
+is a vector of expressions:
+
+```rust
+...
+if let Some(result) = my_pattern_seq(expr) {
+ result.foo // type: Vec<&syntax::ast::Expr>
+}
+```
+
+Another result type occurs when a name is only defined in one branch of an
+alternation:
+
+```rust
+pattern!{
+ // matches if expression is a boolean or integer literal
+ my_pattern_alt: Expr =
+ Lit( Bool(_#bar) | Int(_) )
+}
+```
+
+In the pattern above, the `bar` name is only defined if the pattern matches a
+boolean literal. If it matches an integer literal, the name isn't set. To
+account for this, the result struct's `bar` attribute is an option type:
+
+```rust
+...
+if let Some(result) = my_pattern_alt(expr) {
+ result.bar // type: Option<&bool>
+}
+```
+
+It's also possible to use a name in multiple alternation branches if they have
+compatible types:
+
+```rust
+pattern!{
+ // matches if expression is a boolean or integer literal
+ my_pattern_mult: Expr =
+ Lit(_#baz) | Array( Lit(_#baz) )
+}
+...
+if let Some(result) = my_pattern_mult(expr) {
+ result.baz // type: &syntax::ast::Lit
+}
+```
+
+Named submatches are a **flat** namespace and this is intended. In the example
+above, two different sub-structures are assigned to a flat name. I expect that
+for most lints, a flat namespace is sufficient and easier to work with than a
+hierarchical one.
+
+#### Two stages
+
+Using named subpatterns, users can write lints in two stages. First, a coarse
+selection of possible matches is produced by the pattern syntax. In the second
+stage, the named subpattern references can be used to do additional tests like
+asserting that a node hasn't been created as part of a macro expansion.
+
+## Implementing clippy lints using patterns
+
+As a "real-world" example, I re-implemented the `collapsible_if` lint using
+patterns. The code can be found
+[here](https://github.com/fkohlgrueber/rust-clippy-pattern/blob/039b07ecccaf96d6aa7504f5126720d2c9cceddd/clippy_lints/src/collapsible_if.rs#L88-L163).
+The pattern-based version passes all test cases that were written for
+`collapsible_if`.
+
+
+# Reference-level explanation
+
+## Overview
+
+The following diagram shows the dependencies between the main parts of the
+proposed solution:
+
+```
+ Pattern syntax
+ |
+ | parsing / lowering
+ v
+ PatternTree
+ ^
+ |
+ |
+ IsMatch trait
+ |
+ |
+ +---------------+-----------+---------+
+ | | | |
+ v v v v
+ syntax::ast rustc::hir syn ...
+```
+
+The pattern syntax described in the previous section is parsed / lowered into
+the so-called *PatternTree* data structure that represents a valid syntax tree
+pattern. Matching a *PatternTree* against an actual syntax tree (e.g. rust ast /
+hir or the syn ast, ...) is done using the *IsMatch* trait.
+
+The *PatternTree* and the *IsMatch* trait are introduced in more detail in the
+following sections.
+
+## PatternTree
+
+The core data structure of this RFC is the **PatternTree**.
+
+It's a data structure similar to rust's AST / HIR, but with the following
+differences:
+
+- The PatternTree doesn't contain parsing information like `Span`s
+- The PatternTree can represent alternatives, sequences and optionals
+
+The code below shows a simplified version of the current PatternTree:
+
+> Note: The current implementation can be found
+> [here](https://github.com/fkohlgrueber/pattern-matching/blob/dfb3bc9fbab69cec7c91e72564a63ebaa2ede638/pattern-match/src/pattern_tree.rs#L50-L96).
+
+
+```rust
+pub enum Expr {
+ Lit(Alt<Lit>),
+ Array(Seq<Expr>),
+ Block_(Alt<BlockType>),
+ If(Alt<Expr>, Alt<BlockType>, Opt<Expr>),
+ IfLet(
+ Alt<BlockType>,
+ Opt<Expr>,
+ ),
+}
+
+pub enum Lit {
+ Char(Alt<char>),
+ Bool(Alt<bool>),
+ Int(Alt<u128>),
+}
+
+pub enum Stmt {
+ Expr(Alt<Expr>),
+ Semi(Alt<Expr>),
+}
+
+pub enum BlockType {
+ Block(Seq<Stmt>),
+}
+```
+
+The `Alt`, `Seq` and `Opt` structs look like these:
+
+> Note: The current implementation can be found
+> [here](https://github.com/fkohlgrueber/pattern-matching/blob/dfb3bc9fbab69cec7c91e72564a63ebaa2ede638/pattern-match/src/matchers.rs#L35-L60).
+
+```rust
+pub enum Alt<T> {
+ Any,
+ Elmt(Box<T>),
+ Alt(Box<Self>, Box<Self>),
+ Named(Box<Self>, ...)
+}
+
+pub enum Opt<T> {
+ Any, // anything, but not None
+ Elmt(Box<T>),
+ None,
+ Alt(Box<Self>, Box<Self>),
+ Named(Box<Self>, ...)
+}
+
+pub enum Seq<T> {
+ Any,
+ Empty,
+ Elmt(Box<T>),
+ Repeat(Box<Self>, RepeatRange),
+ Seq(Box<Self>, Box<Self>),
+ Alt(Box<Self>, Box<Self>),
+ Named(Box<Self>, ...)
+}
+
+pub struct RepeatRange {
+ pub start: usize,
+ pub end: Option<usize> // exclusive
+}
+```
+
+## Parsing / Lowering
+
+The input of a `pattern!` macro call is parsed into a `ParseTree` first and then
+lowered to a `PatternTree`.
+
+Valid patterns depend on the *PatternTree* definitions. For example, the pattern
+`Lit(Bool(_)*)` isn't valid because the parameter type of the `Lit` variant of
+the `Expr` enum is `Any<Lit>` and therefore doesn't support repetition (`*`). As
+another example, `Array( Lit(_)* )` is a valid pattern because the parameter of
+`Array` is of type `Seq<Expr>` which allows sequences and repetitions.
+
+> Note: names in the pattern syntax correspond to *PatternTree* enum
+> **variants**. For example, the `Lit` in the pattern above refers to the `Lit`
+> variant of the `Expr` enum (`Expr::Lit`), not the `Lit` enum.
+
+## The IsMatch Trait
+
+The pattern syntax and the *PatternTree* are independant of specific syntax tree
+implementations (rust ast / hir, syn, ...). When looking at the different
+pattern examples in the previous sections, it can be seen that the patterns
+don't contain any information specific to a certain syntax tree implementation.
+In contrast, clippy lints currently match against ast / hir syntax tree nodes
+and therefore directly depend on their implementation.
+
+The connection between the *PatternTree* and specific syntax tree
+implementations is the `IsMatch` trait. It defines how to match *PatternTree*
+nodes against specific syntax tree nodes. A simplified implementation of the
+`IsMatch` trait is shown below:
+
+```rust
+pub trait IsMatch<O> {
+ fn is_match(&self, other: &'o O) -> bool;
+}
+```
+
+This trait needs to be implemented on each enum of the *PatternTree* (for the
+corresponding syntax tree types). For example, the `IsMatch` implementation for
+matching `ast::LitKind` against the *PatternTree's* `Lit` enum might look like
+this:
+
+```rust
+impl IsMatch<ast::LitKind> for Lit {
+ fn is_match(&self, other: &ast::LitKind) -> bool {
+ match (self, other) {
+ (Lit::Char(i), ast::LitKind::Char(j)) => i.is_match(j),
+ (Lit::Bool(i), ast::LitKind::Bool(j)) => i.is_match(j),
+ (Lit::Int(i), ast::LitKind::Int(j, _)) => i.is_match(j),
+ _ => false,
+ }
+ }
+}
+```
+
+All `IsMatch` implementations for matching the current *PatternTree* against
+`syntax::ast` can be found
+[here](https://github.com/fkohlgrueber/pattern-matching/blob/dfb3bc9fbab69cec7c91e72564a63ebaa2ede638/pattern-match/src/ast_match.rs).
+
+
+# Drawbacks
+
+#### Performance
+
+The pattern matching code is currently not optimized for performance, so it
+might be slower than hand-written matching code. Additionally, the two-stage
+approach (matching against the coarse pattern first and checking for additional
+properties later) might be slower than the current practice of checking for
+structure and additional properties in one pass. For example, the following lint
+
+```rust
+pattern!{
+ pat_if_without_else: Expr =
+ If(
+ _,
+ Block(
+ Expr( If(_, _, ())#inner )
+ | Semi( If(_, _, ())#inner )
+ )#then,
+ ()
+ )
+}
+...
+fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
+ if let Some(result) = pat_if_without_else(expr) {
+ if !block_starts_with_comment(cx, result.then) {
+ ...
+ }
+}
+```
+
+first matches against the pattern and then checks that the `then` block doesn't
+start with a comment. Using clippy's current approach, it's possible to check
+for these conditions earlier:
+
+```rust
+fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
+ if_chain! {
+ if let ast::ExprKind::If(ref check, ref then, None) = expr.node;
+ if !block_starts_with_comment(cx, then);
+ if let Some(inner) = expr_block(then);
+ if let ast::ExprKind::If(ref check_inner, ref content, None) = inner.node;
+ then {
+ ...
+ }
+ }
+}
+```
+
+Whether or not this causes performance regressions depends on actual patterns.
+If it turns out to be a problem, the pattern matching algorithms could be
+extended to allow "early filtering" (see the [Early Filtering](#early-filtering)
+section in Future Possibilities).
+
+That being said, I don't see any conceptual limitations regarding pattern
+matching performance.
+
+#### Applicability
+
+Even though I'd expect that a lot of lints can be written using the proposed
+pattern syntax, it's unlikely that all lints can be expressed using patterns. I
+suspect that there will still be lints that need to be implemented by writing
+custom pattern matching code. This would lead to mix within clippy's codebase
+where some lints are implemented using patterns and others aren't. This
+inconsistency might be considered a drawback.
+
+
+# Rationale and alternatives
+
+Specifying lints using syntax tree patterns has a couple of advantages compared
+to the current approach of manually writing matching code. First, syntax tree
+patterns allow users to describe patterns in a simple and expressive way. This
+makes it easier to write new lints for both novices and experts and also makes
+reading / modifying existing lints simpler.
+
+Another advantage is that lints are independent of specific syntax tree
+implementations (e.g. AST / HIR, ...). When these syntax tree implementations
+change, only the `IsMatch` trait implementations need to be adapted and existing
+lints can remain unchanged. This also means that if the `IsMatch` trait
+implementations were integrated into the compiler, updating the `IsMatch`
+implementations would be required for the compiler to compile successfully. This
+could reduce the number of times clippy breaks because of changes in the
+compiler. Another advantage of the pattern's independence is that converting an
+`EarlyLintPass` lint into a `LatePassLint` wouldn't require rewriting the whole
+pattern matching code. In fact, the pattern might work just fine without any
+adaptions.
+
+
+## Alternatives
+
+### Rust-like pattern syntax
+
+The proposed pattern syntax requires users to know the structure of the
+`PatternTree` (which is very similar to the AST's / HIR's structure) and also
+the pattern syntax. An alternative would be to introduce a pattern syntax that
+is similar to actual Rust syntax (probably like the `quote!` macro). For
+example, a pattern that matches `if` expressions that have `false` in their
+condition could look like this:
+
+```rust
+if false {
+ #[*]
+}
+```
+
+#### Problems
+
+Extending Rust syntax (which is quite complex by itself) with additional syntax
+needed for specifying patterns (alternations, sequences, repetisions, named
+submatches, ...) might become difficult to read and really hard to parse
+properly.
+
+For example, a pattern that matches a binary operation that has `0` on both
+sides might look like this:
+
+```
+0 #[*:BinOpKind] 0
+```
+
+Now consider this slightly more complex example:
+
+```
+1 + 0 #[*:BinOpKind] 0
+```
+
+The parser would need to know the precedence of `#[*:BinOpKind]` because it
+affects the structure of the resulting AST. `1 + 0 + 0` is parsed as `(1 + 0) +
+0` while `1 + 0 * 0` is parsed as `1 + (0 * 0)`. Since the pattern could be any
+`BinOpKind`, the precedence cannot be known in advance.
+
+Another example of a problem would be named submatches. Take a look at this
+pattern:
+
+```rust
+fn test() {
+ 1 #foo
+}
+```
+
+Which node is `#foo` referring to? `int`, `ast::Lit`, `ast::Expr`, `ast::Stmt`?
+Naming subpatterns in a rust-like syntax is difficult because a lot of AST nodes
+don't have a syntactic element that can be used to put the name tag on. In these
+situations, the only sensible option would be to assign the name tag to the
+outermost node (`ast::Stmt` in the example above), because the information of
+all child nodes can be retrieved through the outermost node. The problem with
+this then would be that accessing inner nodes (like `ast::Lit`) would again
+require manual pattern matching.
+
+In general, Rust syntax contains a lot of code structure implicitly. This
+structure is reconstructed during parsing (e.g. binary operations are
+reconstructed using operator precedence and left-to-right) and is one of the
+reasons why parsing is a complex task. The advantage of this approach is that
+writing code is simpler for users.
+
+When writing *syntax tree patterns*, each element of the hierarchy might have
+alternatives, repetitions, etc.. Respecting that while still allowing
+human-friendly syntax that contains structure implicitly seems to be really
+complex, if not impossible.
+
+Developing such a syntax would also require to maintain a custom parser that is
+at least as complex as the Rust parser itself. Additionally, future changes in
+the Rust syntax might be incompatible with such a syntax.
+
+In summary, I think that developing such a syntax would introduce a lot of
+complexity to solve a relatively minor problem.
+
+The issue of users not knowing about the *PatternTree* structure could be solved
+by a tool that, given a rust program, generates a pattern that matches only this
+program (similar to the clippy author lint).
+
+For some simple cases (like the first example above), it might be possible to
+successfully mix Rust and pattern syntax. This space could be further explored
+in a future extension.
+
+# Prior art
+
+The pattern syntax is heavily inspired by regular expressions (repetitions,
+alternatives, sequences, ...).
+
+From what I've seen until now, other linters also implement lints that directly
+work on syntax tree data structures, just like clippy does currently. I would
+therefore consider the pattern syntax to be *new*, but please correct me if I'm
+wrong.
+
+# Unresolved questions
+
+#### How to handle multiple matches?
+
+When matching a syntax tree node against a pattern, there are possibly multiple
+ways in which the pattern can be matched. A simple example of this would be the
+following pattern:
+
+```rust
+pattern!{
+ my_pattern: Expr =
+ Array( _* Lit(_)+#literals)
+}
+```
+
+This pattern matches arrays that end with at least one literal. Now given the
+array `[x, 1, 2]`, should `1` be matched as part of the `_*` or the `Lit(_)+`
+part of the pattern? The difference is important because the named submatch
+`#literals` would contain 1 or 2 elements depending how the pattern is matched.
+In regular expressions, this problem is solved by matching "greedy" by default
+and "non-greedy" optionally.
+
+I haven't looked much into this yet because I don't know how relevant it is for
+most lints. The current implementation simply returns the first match it finds.
+
+# Future possibilities
+
+#### Implement rest of Rust Syntax
+
+The current project only implements a small part of the Rust syntax. In the
+future, this should incrementally be extended to more syntax to allow
+implementing more lints. Implementing more of the Rust syntax requires extending
+the `PatternTree` and `IsMatch` implementations, but should be relatively
+straight-forward.
+
+#### Early filtering
+
+As described in the *Drawbacks/Performance* section, allowing additional checks
+during the pattern matching might be beneficial.
+
+The pattern below shows how this could look like:
+
+```rust
+pattern!{
+ pat_if_without_else: Expr =
+ If(
+ _,
+ Block(
+ Expr( If(_, _, ())#inner )
+ | Semi( If(_, _, ())#inner )
+ )#then,
+ ()
+ )
+ where
+ !in_macro(#then.span);
+}
+```
+
+The difference compared to the currently proposed two-stage filtering is that
+using early filtering, the condition (`!in_macro(#then.span)` in this case)
+would be evaluated as soon as the `Block(_)#then` was matched.
+
+Another idea in this area would be to introduce a syntax for backreferences.
+They could be used to require that multiple parts of a pattern should match the
+same value. For example, the `assign_op_pattern` lint that searches for `a = a
+op b` and recommends changing it to `a op= b` requires that both occurrances of
+`a` are the same. Using `=#...` as syntax for backreferences, the lint could be
+implemented like this:
+
+```rust
+pattern!{
+ assign_op_pattern: Expr =
+ Assign(_#target, Binary(_, =#target, _)
+}
+```
+
+#### Match descendant
+
+A lot of lints currently implement custom visitors that check whether any
+subtree (which might not be a direct descendant) of the current node matches
+some properties. This cannot be expressed with the proposed pattern syntax.
+Extending the pattern syntax to allow patterns like "a function that contains at
+least two return statements" could be a practical addition.
+
+#### Negation operator for alternatives
+
+For patterns like "a literal that is not a boolean literal" one currently needs
+to list all alternatives except the boolean case. Introducing a negation
+operator that allows to write `Lit(!Bool(_))` might be a good idea. This pattern
+would be eqivalent to `Lit( Char(_) | Int(_) )` (given that currently only three
+literal types are implemented).
+
+#### Functional composition
+
+Patterns currently don't have any concept of composition. This leads to
+repetitions within patterns. For example, one of the collapsible-if patterns
+currently has to be written like this:
+
+```rust
+pattern!{
+ pat_if_else: Expr =
+ If(
+ _,
+ _,
+ Block_(
+ Block(
+ Expr((If(_, _, _?) | IfLet(_, _?))#else_) |
+ Semi((If(_, _, _?) | IfLet(_, _?))#else_)
+ )#block_inner
+ )#block
+ ) |
+ IfLet(
+ _,
+ Block_(
+ Block(
+ Expr((If(_, _, _?) | IfLet(_, _?))#else_) |
+ Semi((If(_, _, _?) | IfLet(_, _?))#else_)
+ )#block_inner
+ )#block
+ )
+}
+```
+
+If patterns supported defining functions of subpatterns, the code could be
+simplified as follows:
+
+```rust
+pattern!{
+ fn expr_or_semi(expr: Expr) -> Stmt {
+ Expr(expr) | Semi(expr)
+ }
+ fn if_or_if_let(then: Block, else: Opt<Expr>) -> Expr {
+ If(_, then, else) | IfLet(then, else)
+ }
+ pat_if_else: Expr =
+ if_or_if_let(
+ _,
+ Block_(
+ Block(
+ expr_or_semi( if_or_if_let(_, _?)#else_ )
+ )#block_inner
+ )#block
+ )
+}
+```
+
+Additionally, common patterns like `expr_or_semi` could be shared between
+different lints.
+
+#### Clippy Pattern Author
+
+Another improvement could be to create a tool that, given some valid Rust
+syntax, generates a pattern that matches this syntax exactly. This would make
+starting to write a pattern easier. A user could take a look at the patterns
+generated for a couple of Rust code examples and use that information to write a
+pattern that matches all of them.
+
+This is similar to clippy's author lint.
+
+#### Supporting other syntaxes
+
+Most of the proposed system is language-agnostic. For example, the pattern
+syntax could also be used to describe patterns for other programming languages.
+
+In order to support other languages' syntaxes, one would need to implement
+another `PatternTree` that sufficiently describes the languages' AST and
+implement `IsMatch` for this `PatternTree` and the languages' AST.
+
+One aspect of this is that it would even be possible to write lints that work on
+the pattern syntax itself. For example, when writing the following pattern
+
+
+```rust
+pattern!{
+ my_pattern: Expr =
+ Array( Lit(Bool(false)) Lit(Bool(false)) )
+}
+```
+
+a lint that works on the pattern syntax's AST could suggest using this pattern
+instead:
+
+```rust
+pattern!{
+ my_pattern: Expr =
+ Array( Lit(Bool(false)){2} )
+}
+```
+
+In the future, clippy could use this system to also provide lints for custom
+syntaxes like those found in macros.
diff --git a/src/tools/clippy/clippy_dev/Cargo.toml b/src/tools/clippy/clippy_dev/Cargo.toml
index 2ac3b4fe2..510c7e852 100644
--- a/src/tools/clippy/clippy_dev/Cargo.toml
+++ b/src/tools/clippy/clippy_dev/Cargo.toml
@@ -10,7 +10,6 @@ indoc = "1.0"
itertools = "0.10.1"
opener = "0.5"
shell-escape = "0.1"
-tempfile = "3.2"
walkdir = "2.3"
[features]
diff --git a/src/tools/clippy/clippy_dev/src/lint.rs b/src/tools/clippy/clippy_dev/src/lint.rs
index 71005449b..aafd0f71a 100644
--- a/src/tools/clippy/clippy_dev/src/lint.rs
+++ b/src/tools/clippy/clippy_dev/src/lint.rs
@@ -36,20 +36,12 @@ pub fn run<'a>(path: &str, args: impl Iterator<Item = &'a String>) {
} else {
exit_if_err(Command::new("cargo").arg("build").status());
- // Run in a tempdir as changes to clippy do not retrigger linting
- let target = tempfile::Builder::new()
- .prefix("clippy")
- .tempdir()
- .expect("failed to create tempdir");
-
let status = Command::new(cargo_clippy_path())
.arg("clippy")
.args(args)
.current_dir(path)
- .env("CARGO_TARGET_DIR", target.as_ref())
.status();
- target.close().expect("failed to remove tempdir");
exit_if_err(status);
}
}
diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs
index 9e15f1504..ec7f1dd0d 100644
--- a/src/tools/clippy/clippy_dev/src/new_lint.rs
+++ b/src/tools/clippy/clippy_dev/src/new_lint.rs
@@ -120,7 +120,7 @@ fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
let new_lint = if enable_msrv {
format!(
- "store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(msrv)));\n ",
+ "store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(msrv())));\n ",
lint_pass = lint.pass,
ctor_arg = if lint.pass == "late" { "_" } else { "" },
module_name = lint.name,
@@ -238,10 +238,9 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
result.push_str(&if enable_msrv {
formatdoc!(
r#"
- use clippy_utils::msrvs;
+ use clippy_utils::msrvs::{{self, Msrv}};
{pass_import}
use rustc_lint::{{{context_import}, {pass_type}, LintContext}};
- use rustc_semver::RustcVersion;
use rustc_session::{{declare_tool_lint, impl_lint_pass}};
"#
@@ -263,12 +262,12 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
formatdoc!(
r#"
pub struct {name_camel} {{
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}}
impl {name_camel} {{
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {{
+ pub fn new(msrv: Msrv) -> Self {{
Self {{ msrv }}
}}
}}
@@ -357,15 +356,14 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
let _ = writedoc!(
lint_file_contents,
r#"
- use clippy_utils::{{meets_msrv, msrvs}};
+ use clippy_utils::msrvs::{{self, Msrv}};
use rustc_lint::{{{context_import}, LintContext}};
- use rustc_semver::RustcVersion;
use super::{name_upper};
// TODO: Adjust the parameters as necessary
- pub(super) fn check(cx: &{context_import}, msrv: Option<RustcVersion>) {{
- if !meets_msrv(msrv, todo!("Add a new entry in `clippy_utils/src/msrvs`")) {{
+ pub(super) fn check(cx: &{context_import}, msrv: &Msrv) {{
+ if !msrv.meets(todo!("Add a new entry in `clippy_utils/src/msrvs`")) {{
return;
}}
todo!();
diff --git a/src/tools/clippy/clippy_dev/src/setup/git_hook.rs b/src/tools/clippy/clippy_dev/src/setup/git_hook.rs
index 1de5b1940..c7c53bc69 100644
--- a/src/tools/clippy/clippy_dev/src/setup/git_hook.rs
+++ b/src/tools/clippy/clippy_dev/src/setup/git_hook.rs
@@ -6,7 +6,7 @@ use super::verify_inside_clippy_dir;
/// Rusts setup uses `git rev-parse --git-common-dir` to get the root directory of the repo.
/// I've decided against this for the sake of simplicity and to make sure that it doesn't install
/// the hook if `clippy_dev` would be used in the rust tree. The hook also references this tool
-/// for formatting and should therefor only be used in a normal clone of clippy
+/// for formatting and should therefore only be used in a normal clone of clippy
const REPO_GIT_DIR: &str = ".git";
const HOOK_SOURCE_FILE: &str = "util/etc/pre-commit.sh";
const HOOK_TARGET_FILE: &str = ".git/hooks/pre-commit";
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index e690bc369..837618c92 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -3,7 +3,7 @@ use aho_corasick::AhoCorasickBuilder;
use indoc::writedoc;
use itertools::Itertools;
use rustc_lexer::{tokenize, unescape, LiteralKind, TokenKind};
-use std::collections::{BTreeSet, HashMap, HashSet};
+use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;
use std::fmt::Write;
use std::fs::{self, OpenOptions};
@@ -36,6 +36,60 @@ pub enum UpdateMode {
pub fn update(update_mode: UpdateMode) {
let (lints, deprecated_lints, renamed_lints) = gather_all();
generate_lint_files(update_mode, &lints, &deprecated_lints, &renamed_lints);
+ remove_old_files(update_mode);
+}
+
+/// Remove files no longer needed after <https://github.com/rust-lang/rust-clippy/pull/9541>
+/// that may be reintroduced unintentionally
+///
+/// FIXME: This is a temporary measure that should be removed when there are no more PRs that
+/// include the stray files
+fn remove_old_files(update_mode: UpdateMode) {
+ let mut failed = false;
+ let mut remove_file = |path: &Path| match update_mode {
+ UpdateMode::Check => {
+ if path.exists() {
+ failed = true;
+ println!("unexpected file: {}", path.display());
+ }
+ },
+ UpdateMode::Change => {
+ if fs::remove_file(path).is_ok() {
+ println!("removed file: {}", path.display());
+ }
+ },
+ };
+
+ let files = [
+ "clippy_lints/src/lib.register_all.rs",
+ "clippy_lints/src/lib.register_cargo.rs",
+ "clippy_lints/src/lib.register_complexity.rs",
+ "clippy_lints/src/lib.register_correctness.rs",
+ "clippy_lints/src/lib.register_internal.rs",
+ "clippy_lints/src/lib.register_lints.rs",
+ "clippy_lints/src/lib.register_nursery.rs",
+ "clippy_lints/src/lib.register_pedantic.rs",
+ "clippy_lints/src/lib.register_perf.rs",
+ "clippy_lints/src/lib.register_restriction.rs",
+ "clippy_lints/src/lib.register_style.rs",
+ "clippy_lints/src/lib.register_suspicious.rs",
+ "src/docs.rs",
+ ];
+
+ for file in files {
+ remove_file(Path::new(file));
+ }
+
+ if let Ok(docs_dir) = fs::read_dir("src/docs") {
+ for doc_file in docs_dir {
+ let path = doc_file.unwrap().path();
+ remove_file(&path);
+ }
+ }
+
+ if failed {
+ exit_with_failure();
+ }
}
fn generate_lint_files(
@@ -104,9 +158,9 @@ fn generate_lint_files(
);
process_file(
- "clippy_lints/src/lib.register_lints.rs",
+ "clippy_lints/src/declared_lints.rs",
update_mode,
- &gen_register_lint_list(internal_lints.iter(), usable_lints.iter()),
+ &gen_declared_lints(internal_lints.iter(), usable_lints.iter()),
);
process_file(
"clippy_lints/src/lib.deprecated.rs",
@@ -114,26 +168,6 @@ fn generate_lint_files(
&gen_deprecated(deprecated_lints),
);
- let all_group_lints = usable_lints.iter().filter(|l| {
- matches!(
- &*l.group,
- "correctness" | "suspicious" | "style" | "complexity" | "perf"
- )
- });
- let content = gen_lint_group_list("all", all_group_lints);
- process_file("clippy_lints/src/lib.register_all.rs", update_mode, &content);
-
- update_docs(update_mode, &usable_lints);
-
- for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
- let content = gen_lint_group_list(&lint_group, lints.iter());
- process_file(
- format!("clippy_lints/src/lib.register_{lint_group}.rs"),
- update_mode,
- &content,
- );
- }
-
let content = gen_deprecated_lints_test(deprecated_lints);
process_file("tests/ui/deprecated.rs", update_mode, &content);
@@ -141,62 +175,6 @@ fn generate_lint_files(
process_file("tests/ui/rename.rs", update_mode, &content);
}
-fn update_docs(update_mode: UpdateMode, usable_lints: &[Lint]) {
- replace_region_in_file(update_mode, Path::new("src/docs.rs"), "docs! {\n", "\n}\n", |res| {
- for name in usable_lints.iter().map(|lint| lint.name.clone()).sorted() {
- writeln!(res, r#" "{name}","#).unwrap();
- }
- });
-
- if update_mode == UpdateMode::Check {
- let mut extra = BTreeSet::new();
- let mut lint_names = usable_lints
- .iter()
- .map(|lint| lint.name.clone())
- .collect::<BTreeSet<_>>();
- for file in std::fs::read_dir("src/docs").unwrap() {
- let filename = file.unwrap().file_name().into_string().unwrap();
- if let Some(name) = filename.strip_suffix(".txt") {
- if !lint_names.remove(name) {
- extra.insert(name.to_string());
- }
- }
- }
-
- let failed = print_lint_names("extra lint docs:", &extra) | print_lint_names("missing lint docs:", &lint_names);
-
- if failed {
- exit_with_failure();
- }
- } else {
- if std::fs::remove_dir_all("src/docs").is_err() {
- eprintln!("could not remove src/docs directory");
- }
- if std::fs::create_dir("src/docs").is_err() {
- eprintln!("could not recreate src/docs directory");
- }
- }
- for lint in usable_lints {
- process_file(
- Path::new("src/docs").join(lint.name.clone() + ".txt"),
- update_mode,
- &lint.documentation,
- );
- }
-}
-
-fn print_lint_names(header: &str, lints: &BTreeSet<String>) -> bool {
- if lints.is_empty() {
- return false;
- }
- println!("{header}");
- for lint in lints.iter().sorted() {
- println!(" {lint}");
- }
- println!();
- true
-}
-
pub fn print_lints() {
let (lint_list, _, _) = gather_all();
let usable_lints = Lint::usable_lints(&lint_list);
@@ -641,26 +619,17 @@ struct Lint {
desc: String,
module: String,
declaration_range: Range<usize>,
- documentation: String,
}
impl Lint {
#[must_use]
- fn new(
- name: &str,
- group: &str,
- desc: &str,
- module: &str,
- declaration_range: Range<usize>,
- documentation: String,
- ) -> Self {
+ fn new(name: &str, group: &str, desc: &str, module: &str, declaration_range: Range<usize>) -> Self {
Self {
name: name.to_lowercase(),
group: group.into(),
desc: remove_line_splices(desc),
module: module.into(),
declaration_range,
- documentation,
}
}
@@ -716,25 +685,6 @@ impl RenamedLint {
}
}
-/// Generates the code for registering a group
-fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lint>) -> String {
- let mut details: Vec<_> = lints.map(|l| (&l.module, l.name.to_uppercase())).collect();
- details.sort_unstable();
-
- let mut output = GENERATED_FILE_COMMENT.to_string();
-
- let _ = writeln!(
- output,
- "store.register_group(true, \"clippy::{group_name}\", Some(\"clippy_{group_name}\"), vec![",
- );
- for (module, name) in details {
- let _ = writeln!(output, " LintId::of({module}::{name}),");
- }
- output.push_str("])\n");
-
- output
-}
-
/// Generates the `register_removed` code
#[must_use]
fn gen_deprecated(lints: &[DeprecatedLint]) -> String {
@@ -759,7 +709,7 @@ fn gen_deprecated(lints: &[DeprecatedLint]) -> String {
/// Generates the code for registering lints
#[must_use]
-fn gen_register_lint_list<'a>(
+fn gen_declared_lints<'a>(
internal_lints: impl Iterator<Item = &'a Lint>,
usable_lints: impl Iterator<Item = &'a Lint>,
) -> String {
@@ -770,15 +720,15 @@ fn gen_register_lint_list<'a>(
details.sort_unstable();
let mut output = GENERATED_FILE_COMMENT.to_string();
- output.push_str("store.register_lints(&[\n");
+ output.push_str("pub(crate) static LINTS: &[&crate::LintInfo] = &[\n");
for (is_public, module_name, lint_name) in details {
if !is_public {
output.push_str(" #[cfg(feature = \"internal\")]\n");
}
- let _ = writeln!(output, " {module_name}::{lint_name},");
+ let _ = writeln!(output, " crate::{module_name}::{lint_name}_INFO,");
}
- output.push_str("])\n");
+ output.push_str("];\n");
output
}
@@ -910,35 +860,26 @@ fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
}| token_kind == &TokenKind::Ident && *content == "declare_clippy_lint",
) {
let start = range.start;
- let mut docs = String::with_capacity(128);
- let mut iter = iter.by_ref().filter(|t| !matches!(t.token_kind, TokenKind::Whitespace));
+ let mut iter = iter
+ .by_ref()
+ .filter(|t| !matches!(t.token_kind, TokenKind::Whitespace | TokenKind::LineComment { .. }));
// matches `!{`
match_tokens!(iter, Bang OpenBrace);
- let mut in_code = false;
- while let Some(t) = iter.next() {
- match t.token_kind {
- TokenKind::LineComment { .. } => {
- if let Some(line) = t.content.strip_prefix("/// ").or_else(|| t.content.strip_prefix("///")) {
- if line.starts_with("```") {
- docs += "```\n";
- in_code = !in_code;
- } else if !(in_code && line.starts_with("# ")) {
- docs += line;
- docs.push('\n');
- }
- }
- },
- TokenKind::Pound => {
- match_tokens!(iter, OpenBracket Ident Colon Colon Ident Eq Literal{..} CloseBracket Ident);
- break;
- },
- TokenKind::Ident => {
- break;
- },
- _ => {},
- }
+ match iter.next() {
+ // #[clippy::version = "version"] pub
+ Some(LintDeclSearchResult {
+ token_kind: TokenKind::Pound,
+ ..
+ }) => {
+ match_tokens!(iter, OpenBracket Ident Colon Colon Ident Eq Literal{..} CloseBracket Ident);
+ },
+ // pub
+ Some(LintDeclSearchResult {
+ token_kind: TokenKind::Ident,
+ ..
+ }) => (),
+ _ => continue,
}
- docs.pop(); // remove final newline
let (name, group, desc) = match_tokens!(
iter,
@@ -956,7 +897,7 @@ fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
..
}) = iter.next()
{
- lints.push(Lint::new(name, group, desc, module, start..range.end, docs));
+ lints.push(Lint::new(name, group, desc, module, start..range.end));
}
}
}
@@ -1186,7 +1127,6 @@ mod tests {
"\"really long text\"",
"module_name",
Range::default(),
- String::new(),
),
Lint::new(
"doc_markdown",
@@ -1194,7 +1134,6 @@ mod tests {
"\"single line\"",
"module_name",
Range::default(),
- String::new(),
),
];
assert_eq!(expected, result);
@@ -1234,7 +1173,6 @@ mod tests {
"\"abc\"",
"module_name",
Range::default(),
- String::new(),
),
Lint::new(
"should_assert_eq2",
@@ -1242,7 +1180,6 @@ mod tests {
"\"abc\"",
"module_name",
Range::default(),
- String::new(),
),
Lint::new(
"should_assert_eq2",
@@ -1250,7 +1187,6 @@ mod tests {
"\"abc\"",
"module_name",
Range::default(),
- String::new(),
),
];
let expected = vec![Lint::new(
@@ -1259,7 +1195,6 @@ mod tests {
"\"abc\"",
"module_name",
Range::default(),
- String::new(),
)];
assert_eq!(expected, Lint::usable_lints(&lints));
}
@@ -1267,51 +1202,22 @@ mod tests {
#[test]
fn test_by_lint_group() {
let lints = vec![
- Lint::new(
- "should_assert_eq",
- "group1",
- "\"abc\"",
- "module_name",
- Range::default(),
- String::new(),
- ),
+ Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
Lint::new(
"should_assert_eq2",
"group2",
"\"abc\"",
"module_name",
Range::default(),
- String::new(),
- ),
- Lint::new(
- "incorrect_match",
- "group1",
- "\"abc\"",
- "module_name",
- Range::default(),
- String::new(),
),
+ Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
];
let mut expected: HashMap<String, Vec<Lint>> = HashMap::new();
expected.insert(
"group1".to_string(),
vec![
- Lint::new(
- "should_assert_eq",
- "group1",
- "\"abc\"",
- "module_name",
- Range::default(),
- String::new(),
- ),
- Lint::new(
- "incorrect_match",
- "group1",
- "\"abc\"",
- "module_name",
- Range::default(),
- String::new(),
- ),
+ Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
+ Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
],
);
expected.insert(
@@ -1322,7 +1228,6 @@ mod tests {
"\"abc\"",
"module_name",
Range::default(),
- String::new(),
)],
);
assert_eq!(expected, Lint::by_lint_group(lints.into_iter()));
@@ -1357,48 +1262,4 @@ mod tests {
assert_eq!(expected, gen_deprecated(&lints));
}
-
- #[test]
- fn test_gen_lint_group_list() {
- let lints = vec![
- Lint::new(
- "abc",
- "group1",
- "\"abc\"",
- "module_name",
- Range::default(),
- String::new(),
- ),
- Lint::new(
- "should_assert_eq",
- "group1",
- "\"abc\"",
- "module_name",
- Range::default(),
- String::new(),
- ),
- Lint::new(
- "internal",
- "internal_style",
- "\"abc\"",
- "module_name",
- Range::default(),
- String::new(),
- ),
- ];
- let expected = GENERATED_FILE_COMMENT.to_string()
- + &[
- "store.register_group(true, \"clippy::group1\", Some(\"clippy_group1\"), vec![",
- " LintId::of(module_name::ABC),",
- " LintId::of(module_name::INTERNAL),",
- " LintId::of(module_name::SHOULD_ASSERT_EQ),",
- "])",
- ]
- .join("\n")
- + "\n";
-
- let result = gen_lint_group_list("group1", lints.iter());
-
- assert_eq!(expected, result);
- }
}
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index 6fbd6401e..aedff24c1 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.66"
+version = "0.1.67"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"
@@ -11,6 +11,7 @@ edition = "2021"
[dependencies]
cargo_metadata = "0.14"
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 }
diff --git a/src/tools/clippy/clippy_lints/src/almost_complete_letter_range.rs b/src/tools/clippy/clippy_lints/src/almost_complete_letter_range.rs
index 073e4af13..52beaf504 100644
--- a/src/tools/clippy/clippy_lints/src/almost_complete_letter_range.rs
+++ b/src/tools/clippy/clippy_lints/src/almost_complete_letter_range.rs
@@ -1,11 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{trim_span, walk_span_to_context};
-use clippy_utils::{meets_msrv, msrvs};
use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span;
@@ -33,10 +32,10 @@ declare_clippy_lint! {
impl_lint_pass!(AlmostCompleteLetterRange => [ALMOST_COMPLETE_LETTER_RANGE]);
pub struct AlmostCompleteLetterRange {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl AlmostCompleteLetterRange {
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -46,7 +45,7 @@ impl EarlyLintPass for AlmostCompleteLetterRange {
let ctxt = e.span.ctxt();
let sugg = if let Some(start) = walk_span_to_context(start.span, ctxt)
&& let Some(end) = walk_span_to_context(end.span, ctxt)
- && meets_msrv(self.msrv, msrvs::RANGE_INCLUSIVE)
+ && self.msrv.meets(msrvs::RANGE_INCLUSIVE)
{
Some((trim_span(cx.sess().source_map(), start.between(end)), "..="))
} else {
@@ -60,7 +59,7 @@ impl EarlyLintPass for AlmostCompleteLetterRange {
if let PatKind::Range(Some(start), Some(end), kind) = &p.kind
&& matches!(kind.node, RangeEnd::Excluded)
{
- let sugg = if meets_msrv(self.msrv, msrvs::RANGE_INCLUSIVE) {
+ let sugg = if self.msrv.meets(msrvs::RANGE_INCLUSIVE) {
"..="
} else {
"..."
@@ -73,12 +72,21 @@ impl EarlyLintPass for AlmostCompleteLetterRange {
}
fn check_range(cx: &EarlyContext<'_>, span: Span, start: &Expr, end: &Expr, sugg: Option<(Span, &str)>) {
- if let ExprKind::Lit(start_lit) = &start.peel_parens().kind
- && let ExprKind::Lit(end_lit) = &end.peel_parens().kind
+ if let ExprKind::Lit(start_token_lit) = start.peel_parens().kind
+ && let ExprKind::Lit(end_token_lit) = end.peel_parens().kind
&& matches!(
- (&start_lit.kind, &end_lit.kind),
- (LitKind::Byte(b'a') | LitKind::Char('a'), LitKind::Byte(b'z') | LitKind::Char('z'))
- | (LitKind::Byte(b'A') | LitKind::Char('A'), LitKind::Byte(b'Z') | LitKind::Char('Z'))
+ (
+ LitKind::from_token_lit(start_token_lit),
+ LitKind::from_token_lit(end_token_lit),
+ ),
+ (
+ Ok(LitKind::Byte(b'a') | LitKind::Char('a')),
+ Ok(LitKind::Byte(b'z') | LitKind::Char('z'))
+ )
+ | (
+ Ok(LitKind::Byte(b'A') | LitKind::Char('A')),
+ Ok(LitKind::Byte(b'Z') | LitKind::Char('Z')),
+ )
)
&& !in_external_macro(cx.sess(), span)
{
diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs
index 724490fb4..ccf82f132 100644
--- a/src/tools/clippy/clippy_lints/src/approx_const.rs
+++ b/src/tools/clippy/clippy_lints/src/approx_const.rs
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::{meets_msrv, msrvs};
+use clippy_utils::msrvs::{self, Msrv};
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
@@ -63,12 +63,12 @@ const KNOWN_CONSTS: [(f64, &str, usize, Option<RustcVersion>); 19] = [
];
pub struct ApproxConstant {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl ApproxConstant {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
@@ -87,7 +87,7 @@ impl ApproxConstant {
let s = s.as_str();
if s.parse::<f64>().is_ok() {
for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS {
- if is_approx_const(constant, s, min_digits) && msrv.map_or(true, |msrv| meets_msrv(self.msrv, msrv)) {
+ if is_approx_const(constant, s, min_digits) && msrv.map_or(true, |msrv| self.msrv.meets(msrv)) {
span_lint_and_help(
cx,
APPROX_CONSTANT,
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
index 0bd1f8b78..0710ac0bb 100644
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs.rs
@@ -2,23 +2,21 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::macros::{is_panic, macro_backtrace};
-use clippy_utils::msrvs;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
-use clippy_utils::{extract_msrv_attr, meets_msrv};
use if_chain::if_chain;
-use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
+use rustc_ast::{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,
};
-use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
+use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
-use rustc_span::sym;
use rustc_span::symbol::Symbol;
+use rustc_span::{sym, DUMMY_SP};
use semver::Version;
static UNIX_SYSTEMS: &[&str] = &[
@@ -303,6 +301,26 @@ declare_lint_pass!(Attributes => [
]);
impl<'tcx> LateLintPass<'tcx> for Attributes {
+ fn check_crate(&mut self, cx: &LateContext<'tcx>) {
+ for (name, level) in &cx.sess().opts.lint_opts {
+ if name == "clippy::restriction" && *level > Level::Allow {
+ span_lint_and_then(
+ cx,
+ BLANKET_CLIPPY_RESTRICTION_LINTS,
+ DUMMY_SP,
+ "`clippy::restriction` is not meant to be enabled as a group",
+ |diag| {
+ diag.note(format!(
+ "because of the command line `--{} clippy::restriction`",
+ level.as_str()
+ ));
+ diag.help("enable the restriction lints you need individually");
+ },
+ );
+ }
+ }
+ }
+
fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) {
if let Some(items) = &attr.meta_item_list() {
if let Some(ident) = attr.ident() {
@@ -358,7 +376,9 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
| "enum_glob_use"
| "redundant_pub_crate"
| "macro_use_imports"
- | "unsafe_removed_from_name",
+ | "unsafe_removed_from_name"
+ | "module_name_repetitions"
+ | "single_component_path_imports"
)
})
{
@@ -441,9 +461,9 @@ fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMe
cx,
BLANKET_CLIPPY_RESTRICTION_LINTS,
lint.span(),
- "restriction lints are not meant to be all enabled",
+ "`clippy::restriction` is not meant to be enabled as a group",
None,
- "try enabling only the lints you really need",
+ "enable the restriction lints you need individually",
);
}
}
@@ -464,6 +484,11 @@ fn check_lint_reason(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem
return;
}
+ // Check if the attribute is in an external macro and therefore out of the developer's control
+ if in_external_macro(cx.sess(), attr.span) {
+ return;
+ }
+
span_lint_and_help(
cx,
ALLOW_ATTRIBUTES_WITHOUT_REASON,
@@ -549,7 +574,7 @@ fn check_attrs(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribut
}
}
-fn check_semver(cx: &LateContext<'_>, span: Span, lit: &Lit) {
+fn check_semver(cx: &LateContext<'_>, span: Span, lit: &MetaItemLit) {
if let LitKind::Str(is, _) = lit.kind {
if Version::parse(is.as_str()).is_ok() {
return;
@@ -572,7 +597,7 @@ fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool {
}
pub struct EarlyAttributes {
- pub msrv: Option<RustcVersion>,
+ pub msrv: Msrv,
}
impl_lint_pass!(EarlyAttributes => [
@@ -587,7 +612,7 @@ impl EarlyLintPass for EarlyAttributes {
}
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
- check_deprecated_cfg_attr(cx, attr, self.msrv);
+ check_deprecated_cfg_attr(cx, attr, &self.msrv);
check_mismatched_target_os(cx, attr);
}
@@ -627,9 +652,9 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::It
}
}
-fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: Option<RustcVersion>) {
+fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &Msrv) {
if_chain! {
- if meets_msrv(msrv, msrvs::TOOL_ATTRIBUTES);
+ if msrv.meets(msrvs::TOOL_ATTRIBUTES);
// check cfg_attr
if attr.has_name(sym::cfg_attr);
if let Some(items) = attr.meta_item_list();
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 347178118..d40a38543 100644
--- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
+++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
@@ -1,7 +1,6 @@
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::{Namespace, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{AsyncGeneratorKind, Body, BodyId, GeneratorKind};
use rustc_lint::{LateContext, LateLintPass};
@@ -189,7 +188,7 @@ impl LateLintPass<'_> for AwaitHolding {
fn check_crate(&mut self, cx: &LateContext<'_>) {
for conf in &self.conf_invalid_types {
let segs: Vec<_> = conf.path().split("::").collect();
- if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, Some(Namespace::TypeNS)) {
+ for id in clippy_utils::def_path_def_ids(cx, &segs) {
self.def_ids.insert(id, conf.clone());
}
}
diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
index 4bd55c142..82d368bb8 100644
--- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
+++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
@@ -59,7 +59,7 @@ fn is_impl_not_trait_with_bool_out(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
)
})
.map_or(false, |assoc_item| {
- let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, &[]));
+ let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, []));
let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj);
nty.is_bool()
diff --git a/src/tools/clippy/clippy_lints/src/bool_to_int_with_if.rs b/src/tools/clippy/clippy_lints/src/bool_to_int_with_if.rs
index 001d74c26..bdb3a0116 100644
--- a/src/tools/clippy/clippy_lints/src/bool_to_int_with_if.rs
+++ b/src/tools/clippy/clippy_lints/src/bool_to_int_with_if.rs
@@ -1,9 +1,10 @@
+use clippy_utils::higher::If;
use rustc_ast::LitKind;
use rustc_hir::{Block, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
-use clippy_utils::{diagnostics::span_lint_and_then, is_else_clause, is_integer_literal, sugg::Sugg};
+use clippy_utils::{diagnostics::span_lint_and_then, in_constant, is_else_clause, is_integer_literal, sugg::Sugg};
use rustc_errors::Applicability;
declare_clippy_lint! {
@@ -12,7 +13,7 @@ declare_clippy_lint! {
/// this lint suggests using a `from()` function or an `as` coercion.
///
/// ### Why is this bad?
- /// Coercion or `from()` is idiomatic way to convert bool to a number.
+ /// Coercion or `from()` is another way to convert bool to a number.
/// Both methods are guaranteed to return 1 for true, and 0 for false.
///
/// See https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E
@@ -38,23 +39,23 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "1.65.0"]
pub BOOL_TO_INT_WITH_IF,
- style,
+ pedantic,
"using if to convert bool to int"
}
declare_lint_pass!(BoolToIntWithIf => [BOOL_TO_INT_WITH_IF]);
impl<'tcx> LateLintPass<'tcx> for BoolToIntWithIf {
- fn check_expr(&mut self, ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
- if !expr.span.from_expansion() {
- check_if_else(ctx, expr);
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+ if !expr.span.from_expansion() && !in_constant(cx, expr.hir_id) {
+ check_if_else(cx, expr);
}
}
}
-fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
- if let ExprKind::If(check, then, Some(else_)) = expr.kind
+fn check_if_else<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+ if let Some(If { cond, then, r#else: Some(r#else) }) = If::hir(expr)
&& let Some(then_lit) = int_literal(then)
- && let Some(else_lit) = int_literal(else_)
+ && let Some(else_lit) = int_literal(r#else)
{
let inverted = if is_integer_literal(then_lit, 1) && is_integer_literal(else_lit, 0) {
false
@@ -66,17 +67,17 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
};
let mut applicability = Applicability::MachineApplicable;
let snippet = {
- let mut sugg = Sugg::hir_with_applicability(ctx, check, "..", &mut applicability);
+ let mut sugg = Sugg::hir_with_applicability(cx, cond, "..", &mut applicability);
if inverted {
sugg = !sugg;
}
sugg
};
- let ty = ctx.typeck_results().expr_ty(then_lit); // then and else must be of same type
+ let ty = cx.typeck_results().expr_ty(then_lit); // then and else must be of same type
let suggestion = {
- let wrap_in_curly = is_else_clause(ctx.tcx, expr);
+ let wrap_in_curly = is_else_clause(cx.tcx, expr);
let mut s = Sugg::NonParen(format!("{ty}::from({snippet})").into());
if wrap_in_curly {
s = s.blockify();
@@ -87,7 +88,7 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
let into_snippet = snippet.clone().maybe_par();
let as_snippet = snippet.as_ty(ty);
- span_lint_and_then(ctx,
+ span_lint_and_then(cx,
BOOL_TO_INT_WITH_IF,
expr.span,
"boolean to int conversion using if",
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index 08164c0b6..939bdbcdc 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -481,7 +481,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
}
}
-fn implements_ord<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> bool {
+fn implements_ord(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
let ty = cx.typeck_results().expr_ty(expr);
cx.tcx
.get_diagnostic_item(sym::Ord)
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
index 3f1edabe6..442262983 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
@@ -1,11 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::sugg::Sugg;
-use clippy_utils::{meets_msrv, msrvs};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};
-use rustc_semver::RustcVersion;
use super::CAST_ABS_TO_UNSIGNED;
@@ -15,9 +14,9 @@ pub(super) fn check(
cast_expr: &Expr<'_>,
cast_from: Ty<'_>,
cast_to: Ty<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) {
- if meets_msrv(msrv, msrvs::UNSIGNED_ABS)
+ if msrv.meets(msrvs::UNSIGNED_ABS)
&& let ty::Int(from) = cast_from.kind()
&& let ty::Uint(to) = cast_to.kind()
&& let ExprKind::MethodCall(method_path, receiver, ..) = cast_expr.kind
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 13c403234..cf07e050c 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
@@ -1,12 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::in_constant;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::is_isize_or_usize;
-use clippy_utils::{in_constant, meets_msrv, msrvs};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, FloatTy, Ty};
-use rustc_semver::RustcVersion;
use super::{utils, CAST_LOSSLESS};
@@ -16,7 +16,7 @@ pub(super) fn check(
cast_op: &Expr<'_>,
cast_from: Ty<'_>,
cast_to: Ty<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) {
if !should_lint(cx, expr, cast_from, cast_to, msrv) {
return;
@@ -57,13 +57,7 @@ pub(super) fn check(
);
}
-fn should_lint(
- cx: &LateContext<'_>,
- expr: &Expr<'_>,
- cast_from: Ty<'_>,
- cast_to: Ty<'_>,
- msrv: Option<RustcVersion>,
-) -> bool {
+fn should_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>, msrv: &Msrv) -> bool {
// Do not suggest using From in consts/statics until it is valid to do so (see #2267).
if in_constant(cx, expr.hir_id) {
return false;
@@ -89,7 +83,7 @@ fn should_lint(
};
!is_isize_or_usize(cast_from) && from_nbits < to_nbits
},
- (false, true) if matches!(cast_from.kind(), ty::Bool) && meets_msrv(msrv, msrvs::FROM_BOOL) => true,
+ (false, true) if matches!(cast_from.kind(), ty::Bool) && msrv.meets(msrvs::FROM_BOOL) => true,
(_, _) => {
matches!(cast_from.kind(), ty::Float(FloatTy::F32)) && matches!(cast_to.kind(), ty::Float(FloatTy::F64))
},
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 88deb4565..a63764849 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
@@ -2,12 +2,11 @@ use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::expr_or_init;
use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
-use rustc_ast::ast;
-use rustc_attr::IntType;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, FloatTy, Ty};
+use rustc_target::abi::IntegerType;
use super::{utils, CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION};
@@ -119,12 +118,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
};
let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx);
- let cast_from_ptr_size = def.repr().int.map_or(true, |ty| {
- matches!(
- ty,
- IntType::SignedInt(ast::IntTy::Isize) | IntType::UnsignedInt(ast::UintTy::Usize)
- )
- });
+ let cast_from_ptr_size = def.repr().int.map_or(true, |ty| matches!(ty, IntegerType::Pointer(_),));
let suffix = match (cast_from_ptr_size, is_isize_or_usize(cast_to)) {
(false, false) if from_nbits > to_nbits => "",
(true, false) if from_nbits > to_nbits => "",
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
index d31d10d22..e862f13e6 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
@@ -1,16 +1,16 @@
-use clippy_utils::{diagnostics::span_lint_and_then, meets_msrv, msrvs, source};
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::{diagnostics::span_lint_and_then, source};
use if_chain::if_chain;
use rustc_ast::Mutability;
use rustc_hir::{Expr, ExprKind, Node};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, layout::LayoutOf, Ty, TypeAndMut};
-use rustc_semver::RustcVersion;
use super::CAST_SLICE_DIFFERENT_SIZES;
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: Option<RustcVersion>) {
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv) {
// suggestion is invalid if `ptr::slice_from_raw_parts` does not exist
- if !meets_msrv(msrv, msrvs::PTR_SLICE_RAW_PARTS) {
+ if !msrv.meets(msrvs::PTR_SLICE_RAW_PARTS) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
index 284ef1659..627b795d6 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
@@ -1,12 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{match_def_path, meets_msrv, msrvs, paths};
+use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{def_id::DefId, Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};
-use rustc_semver::RustcVersion;
use super::CAST_SLICE_FROM_RAW_PARTS;
@@ -25,15 +25,9 @@ fn raw_parts_kind(cx: &LateContext<'_>, did: DefId) -> Option<RawPartsKind> {
}
}
-pub(super) fn check(
- cx: &LateContext<'_>,
- expr: &Expr<'_>,
- cast_expr: &Expr<'_>,
- cast_to: Ty<'_>,
- msrv: Option<RustcVersion>,
-) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>, msrv: &Msrv) {
if_chain! {
- if meets_msrv(msrv, msrvs::PTR_SLICE_RAW_PARTS);
+ if msrv.meets(msrvs::PTR_SLICE_RAW_PARTS);
if let ty::RawPtr(ptrty) = cast_to.kind();
if let ty::Slice(_) = ptrty.ty.kind();
if let ExprKind::Call(fun, [ptr_arg, len_arg]) = cast_expr.peel_blocks().kind;
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index b72c4c772..c6d505c4a 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -21,11 +21,11 @@ mod ptr_as_ptr;
mod unnecessary_cast;
mod utils;
-use clippy_utils::{is_hir_ty_cfg_dependant, meets_msrv, msrvs};
+use clippy_utils::is_hir_ty_cfg_dependant;
+use clippy_utils::msrvs::{self, Msrv};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! {
@@ -593,7 +593,7 @@ declare_clippy_lint! {
/// let _: *mut [u8] = std::ptr::slice_from_raw_parts_mut(ptr, len);
/// ```
/// [safety requirements]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety
- #[clippy::version = "1.64.0"]
+ #[clippy::version = "1.65.0"]
pub CAST_SLICE_FROM_RAW_PARTS,
suspicious,
"casting a slice created from a pointer and length to a slice pointer"
@@ -648,12 +648,12 @@ declare_clippy_lint! {
}
pub struct Casts {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl Casts {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -686,7 +686,7 @@ impl_lint_pass!(Casts => [
impl<'tcx> LateLintPass<'tcx> for Casts {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if !in_external_macro(cx.sess(), expr.span) {
- ptr_as_ptr::check(cx, expr, self.msrv);
+ ptr_as_ptr::check(cx, expr, &self.msrv);
}
if expr.span.from_expansion() {
@@ -705,7 +705,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) {
return;
}
- cast_slice_from_raw_parts::check(cx, expr, cast_expr, cast_to, self.msrv);
+ cast_slice_from_raw_parts::check(cx, expr, cast_expr, cast_to, &self.msrv);
as_ptr_cast_mut::check(cx, expr, cast_expr, cast_to);
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);
@@ -717,16 +717,16 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
cast_possible_wrap::check(cx, expr, cast_from, cast_to);
cast_precision_loss::check(cx, expr, cast_from, cast_to);
cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to);
- cast_abs_to_unsigned::check(cx, expr, cast_expr, cast_from, cast_to, self.msrv);
+ cast_abs_to_unsigned::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv);
cast_nan_to_int::check(cx, expr, cast_expr, cast_from, cast_to);
}
- cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to, self.msrv);
+ cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv);
cast_enum_constructor::check(cx, expr, cast_expr, cast_from);
}
as_underscore::check(cx, expr, cast_to_hir);
- if meets_msrv(self.msrv, msrvs::BORROW_AS_PTR) {
+ if self.msrv.meets(msrvs::BORROW_AS_PTR) {
borrow_as_ptr::check(cx, expr, cast_expr, cast_to_hir);
}
}
@@ -734,8 +734,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
cast_ref_to_mut::check(cx, expr);
cast_ptr_alignment::check(cx, expr);
char_lit_as_u8::check(cx, expr);
- ptr_as_ptr::check(cx, expr, self.msrv);
- cast_slice_different_sizes::check(cx, expr, self.msrv);
+ ptr_as_ptr::check(cx, expr, &self.msrv);
+ cast_slice_different_sizes::check(cx, expr, &self.msrv);
}
extract_msrv_attr!(LateContext);
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
index b9509ca65..15ffb00da 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
@@ -1,19 +1,18 @@
use std::borrow::Cow;
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::sugg::Sugg;
-use clippy_utils::{meets_msrv, msrvs};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Mutability, TyKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, TypeAndMut};
-use rustc_semver::RustcVersion;
use super::PTR_AS_PTR;
-pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Option<RustcVersion>) {
- if !meets_msrv(msrv, msrvs::POINTER_CAST) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
+ if !msrv.meets(msrvs::POINTER_CAST) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index c8596987e..7e2331807 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::get_parent_expr;
use clippy_utils::numeric_literal::NumericLiteral;
use clippy_utils::source::snippet_opt;
+use clippy_utils::{get_parent_expr, path_to_local};
use if_chain::if_chain;
use rustc_ast::{LitFloatType, LitIntType, LitKind};
use rustc_errors::Applicability;
@@ -75,13 +75,26 @@ pub(super) fn check<'tcx>(
}
if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) {
+ if let Some(id) = path_to_local(cast_expr)
+ && let Some(span) = cx.tcx.hir().opt_span(id)
+ && span.ctxt() != cast_expr.span.ctxt()
+ {
+ // Binding context is different than the identifiers context.
+ // Weird macro wizardry could be involved here.
+ return false;
+ }
+
span_lint_and_sugg(
cx,
UNNECESSARY_CAST,
expr.span,
&format!("casting to the same type is unnecessary (`{cast_from}` -> `{cast_to}`)"),
"try",
- cast_str,
+ if get_parent_expr(cx, expr).map_or(false, |e| matches!(e.kind, ExprKind::AddrOf(..))) {
+ format!("{{ {cast_str} }}")
+ } else {
+ cast_str
+ },
Applicability::MachineApplicable,
);
return true;
diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
index 78e9921f0..9102a89e3 100644
--- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
@@ -1,14 +1,14 @@
//! lint on manually implemented checked conversions that could be transformed into `try_from`
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{in_constant, is_integer_literal, meets_msrv, msrvs, SpanlessEq};
+use clippy_utils::{in_constant, is_integer_literal, SpanlessEq};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! {
@@ -37,12 +37,12 @@ declare_clippy_lint! {
}
pub struct CheckedConversions {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl CheckedConversions {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -51,7 +51,7 @@ impl_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]);
impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
- if !meets_msrv(self.msrv, msrvs::TRY_FROM) {
+ if !self.msrv.meets(msrvs::TRY_FROM) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index 77af3b53d..1c3a89a97 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -4,11 +4,11 @@ use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::visitors::for_each_expr;
-use clippy_utils::LimitStack;
+use clippy_utils::{get_async_fn_body, is_async_fn, LimitStack};
use core::ops::ControlFlow;
use rustc_ast::ast::Attribute;
use rustc_hir::intravisit::FnKind;
-use rustc_hir::{Body, ExprKind, FnDecl, HirId};
+use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
@@ -56,15 +56,13 @@ impl CognitiveComplexity {
cx: &LateContext<'tcx>,
kind: FnKind<'tcx>,
decl: &'tcx FnDecl<'_>,
- body: &'tcx Body<'_>,
+ expr: &'tcx Expr<'_>,
body_span: Span,
) {
if body_span.from_expansion() {
return;
}
- let expr = body.value;
-
let mut cc = 1u64;
let mut returns = 0u64;
let _: Option<!> = for_each_expr(expr, |e| {
@@ -146,7 +144,18 @@ impl<'tcx> LateLintPass<'tcx> for CognitiveComplexity {
) {
let def_id = cx.tcx.hir().local_def_id(hir_id);
if !cx.tcx.has_attr(def_id.to_def_id(), sym::test) {
- self.check(cx, kind, decl, body, span);
+ let expr = if is_async_fn(kind) {
+ match get_async_fn_body(cx.tcx, body) {
+ Some(b) => b,
+ None => {
+ return;
+ },
+ }
+ } else {
+ body.value
+ };
+
+ self.check(cx, kind, decl, expr, span);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/collapsible_if.rs b/src/tools/clippy/clippy_lints/src/collapsible_if.rs
index 90430b71a..b38e09dc0 100644
--- a/src/tools/clippy/clippy_lints/src/collapsible_if.rs
+++ b/src/tools/clippy/clippy_lints/src/collapsible_if.rs
@@ -160,11 +160,13 @@ fn check_collapsible_no_if_let(cx: &EarlyContext<'_>, expr: &ast::Expr, check: &
if let ast::ExprKind::If(ref check_inner, ref content, None) = inner.kind;
// Prevent triggering on `if c { if let a = b { .. } }`.
if !matches!(check_inner.kind, ast::ExprKind::Let(..));
- if expr.span.ctxt() == inner.span.ctxt();
+ let ctxt = expr.span.ctxt();
+ if inner.span.ctxt() == ctxt;
then {
span_lint_and_then(cx, COLLAPSIBLE_IF, expr.span, "this `if` statement can be collapsed", |diag| {
- let lhs = Sugg::ast(cx, check, "..");
- let rhs = Sugg::ast(cx, check_inner, "..");
+ let mut app = Applicability::MachineApplicable;
+ let lhs = Sugg::ast(cx, check, "..", ctxt, &mut app);
+ let rhs = Sugg::ast(cx, check_inner, "..", ctxt, &mut app);
diag.span_suggestion(
expr.span,
"collapse nested if block",
@@ -173,7 +175,7 @@ fn check_collapsible_no_if_let(cx: &EarlyContext<'_>, expr: &ast::Expr, check: &
lhs.and(&rhs),
snippet_block(cx, content.span, "..", Some(expr.span)),
),
- Applicability::MachineApplicable, // snippet
+ app, // snippet
);
});
}
diff --git a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
index 20cc330e0..b2fe0386f 100644
--- a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
+++ b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
@@ -55,7 +55,7 @@ impl EarlyLintPass for CrateInMacroDef {
if_chain! {
if item.attrs.iter().any(is_macro_export);
if let ItemKind::MacroDef(macro_def) = &item.kind;
- let tts = macro_def.body.inner_tokens();
+ let tts = macro_def.body.tokens.clone();
if let Some(span) = contains_unhygienic_crate_reference(&tts);
then {
span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
new file mode 100644
index 000000000..e4d76f07d
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -0,0 +1,630 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+pub(crate) static LINTS: &[&crate::LintInfo] = &[
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::clippy_lints_internal::CLIPPY_LINTS_INTERNAL_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::compiler_lint_functions::COMPILER_LINT_FUNCTIONS_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::if_chain_style::IF_CHAIN_STYLE_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::interning_defined_symbol::INTERNING_DEFINED_SYMBOL_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::interning_defined_symbol::UNNECESSARY_SYMBOL_STR_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::invalid_paths::INVALID_PATHS_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::lint_without_lint_pass::DEFAULT_DEPRECATION_REASON_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::lint_without_lint_pass::DEFAULT_LINT_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::lint_without_lint_pass::INVALID_CLIPPY_VERSION_ATTRIBUTE_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::lint_without_lint_pass::LINT_WITHOUT_LINT_PASS_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::msrv_attr_impl::MISSING_MSRV_ATTR_IMPL_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::outer_expn_data_pass::OUTER_EXPN_EXPN_DATA_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::produce_ice::PRODUCE_ICE_INFO,
+ #[cfg(feature = "internal")]
+ crate::utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH_INFO,
+ crate::almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE_INFO,
+ crate::approx_const::APPROX_CONSTANT_INFO,
+ crate::as_conversions::AS_CONVERSIONS_INFO,
+ crate::asm_syntax::INLINE_ASM_X86_ATT_SYNTAX_INFO,
+ crate::asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX_INFO,
+ crate::assertions_on_constants::ASSERTIONS_ON_CONSTANTS_INFO,
+ crate::assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES_INFO,
+ crate::async_yields_async::ASYNC_YIELDS_ASYNC_INFO,
+ crate::attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON_INFO,
+ crate::attrs::BLANKET_CLIPPY_RESTRICTION_LINTS_INFO,
+ crate::attrs::DEPRECATED_CFG_ATTR_INFO,
+ crate::attrs::DEPRECATED_SEMVER_INFO,
+ crate::attrs::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,
+ crate::attrs::INLINE_ALWAYS_INFO,
+ crate::attrs::MISMATCHED_TARGET_OS_INFO,
+ crate::attrs::USELESS_ATTRIBUTE_INFO,
+ crate::await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE_INFO,
+ crate::await_holding_invalid::AWAIT_HOLDING_LOCK_INFO,
+ crate::await_holding_invalid::AWAIT_HOLDING_REFCELL_REF_INFO,
+ crate::blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS_INFO,
+ crate::bool_assert_comparison::BOOL_ASSERT_COMPARISON_INFO,
+ crate::bool_to_int_with_if::BOOL_TO_INT_WITH_IF_INFO,
+ crate::booleans::NONMINIMAL_BOOL_INFO,
+ crate::booleans::OVERLY_COMPLEX_BOOL_EXPR_INFO,
+ crate::borrow_deref_ref::BORROW_DEREF_REF_INFO,
+ crate::box_default::BOX_DEFAULT_INFO,
+ crate::cargo::CARGO_COMMON_METADATA_INFO,
+ crate::cargo::MULTIPLE_CRATE_VERSIONS_INFO,
+ crate::cargo::NEGATIVE_FEATURE_NAMES_INFO,
+ crate::cargo::REDUNDANT_FEATURE_NAMES_INFO,
+ crate::cargo::WILDCARD_DEPENDENCIES_INFO,
+ crate::casts::AS_PTR_CAST_MUT_INFO,
+ crate::casts::AS_UNDERSCORE_INFO,
+ crate::casts::BORROW_AS_PTR_INFO,
+ crate::casts::CAST_ABS_TO_UNSIGNED_INFO,
+ crate::casts::CAST_ENUM_CONSTRUCTOR_INFO,
+ crate::casts::CAST_ENUM_TRUNCATION_INFO,
+ crate::casts::CAST_LOSSLESS_INFO,
+ crate::casts::CAST_NAN_TO_INT_INFO,
+ crate::casts::CAST_POSSIBLE_TRUNCATION_INFO,
+ crate::casts::CAST_POSSIBLE_WRAP_INFO,
+ crate::casts::CAST_PRECISION_LOSS_INFO,
+ crate::casts::CAST_PTR_ALIGNMENT_INFO,
+ crate::casts::CAST_REF_TO_MUT_INFO,
+ crate::casts::CAST_SIGN_LOSS_INFO,
+ crate::casts::CAST_SLICE_DIFFERENT_SIZES_INFO,
+ crate::casts::CAST_SLICE_FROM_RAW_PARTS_INFO,
+ crate::casts::CHAR_LIT_AS_U8_INFO,
+ crate::casts::FN_TO_NUMERIC_CAST_INFO,
+ crate::casts::FN_TO_NUMERIC_CAST_ANY_INFO,
+ crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO,
+ crate::casts::PTR_AS_PTR_INFO,
+ crate::casts::UNNECESSARY_CAST_INFO,
+ crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
+ crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO,
+ crate::collapsible_if::COLLAPSIBLE_ELSE_IF_INFO,
+ crate::collapsible_if::COLLAPSIBLE_IF_INFO,
+ crate::comparison_chain::COMPARISON_CHAIN_INFO,
+ crate::copies::BRANCHES_SHARING_CODE_INFO,
+ crate::copies::IFS_SAME_COND_INFO,
+ crate::copies::IF_SAME_THEN_ELSE_INFO,
+ crate::copies::SAME_FUNCTIONS_IN_IF_CONDITION_INFO,
+ crate::copy_iterator::COPY_ITERATOR_INFO,
+ crate::crate_in_macro_def::CRATE_IN_MACRO_DEF_INFO,
+ crate::create_dir::CREATE_DIR_INFO,
+ crate::dbg_macro::DBG_MACRO_INFO,
+ crate::default::DEFAULT_TRAIT_ACCESS_INFO,
+ crate::default::FIELD_REASSIGN_WITH_DEFAULT_INFO,
+ crate::default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY_INFO,
+ crate::default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK_INFO,
+ crate::default_union_representation::DEFAULT_UNION_REPRESENTATION_INFO,
+ crate::dereference::EXPLICIT_AUTO_DEREF_INFO,
+ crate::dereference::EXPLICIT_DEREF_METHODS_INFO,
+ crate::dereference::NEEDLESS_BORROW_INFO,
+ crate::dereference::REF_BINDING_TO_REFERENCE_INFO,
+ crate::derivable_impls::DERIVABLE_IMPLS_INFO,
+ crate::derive::DERIVE_HASH_XOR_EQ_INFO,
+ crate::derive::DERIVE_ORD_XOR_PARTIAL_ORD_INFO,
+ crate::derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ_INFO,
+ crate::derive::EXPL_IMPL_CLONE_ON_COPY_INFO,
+ crate::derive::UNSAFE_DERIVE_DESERIALIZE_INFO,
+ crate::disallowed_macros::DISALLOWED_MACROS_INFO,
+ crate::disallowed_methods::DISALLOWED_METHODS_INFO,
+ crate::disallowed_names::DISALLOWED_NAMES_INFO,
+ crate::disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS_INFO,
+ crate::disallowed_types::DISALLOWED_TYPES_INFO,
+ crate::doc::DOC_LINK_WITH_QUOTES_INFO,
+ crate::doc::DOC_MARKDOWN_INFO,
+ crate::doc::MISSING_ERRORS_DOC_INFO,
+ crate::doc::MISSING_PANICS_DOC_INFO,
+ crate::doc::MISSING_SAFETY_DOC_INFO,
+ crate::doc::NEEDLESS_DOCTEST_MAIN_INFO,
+ crate::doc::UNNECESSARY_SAFETY_DOC_INFO,
+ crate::double_parens::DOUBLE_PARENS_INFO,
+ crate::drop_forget_ref::DROP_COPY_INFO,
+ crate::drop_forget_ref::DROP_NON_DROP_INFO,
+ crate::drop_forget_ref::DROP_REF_INFO,
+ crate::drop_forget_ref::FORGET_COPY_INFO,
+ crate::drop_forget_ref::FORGET_NON_DROP_INFO,
+ crate::drop_forget_ref::FORGET_REF_INFO,
+ crate::drop_forget_ref::UNDROPPED_MANUALLY_DROPS_INFO,
+ crate::duplicate_mod::DUPLICATE_MOD_INFO,
+ crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO,
+ crate::empty_drop::EMPTY_DROP_INFO,
+ crate::empty_enum::EMPTY_ENUM_INFO,
+ crate::empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS_INFO,
+ crate::entry::MAP_ENTRY_INFO,
+ crate::enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT_INFO,
+ crate::enum_variants::ENUM_VARIANT_NAMES_INFO,
+ crate::enum_variants::MODULE_INCEPTION_INFO,
+ crate::enum_variants::MODULE_NAME_REPETITIONS_INFO,
+ crate::equatable_if_let::EQUATABLE_IF_LET_INFO,
+ crate::escape::BOXED_LOCAL_INFO,
+ crate::eta_reduction::REDUNDANT_CLOSURE_INFO,
+ crate::eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS_INFO,
+ crate::excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS_INFO,
+ crate::excessive_bools::STRUCT_EXCESSIVE_BOOLS_INFO,
+ crate::exhaustive_items::EXHAUSTIVE_ENUMS_INFO,
+ crate::exhaustive_items::EXHAUSTIVE_STRUCTS_INFO,
+ crate::exit::EXIT_INFO,
+ crate::explicit_write::EXPLICIT_WRITE_INFO,
+ crate::fallible_impl_from::FALLIBLE_IMPL_FROM_INFO,
+ crate::float_literal::EXCESSIVE_PRECISION_INFO,
+ crate::float_literal::LOSSY_FLOAT_LITERAL_INFO,
+ crate::floating_point_arithmetic::IMPRECISE_FLOPS_INFO,
+ crate::floating_point_arithmetic::SUBOPTIMAL_FLOPS_INFO,
+ crate::format::USELESS_FORMAT_INFO,
+ crate::format_args::FORMAT_IN_FORMAT_ARGS_INFO,
+ crate::format_args::TO_STRING_IN_FORMAT_ARGS_INFO,
+ crate::format_args::UNINLINED_FORMAT_ARGS_INFO,
+ crate::format_args::UNUSED_FORMAT_SPECS_INFO,
+ crate::format_impl::PRINT_IN_FORMAT_IMPL_INFO,
+ crate::format_impl::RECURSIVE_FORMAT_IMPL_INFO,
+ crate::format_push_string::FORMAT_PUSH_STRING_INFO,
+ crate::formatting::POSSIBLE_MISSING_COMMA_INFO,
+ crate::formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING_INFO,
+ crate::formatting::SUSPICIOUS_ELSE_FORMATTING_INFO,
+ crate::formatting::SUSPICIOUS_UNARY_OP_FORMATTING_INFO,
+ crate::from_over_into::FROM_OVER_INTO_INFO,
+ crate::from_raw_with_void_ptr::FROM_RAW_WITH_VOID_PTR_INFO,
+ crate::from_str_radix_10::FROM_STR_RADIX_10_INFO,
+ crate::functions::DOUBLE_MUST_USE_INFO,
+ crate::functions::MISNAMED_GETTERS_INFO,
+ crate::functions::MUST_USE_CANDIDATE_INFO,
+ crate::functions::MUST_USE_UNIT_INFO,
+ crate::functions::NOT_UNSAFE_PTR_ARG_DEREF_INFO,
+ crate::functions::RESULT_LARGE_ERR_INFO,
+ crate::functions::RESULT_UNIT_ERR_INFO,
+ crate::functions::TOO_MANY_ARGUMENTS_INFO,
+ crate::functions::TOO_MANY_LINES_INFO,
+ crate::future_not_send::FUTURE_NOT_SEND_INFO,
+ crate::if_let_mutex::IF_LET_MUTEX_INFO,
+ crate::if_not_else::IF_NOT_ELSE_INFO,
+ crate::if_then_some_else_none::IF_THEN_SOME_ELSE_NONE_INFO,
+ crate::implicit_hasher::IMPLICIT_HASHER_INFO,
+ crate::implicit_return::IMPLICIT_RETURN_INFO,
+ crate::implicit_saturating_add::IMPLICIT_SATURATING_ADD_INFO,
+ crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO,
+ crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO,
+ crate::index_refutable_slice::INDEX_REFUTABLE_SLICE_INFO,
+ crate::indexing_slicing::INDEXING_SLICING_INFO,
+ crate::indexing_slicing::OUT_OF_BOUNDS_INDEXING_INFO,
+ crate::infinite_iter::INFINITE_ITER_INFO,
+ crate::infinite_iter::MAYBE_INFINITE_ITER_INFO,
+ crate::inherent_impl::MULTIPLE_INHERENT_IMPL_INFO,
+ crate::inherent_to_string::INHERENT_TO_STRING_INFO,
+ crate::inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY_INFO,
+ crate::init_numbered_fields::INIT_NUMBERED_FIELDS_INFO,
+ crate::inline_fn_without_body::INLINE_FN_WITHOUT_BODY_INFO,
+ crate::instant_subtraction::MANUAL_INSTANT_ELAPSED_INFO,
+ crate::instant_subtraction::UNCHECKED_DURATION_SUBTRACTION_INFO,
+ crate::int_plus_one::INT_PLUS_ONE_INFO,
+ crate::invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS_INFO,
+ crate::invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED_INFO,
+ crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO,
+ crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO,
+ crate::large_const_arrays::LARGE_CONST_ARRAYS_INFO,
+ crate::large_enum_variant::LARGE_ENUM_VARIANT_INFO,
+ crate::large_include_file::LARGE_INCLUDE_FILE_INFO,
+ crate::large_stack_arrays::LARGE_STACK_ARRAYS_INFO,
+ crate::len_zero::COMPARISON_TO_EMPTY_INFO,
+ crate::len_zero::LEN_WITHOUT_IS_EMPTY_INFO,
+ crate::len_zero::LEN_ZERO_INFO,
+ crate::let_if_seq::USELESS_LET_IF_SEQ_INFO,
+ crate::let_underscore::LET_UNDERSCORE_FUTURE_INFO,
+ crate::let_underscore::LET_UNDERSCORE_LOCK_INFO,
+ crate::let_underscore::LET_UNDERSCORE_MUST_USE_INFO,
+ crate::lifetimes::EXTRA_UNUSED_LIFETIMES_INFO,
+ crate::lifetimes::NEEDLESS_LIFETIMES_INFO,
+ crate::literal_representation::DECIMAL_LITERAL_REPRESENTATION_INFO,
+ crate::literal_representation::INCONSISTENT_DIGIT_GROUPING_INFO,
+ crate::literal_representation::LARGE_DIGIT_GROUPS_INFO,
+ crate::literal_representation::MISTYPED_LITERAL_SUFFIXES_INFO,
+ crate::literal_representation::UNREADABLE_LITERAL_INFO,
+ crate::literal_representation::UNUSUAL_BYTE_GROUPINGS_INFO,
+ crate::loops::EMPTY_LOOP_INFO,
+ crate::loops::EXPLICIT_COUNTER_LOOP_INFO,
+ crate::loops::EXPLICIT_INTO_ITER_LOOP_INFO,
+ crate::loops::EXPLICIT_ITER_LOOP_INFO,
+ crate::loops::FOR_KV_MAP_INFO,
+ crate::loops::ITER_NEXT_LOOP_INFO,
+ crate::loops::MANUAL_FIND_INFO,
+ crate::loops::MANUAL_FLATTEN_INFO,
+ crate::loops::MANUAL_MEMCPY_INFO,
+ crate::loops::MISSING_SPIN_LOOP_INFO,
+ crate::loops::MUT_RANGE_BOUND_INFO,
+ crate::loops::NEEDLESS_RANGE_LOOP_INFO,
+ crate::loops::NEVER_LOOP_INFO,
+ crate::loops::SAME_ITEM_PUSH_INFO,
+ crate::loops::SINGLE_ELEMENT_LOOP_INFO,
+ crate::loops::WHILE_IMMUTABLE_CONDITION_INFO,
+ crate::loops::WHILE_LET_LOOP_INFO,
+ crate::loops::WHILE_LET_ON_ITERATOR_INFO,
+ crate::macro_use::MACRO_USE_IMPORTS_INFO,
+ crate::main_recursion::MAIN_RECURSION_INFO,
+ crate::manual_assert::MANUAL_ASSERT_INFO,
+ crate::manual_async_fn::MANUAL_ASYNC_FN_INFO,
+ crate::manual_bits::MANUAL_BITS_INFO,
+ crate::manual_clamp::MANUAL_CLAMP_INFO,
+ crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO,
+ crate::manual_let_else::MANUAL_LET_ELSE_INFO,
+ crate::manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE_INFO,
+ crate::manual_rem_euclid::MANUAL_REM_EUCLID_INFO,
+ crate::manual_retain::MANUAL_RETAIN_INFO,
+ crate::manual_string_new::MANUAL_STRING_NEW_INFO,
+ crate::manual_strip::MANUAL_STRIP_INFO,
+ crate::map_unit_fn::OPTION_MAP_UNIT_FN_INFO,
+ crate::map_unit_fn::RESULT_MAP_UNIT_FN_INFO,
+ crate::match_result_ok::MATCH_RESULT_OK_INFO,
+ crate::matches::COLLAPSIBLE_MATCH_INFO,
+ crate::matches::INFALLIBLE_DESTRUCTURING_MATCH_INFO,
+ crate::matches::MANUAL_FILTER_INFO,
+ crate::matches::MANUAL_MAP_INFO,
+ crate::matches::MANUAL_UNWRAP_OR_INFO,
+ crate::matches::MATCH_AS_REF_INFO,
+ crate::matches::MATCH_BOOL_INFO,
+ crate::matches::MATCH_LIKE_MATCHES_MACRO_INFO,
+ crate::matches::MATCH_ON_VEC_ITEMS_INFO,
+ crate::matches::MATCH_OVERLAPPING_ARM_INFO,
+ crate::matches::MATCH_REF_PATS_INFO,
+ crate::matches::MATCH_SAME_ARMS_INFO,
+ crate::matches::MATCH_SINGLE_BINDING_INFO,
+ crate::matches::MATCH_STR_CASE_MISMATCH_INFO,
+ crate::matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS_INFO,
+ crate::matches::MATCH_WILD_ERR_ARM_INFO,
+ crate::matches::NEEDLESS_MATCH_INFO,
+ crate::matches::REDUNDANT_PATTERN_MATCHING_INFO,
+ crate::matches::REST_PAT_IN_FULLY_BOUND_STRUCTS_INFO,
+ crate::matches::SIGNIFICANT_DROP_IN_SCRUTINEE_INFO,
+ crate::matches::SINGLE_MATCH_INFO,
+ crate::matches::SINGLE_MATCH_ELSE_INFO,
+ crate::matches::TRY_ERR_INFO,
+ crate::matches::WILDCARD_ENUM_MATCH_ARM_INFO,
+ crate::matches::WILDCARD_IN_OR_PATTERNS_INFO,
+ crate::mem_forget::MEM_FORGET_INFO,
+ crate::mem_replace::MEM_REPLACE_OPTION_WITH_NONE_INFO,
+ crate::mem_replace::MEM_REPLACE_WITH_DEFAULT_INFO,
+ crate::mem_replace::MEM_REPLACE_WITH_UNINIT_INFO,
+ crate::methods::BIND_INSTEAD_OF_MAP_INFO,
+ crate::methods::BYTES_COUNT_TO_LEN_INFO,
+ crate::methods::BYTES_NTH_INFO,
+ crate::methods::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS_INFO,
+ crate::methods::CHARS_LAST_CMP_INFO,
+ crate::methods::CHARS_NEXT_CMP_INFO,
+ crate::methods::CLONED_INSTEAD_OF_COPIED_INFO,
+ crate::methods::CLONE_DOUBLE_REF_INFO,
+ crate::methods::CLONE_ON_COPY_INFO,
+ crate::methods::CLONE_ON_REF_PTR_INFO,
+ crate::methods::COLLAPSIBLE_STR_REPLACE_INFO,
+ crate::methods::ERR_EXPECT_INFO,
+ crate::methods::EXPECT_FUN_CALL_INFO,
+ crate::methods::EXPECT_USED_INFO,
+ crate::methods::EXTEND_WITH_DRAIN_INFO,
+ crate::methods::FILETYPE_IS_FILE_INFO,
+ crate::methods::FILTER_MAP_IDENTITY_INFO,
+ crate::methods::FILTER_MAP_NEXT_INFO,
+ crate::methods::FILTER_NEXT_INFO,
+ crate::methods::FLAT_MAP_IDENTITY_INFO,
+ crate::methods::FLAT_MAP_OPTION_INFO,
+ crate::methods::FROM_ITER_INSTEAD_OF_COLLECT_INFO,
+ crate::methods::GET_FIRST_INFO,
+ crate::methods::GET_LAST_WITH_LEN_INFO,
+ crate::methods::GET_UNWRAP_INFO,
+ crate::methods::IMPLICIT_CLONE_INFO,
+ crate::methods::INEFFICIENT_TO_STRING_INFO,
+ crate::methods::INSPECT_FOR_EACH_INFO,
+ crate::methods::INTO_ITER_ON_REF_INFO,
+ crate::methods::IS_DIGIT_ASCII_RADIX_INFO,
+ crate::methods::ITERATOR_STEP_BY_ZERO_INFO,
+ crate::methods::ITER_CLONED_COLLECT_INFO,
+ crate::methods::ITER_COUNT_INFO,
+ crate::methods::ITER_KV_MAP_INFO,
+ crate::methods::ITER_NEXT_SLICE_INFO,
+ crate::methods::ITER_NTH_INFO,
+ crate::methods::ITER_NTH_ZERO_INFO,
+ crate::methods::ITER_ON_EMPTY_COLLECTIONS_INFO,
+ crate::methods::ITER_ON_SINGLE_ITEMS_INFO,
+ crate::methods::ITER_OVEREAGER_CLONED_INFO,
+ crate::methods::ITER_SKIP_NEXT_INFO,
+ crate::methods::ITER_WITH_DRAIN_INFO,
+ crate::methods::MANUAL_FILTER_MAP_INFO,
+ crate::methods::MANUAL_FIND_MAP_INFO,
+ crate::methods::MANUAL_OK_OR_INFO,
+ crate::methods::MANUAL_SATURATING_ARITHMETIC_INFO,
+ crate::methods::MANUAL_SPLIT_ONCE_INFO,
+ crate::methods::MANUAL_STR_REPEAT_INFO,
+ crate::methods::MAP_CLONE_INFO,
+ crate::methods::MAP_COLLECT_RESULT_UNIT_INFO,
+ crate::methods::MAP_ERR_IGNORE_INFO,
+ crate::methods::MAP_FLATTEN_INFO,
+ crate::methods::MAP_IDENTITY_INFO,
+ crate::methods::MAP_UNWRAP_OR_INFO,
+ crate::methods::MUT_MUTEX_LOCK_INFO,
+ crate::methods::NAIVE_BYTECOUNT_INFO,
+ crate::methods::NEEDLESS_COLLECT_INFO,
+ crate::methods::NEEDLESS_OPTION_AS_DEREF_INFO,
+ crate::methods::NEEDLESS_OPTION_TAKE_INFO,
+ crate::methods::NEEDLESS_SPLITN_INFO,
+ crate::methods::NEW_RET_NO_SELF_INFO,
+ crate::methods::NONSENSICAL_OPEN_OPTIONS_INFO,
+ crate::methods::NO_EFFECT_REPLACE_INFO,
+ crate::methods::OBFUSCATED_IF_ELSE_INFO,
+ crate::methods::OK_EXPECT_INFO,
+ crate::methods::OPTION_AS_REF_DEREF_INFO,
+ crate::methods::OPTION_FILTER_MAP_INFO,
+ crate::methods::OPTION_MAP_OR_NONE_INFO,
+ crate::methods::OR_FUN_CALL_INFO,
+ crate::methods::OR_THEN_UNWRAP_INFO,
+ crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO,
+ crate::methods::RANGE_ZIP_WITH_LEN_INFO,
+ crate::methods::REPEAT_ONCE_INFO,
+ crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO,
+ crate::methods::SEARCH_IS_SOME_INFO,
+ crate::methods::SEEK_FROM_CURRENT_INFO,
+ crate::methods::SEEK_TO_START_INSTEAD_OF_REWIND_INFO,
+ crate::methods::SHOULD_IMPLEMENT_TRAIT_INFO,
+ crate::methods::SINGLE_CHAR_ADD_STR_INFO,
+ crate::methods::SINGLE_CHAR_PATTERN_INFO,
+ crate::methods::SKIP_WHILE_NEXT_INFO,
+ crate::methods::STABLE_SORT_PRIMITIVE_INFO,
+ crate::methods::STRING_EXTEND_CHARS_INFO,
+ crate::methods::SUSPICIOUS_MAP_INFO,
+ crate::methods::SUSPICIOUS_SPLITN_INFO,
+ crate::methods::SUSPICIOUS_TO_OWNED_INFO,
+ crate::methods::UNINIT_ASSUMED_INIT_INFO,
+ crate::methods::UNIT_HASH_INFO,
+ crate::methods::UNNECESSARY_FILTER_MAP_INFO,
+ crate::methods::UNNECESSARY_FIND_MAP_INFO,
+ crate::methods::UNNECESSARY_FOLD_INFO,
+ crate::methods::UNNECESSARY_JOIN_INFO,
+ crate::methods::UNNECESSARY_LAZY_EVALUATIONS_INFO,
+ crate::methods::UNNECESSARY_SORT_BY_INFO,
+ crate::methods::UNNECESSARY_TO_OWNED_INFO,
+ crate::methods::UNWRAP_OR_ELSE_DEFAULT_INFO,
+ crate::methods::UNWRAP_USED_INFO,
+ crate::methods::USELESS_ASREF_INFO,
+ crate::methods::VEC_RESIZE_TO_ZERO_INFO,
+ crate::methods::VERBOSE_FILE_READS_INFO,
+ crate::methods::WRONG_SELF_CONVENTION_INFO,
+ crate::methods::ZST_OFFSET_INFO,
+ crate::minmax::MIN_MAX_INFO,
+ 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,
+ crate::misc_early::MIXED_CASE_HEX_LITERALS_INFO,
+ crate::misc_early::REDUNDANT_PATTERN_INFO,
+ crate::misc_early::SEPARATED_LITERAL_SUFFIX_INFO,
+ crate::misc_early::UNNEEDED_FIELD_PATTERN_INFO,
+ crate::misc_early::UNNEEDED_WILDCARD_PATTERN_INFO,
+ crate::misc_early::UNSEPARATED_LITERAL_SUFFIX_INFO,
+ crate::misc_early::ZERO_PREFIXED_LITERAL_INFO,
+ crate::mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER_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,
+ crate::missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS_INFO,
+ crate::missing_trait_methods::MISSING_TRAIT_METHODS_INFO,
+ crate::mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION_INFO,
+ crate::mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION_INFO,
+ crate::module_style::MOD_MODULE_FILES_INFO,
+ crate::module_style::SELF_NAMED_MODULE_FILES_INFO,
+ crate::multi_assignments::MULTI_ASSIGNMENTS_INFO,
+ crate::mut_key::MUTABLE_KEY_TYPE_INFO,
+ crate::mut_mut::MUT_MUT_INFO,
+ crate::mut_reference::UNNECESSARY_MUT_PASSED_INFO,
+ crate::mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL_INFO,
+ crate::mutex_atomic::MUTEX_ATOMIC_INFO,
+ crate::mutex_atomic::MUTEX_INTEGER_INFO,
+ crate::needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE_INFO,
+ crate::needless_bool::BOOL_COMPARISON_INFO,
+ crate::needless_bool::NEEDLESS_BOOL_INFO,
+ crate::needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE_INFO,
+ crate::needless_continue::NEEDLESS_CONTINUE_INFO,
+ crate::needless_for_each::NEEDLESS_FOR_EACH_INFO,
+ crate::needless_late_init::NEEDLESS_LATE_INIT_INFO,
+ crate::needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS_INFO,
+ crate::needless_pass_by_value::NEEDLESS_PASS_BY_VALUE_INFO,
+ crate::needless_question_mark::NEEDLESS_QUESTION_MARK_INFO,
+ crate::needless_update::NEEDLESS_UPDATE_INFO,
+ crate::neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD_INFO,
+ crate::neg_multiply::NEG_MULTIPLY_INFO,
+ crate::new_without_default::NEW_WITHOUT_DEFAULT_INFO,
+ crate::no_effect::NO_EFFECT_INFO,
+ crate::no_effect::NO_EFFECT_UNDERSCORE_BINDING_INFO,
+ crate::no_effect::UNNECESSARY_OPERATION_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,
+ crate::non_expressive_names::MANY_SINGLE_CHAR_NAMES_INFO,
+ crate::non_expressive_names::SIMILAR_NAMES_INFO,
+ crate::non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS_INFO,
+ crate::non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY_INFO,
+ crate::nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES_INFO,
+ crate::octal_escapes::OCTAL_ESCAPES_INFO,
+ crate::only_used_in_recursion::ONLY_USED_IN_RECURSION_INFO,
+ crate::operators::ABSURD_EXTREME_COMPARISONS_INFO,
+ crate::operators::ARITHMETIC_SIDE_EFFECTS_INFO,
+ crate::operators::ASSIGN_OP_PATTERN_INFO,
+ crate::operators::BAD_BIT_MASK_INFO,
+ crate::operators::CMP_NAN_INFO,
+ crate::operators::CMP_OWNED_INFO,
+ crate::operators::DOUBLE_COMPARISONS_INFO,
+ crate::operators::DURATION_SUBSEC_INFO,
+ crate::operators::EQ_OP_INFO,
+ crate::operators::ERASING_OP_INFO,
+ crate::operators::FLOAT_ARITHMETIC_INFO,
+ crate::operators::FLOAT_CMP_INFO,
+ crate::operators::FLOAT_CMP_CONST_INFO,
+ crate::operators::FLOAT_EQUALITY_WITHOUT_ABS_INFO,
+ crate::operators::IDENTITY_OP_INFO,
+ crate::operators::INEFFECTIVE_BIT_MASK_INFO,
+ crate::operators::INTEGER_ARITHMETIC_INFO,
+ crate::operators::INTEGER_DIVISION_INFO,
+ crate::operators::MISREFACTORED_ASSIGN_OP_INFO,
+ crate::operators::MODULO_ARITHMETIC_INFO,
+ crate::operators::MODULO_ONE_INFO,
+ crate::operators::NEEDLESS_BITWISE_BOOL_INFO,
+ crate::operators::OP_REF_INFO,
+ crate::operators::PTR_EQ_INFO,
+ crate::operators::SELF_ASSIGNMENT_INFO,
+ crate::operators::VERBOSE_BIT_MASK_INFO,
+ crate::option_env_unwrap::OPTION_ENV_UNWRAP_INFO,
+ crate::option_if_let_else::OPTION_IF_LET_ELSE_INFO,
+ crate::overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL_INFO,
+ crate::panic_in_result_fn::PANIC_IN_RESULT_FN_INFO,
+ crate::panic_unimplemented::PANIC_INFO,
+ crate::panic_unimplemented::TODO_INFO,
+ crate::panic_unimplemented::UNIMPLEMENTED_INFO,
+ crate::panic_unimplemented::UNREACHABLE_INFO,
+ crate::partial_pub_fields::PARTIAL_PUB_FIELDS_INFO,
+ crate::partialeq_ne_impl::PARTIALEQ_NE_IMPL_INFO,
+ crate::partialeq_to_none::PARTIALEQ_TO_NONE_INFO,
+ crate::pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE_INFO,
+ crate::pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF_INFO,
+ crate::pattern_type_mismatch::PATTERN_TYPE_MISMATCH_INFO,
+ crate::precedence::PRECEDENCE_INFO,
+ crate::ptr::CMP_NULL_INFO,
+ crate::ptr::INVALID_NULL_PTR_USAGE_INFO,
+ crate::ptr::MUT_FROM_REF_INFO,
+ crate::ptr::PTR_ARG_INFO,
+ crate::ptr_offset_with_cast::PTR_OFFSET_WITH_CAST_INFO,
+ crate::pub_use::PUB_USE_INFO,
+ crate::question_mark::QUESTION_MARK_INFO,
+ crate::ranges::MANUAL_RANGE_CONTAINS_INFO,
+ crate::ranges::RANGE_MINUS_ONE_INFO,
+ crate::ranges::RANGE_PLUS_ONE_INFO,
+ crate::ranges::REVERSED_EMPTY_RANGES_INFO,
+ crate::rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT_INFO,
+ crate::read_zero_byte_vec::READ_ZERO_BYTE_VEC_INFO,
+ crate::redundant_clone::REDUNDANT_CLONE_INFO,
+ crate::redundant_closure_call::REDUNDANT_CLOSURE_CALL_INFO,
+ crate::redundant_else::REDUNDANT_ELSE_INFO,
+ crate::redundant_field_names::REDUNDANT_FIELD_NAMES_INFO,
+ crate::redundant_pub_crate::REDUNDANT_PUB_CRATE_INFO,
+ crate::redundant_slicing::DEREF_BY_SLICING_INFO,
+ crate::redundant_slicing::REDUNDANT_SLICING_INFO,
+ crate::redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES_INFO,
+ crate::ref_option_ref::REF_OPTION_REF_INFO,
+ crate::reference::DEREF_ADDROF_INFO,
+ crate::regex::INVALID_REGEX_INFO,
+ crate::regex::TRIVIAL_REGEX_INFO,
+ crate::return_self_not_must_use::RETURN_SELF_NOT_MUST_USE_INFO,
+ crate::returns::LET_AND_RETURN_INFO,
+ crate::returns::NEEDLESS_RETURN_INFO,
+ crate::same_name_method::SAME_NAME_METHOD_INFO,
+ crate::self_named_constructors::SELF_NAMED_CONSTRUCTORS_INFO,
+ crate::semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED_INFO,
+ crate::serde_api::SERDE_API_MISUSE_INFO,
+ crate::shadow::SHADOW_REUSE_INFO,
+ crate::shadow::SHADOW_SAME_INFO,
+ crate::shadow::SHADOW_UNRELATED_INFO,
+ crate::single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES_INFO,
+ crate::single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS_INFO,
+ crate::size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT_INFO,
+ crate::slow_vector_initialization::SLOW_VECTOR_INITIALIZATION_INFO,
+ crate::std_instead_of_core::ALLOC_INSTEAD_OF_CORE_INFO,
+ crate::std_instead_of_core::STD_INSTEAD_OF_ALLOC_INFO,
+ crate::std_instead_of_core::STD_INSTEAD_OF_CORE_INFO,
+ crate::strings::STRING_ADD_INFO,
+ crate::strings::STRING_ADD_ASSIGN_INFO,
+ crate::strings::STRING_FROM_UTF8_AS_BYTES_INFO,
+ crate::strings::STRING_LIT_AS_BYTES_INFO,
+ crate::strings::STRING_SLICE_INFO,
+ crate::strings::STRING_TO_STRING_INFO,
+ crate::strings::STR_TO_STRING_INFO,
+ crate::strings::TRIM_SPLIT_WHITESPACE_INFO,
+ crate::strlen_on_c_strings::STRLEN_ON_C_STRINGS_INFO,
+ crate::suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS_INFO,
+ crate::suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL_INFO,
+ crate::suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL_INFO,
+ crate::suspicious_xor_used_as_pow::SUSPICIOUS_XOR_USED_AS_POW_INFO,
+ crate::swap::ALMOST_SWAPPED_INFO,
+ crate::swap::MANUAL_SWAP_INFO,
+ crate::swap_ptr_to_ref::SWAP_PTR_TO_REF_INFO,
+ crate::tabs_in_doc_comments::TABS_IN_DOC_COMMENTS_INFO,
+ crate::temporary_assignment::TEMPORARY_ASSIGNMENT_INFO,
+ crate::to_digit_is_some::TO_DIGIT_IS_SOME_INFO,
+ crate::trailing_empty_array::TRAILING_EMPTY_ARRAY_INFO,
+ crate::trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS_INFO,
+ crate::trait_bounds::TYPE_REPETITION_IN_BOUNDS_INFO,
+ crate::transmute::CROSSPOINTER_TRANSMUTE_INFO,
+ crate::transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS_INFO,
+ crate::transmute::TRANSMUTE_BYTES_TO_STR_INFO,
+ crate::transmute::TRANSMUTE_FLOAT_TO_INT_INFO,
+ crate::transmute::TRANSMUTE_INT_TO_BOOL_INFO,
+ crate::transmute::TRANSMUTE_INT_TO_CHAR_INFO,
+ crate::transmute::TRANSMUTE_INT_TO_FLOAT_INFO,
+ crate::transmute::TRANSMUTE_NUM_TO_BYTES_INFO,
+ crate::transmute::TRANSMUTE_PTR_TO_PTR_INFO,
+ crate::transmute::TRANSMUTE_PTR_TO_REF_INFO,
+ crate::transmute::TRANSMUTE_UNDEFINED_REPR_INFO,
+ crate::transmute::TRANSMUTING_NULL_INFO,
+ crate::transmute::UNSOUND_COLLECTION_TRANSMUTE_INFO,
+ crate::transmute::USELESS_TRANSMUTE_INFO,
+ crate::transmute::WRONG_TRANSMUTE_INFO,
+ crate::types::BORROWED_BOX_INFO,
+ crate::types::BOX_COLLECTION_INFO,
+ crate::types::LINKEDLIST_INFO,
+ crate::types::OPTION_OPTION_INFO,
+ crate::types::RC_BUFFER_INFO,
+ crate::types::RC_MUTEX_INFO,
+ crate::types::REDUNDANT_ALLOCATION_INFO,
+ crate::types::TYPE_COMPLEXITY_INFO,
+ crate::types::VEC_BOX_INFO,
+ crate::undocumented_unsafe_blocks::UNDOCUMENTED_UNSAFE_BLOCKS_INFO,
+ crate::undocumented_unsafe_blocks::UNNECESSARY_SAFETY_COMMENT_INFO,
+ crate::unicode::INVISIBLE_CHARACTERS_INFO,
+ crate::unicode::NON_ASCII_LITERAL_INFO,
+ crate::unicode::UNICODE_NOT_NFC_INFO,
+ crate::uninit_vec::UNINIT_VEC_INFO,
+ crate::unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD_INFO,
+ crate::unit_types::LET_UNIT_VALUE_INFO,
+ crate::unit_types::UNIT_ARG_INFO,
+ crate::unit_types::UNIT_CMP_INFO,
+ crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO,
+ crate::unnamed_address::VTABLE_ADDRESS_COMPARISONS_INFO,
+ crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO,
+ crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO,
+ crate::unnecessary_wraps::UNNECESSARY_WRAPS_INFO,
+ crate::unnested_or_patterns::UNNESTED_OR_PATTERNS_INFO,
+ crate::unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME_INFO,
+ crate::unused_async::UNUSED_ASYNC_INFO,
+ crate::unused_io_amount::UNUSED_IO_AMOUNT_INFO,
+ crate::unused_peekable::UNUSED_PEEKABLE_INFO,
+ crate::unused_rounding::UNUSED_ROUNDING_INFO,
+ crate::unused_self::UNUSED_SELF_INFO,
+ crate::unused_unit::UNUSED_UNIT_INFO,
+ crate::unwrap::PANICKING_UNWRAP_INFO,
+ crate::unwrap::UNNECESSARY_UNWRAP_INFO,
+ crate::unwrap_in_result::UNWRAP_IN_RESULT_INFO,
+ crate::upper_case_acronyms::UPPER_CASE_ACRONYMS_INFO,
+ crate::use_self::USE_SELF_INFO,
+ crate::useless_conversion::USELESS_CONVERSION_INFO,
+ crate::vec::USELESS_VEC_INFO,
+ crate::vec_init_then_push::VEC_INIT_THEN_PUSH_INFO,
+ crate::wildcard_imports::ENUM_GLOB_USE_INFO,
+ crate::wildcard_imports::WILDCARD_IMPORTS_INFO,
+ crate::write::PRINTLN_EMPTY_STRING_INFO,
+ crate::write::PRINT_LITERAL_INFO,
+ crate::write::PRINT_STDERR_INFO,
+ crate::write::PRINT_STDOUT_INFO,
+ crate::write::PRINT_WITH_NEWLINE_INFO,
+ crate::write::USE_DEBUG_INFO,
+ crate::write::WRITELN_EMPTY_STRING_INFO,
+ crate::write::WRITE_LITERAL_INFO,
+ crate::write::WRITE_WITH_NEWLINE_INFO,
+ crate::zero_div_zero::ZERO_DIVIDED_BY_ZERO_INFO,
+ crate::zero_sized_map_values::ZERO_SIZED_MAP_VALUES_INFO,
+];
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index a37ee82d4..38329659e 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1,14 +1,16 @@
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::{expr_sig, is_copy, peel_mid_ty_refs, ty_sig, variant_of_res};
use clippy_utils::{
- fn_def_id, get_parent_expr, get_parent_expr_for_hir, is_lint_allowed, meets_msrv, msrvs, path_to_local,
- walk_to_expr_usage,
+ fn_def_id, get_parent_expr, get_parent_expr_for_hir, is_lint_allowed, path_to_local, walk_to_expr_usage,
};
+
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::intravisit::{walk_ty, Visitor};
use rustc_hir::{
@@ -24,10 +26,9 @@ 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, Binder, BoundVariableKind, EarlyBinder, FnSig, GenericArgKind, List, ParamTy, PredicateKind,
+ self, Binder, BoundVariableKind, Clause, EarlyBinder, FnSig, GenericArgKind, List, ParamTy, PredicateKind,
ProjectionPredicate, Ty, TyCtxt, TypeVisitable, TypeckResults,
};
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{symbol::sym, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt as _;
@@ -180,12 +181,12 @@ pub struct Dereferencing<'tcx> {
possible_borrowers: Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
// `IntoIterator` for arrays requires Rust 1.53.
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl<'tcx> Dereferencing<'tcx> {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self {
msrv,
..Dereferencing::default()
@@ -274,9 +275,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
}
let typeck = cx.typeck_results();
- let (kind, sub_expr) = if let Some(x) = try_parse_ref_op(cx.tcx, typeck, expr) {
- x
- } else {
+ let Some((kind, sub_expr)) = try_parse_ref_op(cx.tcx, typeck, expr) else {
// The whole chain of reference operations has been seen
if let Some((state, data)) = self.state.take() {
report(cx, expr, state, data);
@@ -287,26 +286,27 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
match (self.state.take(), kind) {
(None, kind) => {
let expr_ty = typeck.expr_ty(expr);
- let (position, adjustments) = walk_parents(cx, &mut self.possible_borrowers, expr, self.msrv);
+ let (position, adjustments) = walk_parents(cx, &mut self.possible_borrowers, expr, &self.msrv);
match kind {
RefOp::Deref => {
+ let sub_ty = typeck.expr_ty(sub_expr);
if let Position::FieldAccess {
name,
of_union: false,
} = position
- && !ty_contains_field(typeck.expr_ty(sub_expr), name)
+ && !ty_contains_field(sub_ty, name)
{
self.state = Some((
State::ExplicitDerefField { name },
StateData { span: expr.span, hir_id: expr.hir_id, position },
));
- } else if position.is_deref_stable() {
+ } else if position.is_deref_stable() && sub_ty.is_ref() {
self.state = Some((
State::ExplicitDeref { mutability: None },
StateData { span: expr.span, hir_id: expr.hir_id, position },
));
}
- }
+ },
RefOp::Method(target_mut)
if !is_lint_allowed(cx, EXPLICIT_DEREF_METHODS, expr.hir_id)
&& position.lint_explicit_deref() =>
@@ -321,7 +321,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
StateData {
span: expr.span,
hir_id: expr.hir_id,
- position
+ position,
},
));
},
@@ -395,7 +395,11 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
msg,
snip_expr,
}),
- StateData { span: expr.span, hir_id: expr.hir_id, position },
+ StateData {
+ span: expr.span,
+ hir_id: expr.hir_id,
+ position,
+ },
));
} else if position.is_deref_stable()
// Auto-deref doesn't combine with other adjustments
@@ -407,7 +411,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
StateData {
span: expr.span,
hir_id: expr.hir_id,
- position
+ position,
},
));
}
@@ -699,7 +703,7 @@ fn walk_parents<'tcx>(
cx: &LateContext<'tcx>,
possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
e: &'tcx Expr<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) -> (Position, &'tcx [Adjustment<'tcx>]) {
let mut adjustments = [].as_slice();
let mut precedence = 0i8;
@@ -806,30 +810,39 @@ fn walk_parents<'tcx>(
.position(|arg| arg.hir_id == child_id)
.zip(expr_sig(cx, func))
.and_then(|(i, sig)| {
- sig.input_with_hir(i).map(|(hir_ty, ty)| match hir_ty {
- // Type inference for closures can depend on how they're called. Only go by the explicit
- // types here.
- Some(hir_ty) => binding_ty_auto_deref_stability(cx, hir_ty, precedence, ty.bound_vars()),
- None => {
- if let ty::Param(param_ty) = ty.skip_binder().kind() {
- needless_borrow_impl_arg_position(
- cx,
- possible_borrowers,
- parent,
- i,
- *param_ty,
- e,
- precedence,
- msrv,
- )
- } else {
- ty_auto_deref_stability(cx, cx.tcx.erase_late_bound_regions(ty), precedence)
- .position_for_arg()
- }
- },
+ sig.input_with_hir(i).map(|(hir_ty, ty)| {
+ match hir_ty {
+ // Type inference for closures can depend on how they're called. Only go by the explicit
+ // types here.
+ Some(hir_ty) => {
+ binding_ty_auto_deref_stability(cx, hir_ty, precedence, ty.bound_vars())
+ },
+ None => {
+ // `e.hir_id == child_id` for https://github.com/rust-lang/rust-clippy/issues/9739
+ // `!call_is_qualified(func)` for https://github.com/rust-lang/rust-clippy/issues/9782
+ if e.hir_id == child_id
+ && !call_is_qualified(func)
+ && let ty::Param(param_ty) = ty.skip_binder().kind()
+ {
+ needless_borrow_impl_arg_position(
+ cx,
+ possible_borrowers,
+ parent,
+ i,
+ *param_ty,
+ e,
+ precedence,
+ msrv,
+ )
+ } else {
+ ty_auto_deref_stability(cx, cx.tcx.erase_late_bound_regions(ty), precedence)
+ .position_for_arg()
+ }
+ },
+ }
})
}),
- ExprKind::MethodCall(_, receiver, args, _) => {
+ ExprKind::MethodCall(method, receiver, args, _) => {
let id = cx.typeck_results().type_dependent_def_id(parent.hir_id).unwrap();
if receiver.hir_id == child_id {
// Check for calls to trait methods where the trait is implemented on a reference.
@@ -842,14 +855,10 @@ fn walk_parents<'tcx>(
} else if let Some(trait_id) = cx.tcx.trait_of_item(id)
&& let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e))
&& let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
- && let subs = match cx
+ && let subs = cx
.typeck_results()
- .node_substs_opt(parent.hir_id)
- .and_then(|subs| subs.get(1..))
- {
- Some(subs) => cx.tcx.mk_substs(subs.iter().copied()),
- None => cx.tcx.mk_substs(std::iter::empty::<ty::subst::GenericArg<'_>>()),
- } && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
+ .node_substs_opt(parent.hir_id).map(|subs| &subs[1..]).unwrap_or_default()
+ && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
// Trait methods taking `&self`
sub_ty
} else {
@@ -858,7 +867,11 @@ fn walk_parents<'tcx>(
} && impl_ty.is_ref()
&& let infcx = cx.tcx.infer_ctxt().build()
&& infcx
- .type_implements_trait(trait_id, impl_ty, subs, cx.param_env)
+ .type_implements_trait(
+ trait_id,
+ [impl_ty.into()].into_iter().chain(subs.iter().copied()),
+ cx.param_env,
+ )
.must_apply_modulo_regions()
{
return Some(Position::MethodReceiverRefImpl)
@@ -867,7 +880,9 @@ fn walk_parents<'tcx>(
}
args.iter().position(|arg| arg.hir_id == child_id).map(|i| {
let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i + 1];
- if let ty::Param(param_ty) = ty.kind() {
+ // `e.hir_id == child_id` for https://github.com/rust-lang/rust-clippy/issues/9739
+ // `method.args.is_none()` for https://github.com/rust-lang/rust-clippy/issues/9782
+ if e.hir_id == child_id && method.args.is_none() && let ty::Param(param_ty) = ty.kind() {
needless_borrow_impl_arg_position(
cx,
possible_borrowers,
@@ -1045,13 +1060,25 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
v.0
}
+fn call_is_qualified(expr: &Expr<'_>) -> bool {
+ if let ExprKind::Path(path) = &expr.kind {
+ match path {
+ QPath::Resolved(_, path) => path.segments.last().map_or(false, |segment| segment.args.is_some()),
+ QPath::TypeRelative(_, segment) => segment.args.is_some(),
+ QPath::LangItem(..) => false,
+ }
+ } else {
+ false
+ }
+}
+
// Checks whether:
// * child is an expression of the form `&e` in an argument position requiring an `impl Trait`
// * `e`'s type implements `Trait` and is copyable
// If the conditions are met, returns `Some(Position::ImplArg(..))`; otherwise, returns `None`.
// The "is copyable" condition is to avoid the case where removing the `&` means `e` would have to
// be moved, but it cannot be.
-#[expect(clippy::too_many_arguments)]
+#[expect(clippy::too_many_arguments, clippy::too_many_lines)]
fn needless_borrow_impl_arg_position<'tcx>(
cx: &LateContext<'tcx>,
possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
@@ -1060,7 +1087,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
param_ty: ParamTy,
mut expr: &Expr<'tcx>,
precedence: i8,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) -> Position {
let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
@@ -1079,7 +1106,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
let projection_predicates = predicates
.iter()
.filter_map(|predicate| {
- if let PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
+ if let PredicateKind::Clause(Clause::Projection(projection_predicate)) = predicate.kind().skip_binder() {
Some(projection_predicate)
} else {
None
@@ -1093,7 +1120,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
if predicates
.iter()
.filter_map(|predicate| {
- if let PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+ if let PredicateKind::Clause(Clause::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)
@@ -1113,6 +1140,16 @@ fn needless_borrow_impl_arg_position<'tcx>(
return Position::Other(precedence);
}
+ // 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, callee_def_id, projection_predicate))
+ {
+ return Position::Other(precedence);
+ }
+
// `substs_with_referent_ty` can be constructed outside of `check_referent` because the same
// elements are modified each time `check_referent` is called.
let mut substs_with_referent_ty = substs_with_expr_ty.to_vec();
@@ -1145,18 +1182,18 @@ fn needless_borrow_impl_arg_position<'tcx>(
}
predicates.iter().all(|predicate| {
- if let PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+ if let PredicateKind::Clause(Clause::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) = substs_with_referent_ty[param_ty.index as usize].unpack()
&& ty.is_array()
- && !meets_msrv(msrv, msrvs::ARRAY_INTO_ITERATOR)
+ && !msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
{
return false;
}
let predicate = EarlyBinder(predicate).subst(cx.tcx, &substs_with_referent_ty);
- let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
+ 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)
})
@@ -1192,6 +1229,37 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
})
}
+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::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>)>,
@@ -1203,6 +1271,8 @@ fn referent_used_exactly_once<'tcx>(
&& let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
&& let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
&& !place.has_deref()
+ // 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
@@ -1263,7 +1333,7 @@ fn replace_types<'tcx>(
let item_def_id = projection_predicate.projection_ty.item_def_id;
let assoc_item = cx.tcx.associated_item(item_def_id);
let projection = cx.tcx
- .mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(new_ty, &[]));
+ .mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(new_ty, []));
if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
&& substs[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty)
@@ -1320,6 +1390,7 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc
continue;
},
ty::Param(_) => TyPosition::new_deref_stable_for_result(precedence, ty),
+ ty::Projection(_) if ty.has_non_region_param() => TyPosition::new_deref_stable_for_result(precedence, ty),
ty::Infer(_) | ty::Error(_) | ty::Bound(..) | ty::Opaque(..) | ty::Placeholder(_) | ty::Dynamic(..) => {
Position::ReborrowStable(precedence).into()
},
@@ -1346,11 +1417,9 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc
| ty::Closure(..)
| ty::Never
| ty::Tuple(_)
- | ty::Projection(_) => Position::DerefStable(
- precedence,
- ty.is_sized(cx.tcx, cx.param_env.without_caller_bounds()),
- )
- .into(),
+ | ty::Projection(_) => {
+ Position::DerefStable(precedence, ty.is_sized(cx.tcx, cx.param_env.without_caller_bounds())).into()
+ },
};
}
}
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 102a02138..9e596ca81 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -14,8 +14,8 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_middle::traits::Reveal;
use rustc_middle::ty::{
- self, Binder, BoundConstness, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, TraitPredicate, TraitRef,
- Ty, TyCtxt,
+ self, Binder, BoundConstness, Clause, GenericParamDefKind, ImplPolarity, ParamEnv, PredicateKind, TraitPredicate,
+ TraitRef, Ty, TyCtxt,
};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
@@ -466,12 +466,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
if let Some(def_id) = trait_ref.trait_def_id();
if cx.tcx.is_diagnostic_item(sym::PartialEq, def_id);
let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id);
- if !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[]);
+ if !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, []);
// If all of our fields implement `Eq`, we can implement `Eq` too
if adt
.all_fields()
.map(|f| f.ty(cx.tcx, substs))
- .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[]));
+ .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, []));
then {
span_lint_and_sugg(
cx,
@@ -499,7 +499,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
let ty_predicates = tcx.predicates_of(did).predicates;
for (p, _) in ty_predicates {
- if let PredicateKind::Trait(p) = p.kind().skip_binder()
+ if let PredicateKind::Clause(Clause::Trait(p)) = p.kind().skip_binder()
&& p.trait_ref.def_id == eq_trait_id
&& let ty::Param(self_ty) = p.trait_ref.self_ty().kind()
&& p.constness == BoundConstness::NotConst
@@ -512,14 +512,14 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
ParamEnv::new(
tcx.mk_predicates(ty_predicates.iter().map(|&(p, _)| p).chain(
params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
- tcx.mk_predicate(Binder::dummy(PredicateKind::Trait(TraitPredicate {
+ tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait(TraitPredicate {
trait_ref: TraitRef::new(
eq_trait_id,
tcx.mk_substs(std::iter::once(tcx.mk_param_from_def(param))),
),
constness: BoundConstness::NotConst,
polarity: ImplPolarity::Positive,
- })))
+ }))))
}),
)),
Reveal::UserFacing,
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
index 5ab7144e2..68122b4ce 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
@@ -1,7 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::macros::macro_backtrace;
use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::def::{Namespace, Res};
use rustc_hir::def_id::DefIdMap;
use rustc_hir::{Expr, ForeignItem, HirId, ImplItem, Item, Pat, Path, Stmt, TraitItem, Ty};
use rustc_lint::{LateContext, LateLintPass};
@@ -89,7 +88,7 @@ impl DisallowedMacros {
&format!("use of a disallowed macro `{}`", conf.path()),
|diag| {
if let Some(reason) = conf.reason() {
- diag.note(&format!("{reason} (from clippy.toml)"));
+ diag.note(reason);
}
},
);
@@ -104,7 +103,7 @@ impl LateLintPass<'_> for DisallowedMacros {
fn check_crate(&mut self, cx: &LateContext<'_>) {
for (index, conf) in self.conf_disallowed.iter().enumerate() {
let segs: Vec<_> = conf.path().split("::").collect();
- if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, Some(Namespace::MacroNS)) {
+ for id in clippy_utils::def_path_def_ids(cx, &segs) {
self.disallowed.insert(id, index);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_methods.rs b/src/tools/clippy/clippy_lints/src/disallowed_methods.rs
index 6ac85606d..ca8671c8f 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_methods.rs
@@ -1,7 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::{fn_def_id, get_parent_expr, path_def_id};
-use rustc_hir::def::{Namespace, Res};
use rustc_hir::def_id::DefIdMap;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
@@ -79,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethods {
fn check_crate(&mut self, cx: &LateContext<'_>) {
for (index, conf) in self.conf_disallowed.iter().enumerate() {
let segs: Vec<_> = conf.path().split("::").collect();
- if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, Some(Namespace::ValueNS)) {
+ for id in clippy_utils::def_path_def_ids(cx, &segs) {
self.disallowed.insert(id, index);
}
}
@@ -104,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethods {
let msg = format!("use of a disallowed method `{}`", conf.path());
span_lint_and_then(cx, DISALLOWED_METHODS, expr.span, &msg, |diag| {
if let Some(reason) = conf.reason() {
- diag.note(&format!("{reason} (from clippy.toml)"));
+ diag.note(reason);
}
});
}
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_types.rs b/src/tools/clippy/clippy_lints/src/disallowed_types.rs
index c7131fc16..1f56d0118 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_types.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_types.rs
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def::{Namespace, Res};
+use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
use rustc_hir::{Item, ItemKind, PolyTraitRef, PrimTy, Ty, TyKind, UseKind};
use rustc_lint::{LateContext, LateLintPass};
@@ -53,8 +53,8 @@ declare_clippy_lint! {
#[derive(Clone, Debug)]
pub struct DisallowedTypes {
conf_disallowed: Vec<conf::DisallowedPath>,
- def_ids: FxHashMap<DefId, Option<String>>,
- prim_tys: FxHashMap<PrimTy, Option<String>>,
+ def_ids: FxHashMap<DefId, usize>,
+ prim_tys: FxHashMap<PrimTy, usize>,
}
impl DisallowedTypes {
@@ -69,13 +69,13 @@ impl DisallowedTypes {
fn check_res_emit(&self, cx: &LateContext<'_>, res: &Res, span: Span) {
match res {
Res::Def(_, did) => {
- if let Some(reason) = self.def_ids.get(did) {
- emit(cx, &cx.tcx.def_path_str(*did), span, reason.as_deref());
+ if let Some(&index) = self.def_ids.get(did) {
+ emit(cx, &cx.tcx.def_path_str(*did), span, &self.conf_disallowed[index]);
}
},
Res::PrimTy(prim) => {
- if let Some(reason) = self.prim_tys.get(prim) {
- emit(cx, prim.name_str(), span, reason.as_deref());
+ if let Some(&index) = self.prim_tys.get(prim) {
+ emit(cx, prim.name_str(), span, &self.conf_disallowed[index]);
}
},
_ => {},
@@ -87,24 +87,28 @@ impl_lint_pass!(DisallowedTypes => [DISALLOWED_TYPES]);
impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
fn check_crate(&mut self, cx: &LateContext<'_>) {
- for conf in &self.conf_disallowed {
+ for (index, conf) in self.conf_disallowed.iter().enumerate() {
let segs: Vec<_> = conf.path().split("::").collect();
- let reason = conf.reason().map(|reason| format!("{reason} (from clippy.toml)"));
- match clippy_utils::def_path_res(cx, &segs, Some(Namespace::TypeNS)) {
- Res::Def(_, id) => {
- self.def_ids.insert(id, reason);
- },
- Res::PrimTy(ty) => {
- self.prim_tys.insert(ty, reason);
- },
- _ => {},
+
+ for res in clippy_utils::def_path_res(cx, &segs) {
+ match res {
+ Res::Def(_, id) => {
+ self.def_ids.insert(id, index);
+ },
+ Res::PrimTy(ty) => {
+ self.prim_tys.insert(ty, index);
+ },
+ _ => {},
+ }
}
}
}
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
if let ItemKind::Use(path, UseKind::Single) = &item.kind {
- self.check_res_emit(cx, &path.res, item.span);
+ for res in &path.res {
+ self.check_res_emit(cx, res, item.span);
+ }
}
}
@@ -119,14 +123,14 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
}
}
-fn emit(cx: &LateContext<'_>, name: &str, span: Span, reason: Option<&str>) {
+fn emit(cx: &LateContext<'_>, name: &str, span: Span, conf: &conf::DisallowedPath) {
span_lint_and_then(
cx,
DISALLOWED_TYPES,
span,
&format!("`{name}` is not allowed according to config"),
|diag| {
- if let Some(reason) = reason {
+ if let Some(reason) = conf.reason() {
diag.note(reason);
}
},
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index 24d6a6951..cdc23a4d2 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -11,7 +11,7 @@ use rustc_ast::token::CommentKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::EmitterWriter;
-use rustc_errors::{Applicability, Handler, MultiSpan, SuggestionStyle};
+use rustc_errors::{Applicability, Handler, SuggestionStyle};
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{AnonConst, Expr};
@@ -221,6 +221,42 @@ declare_clippy_lint! {
"possible typo for an intra-doc link"
}
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for the doc comments of publicly visible
+ /// safe functions and traits and warns if there is a `# Safety` section.
+ ///
+ /// ### Why is this bad?
+ /// Safe functions and traits are safe to implement and therefore do not
+ /// need to describe safety preconditions that users are required to uphold.
+ ///
+ /// ### Examples
+ /// ```rust
+ ///# type Universe = ();
+ /// /// # Safety
+ /// ///
+ /// /// This function should not be called before the horsemen are ready.
+ /// pub fn start_apocalypse_but_safely(u: &mut Universe) {
+ /// unimplemented!();
+ /// }
+ /// ```
+ ///
+ /// The function is safe, so there shouldn't be any preconditions
+ /// that have to be explained for safety reasons.
+ ///
+ /// ```rust
+ ///# type Universe = ();
+ /// /// This function should really be documented
+ /// pub fn start_apocalypse(u: &mut Universe) {
+ /// unimplemented!();
+ /// }
+ /// ```
+ #[clippy::version = "1.66.0"]
+ pub UNNECESSARY_SAFETY_DOC,
+ restriction,
+ "`pub fn` or `pub trait` with `# Safety` docs"
+}
+
#[expect(clippy::module_name_repetitions)]
#[derive(Clone)]
pub struct DocMarkdown {
@@ -243,7 +279,8 @@ impl_lint_pass!(DocMarkdown => [
MISSING_SAFETY_DOC,
MISSING_ERRORS_DOC,
MISSING_PANICS_DOC,
- NEEDLESS_DOCTEST_MAIN
+ NEEDLESS_DOCTEST_MAIN,
+ UNNECESSARY_SAFETY_DOC,
]);
impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
@@ -254,7 +291,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
- let headers = check_attrs(cx, &self.valid_idents, attrs);
+ let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
match item.kind {
hir::ItemKind::Fn(ref sig, _, body_id) => {
if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
@@ -265,29 +302,26 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
panic_span: None,
};
fpu.visit_expr(body.value);
- lint_for_missing_headers(
- cx,
- item.owner_id.def_id,
- item.span,
- sig,
- headers,
- Some(body_id),
- fpu.panic_span,
- );
+ lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, Some(body_id), fpu.panic_span);
}
},
hir::ItemKind::Impl(impl_) => {
self.in_trait_impl = impl_.of_trait.is_some();
},
- hir::ItemKind::Trait(_, unsafety, ..) => {
- if !headers.safety && unsafety == hir::Unsafety::Unsafe {
- span_lint(
- cx,
- MISSING_SAFETY_DOC,
- item.span,
- "docs for unsafe trait missing `# Safety` section",
- );
- }
+ hir::ItemKind::Trait(_, unsafety, ..) => match (headers.safety, unsafety) {
+ (false, hir::Unsafety::Unsafe) => span_lint(
+ cx,
+ MISSING_SAFETY_DOC,
+ cx.tcx.def_span(item.owner_id),
+ "docs for unsafe trait missing `# Safety` section",
+ ),
+ (true, hir::Unsafety::Normal) => span_lint(
+ cx,
+ UNNECESSARY_SAFETY_DOC,
+ cx.tcx.def_span(item.owner_id),
+ "docs for safe trait have unnecessary `# Safety` section",
+ ),
+ _ => (),
},
_ => (),
}
@@ -301,17 +335,17 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
- let headers = check_attrs(cx, &self.valid_idents, attrs);
+ let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
if !in_external_macro(cx.tcx.sess, item.span) {
- lint_for_missing_headers(cx, item.owner_id.def_id, item.span, sig, headers, None, None);
+ lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, None, None);
}
}
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
- let headers = check_attrs(cx, &self.valid_idents, attrs);
+ let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) {
return;
}
@@ -323,23 +357,14 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
panic_span: None,
};
fpu.visit_expr(body.value);
- lint_for_missing_headers(
- cx,
- item.owner_id.def_id,
- item.span,
- sig,
- headers,
- Some(body_id),
- fpu.panic_span,
- );
+ lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, Some(body_id), fpu.panic_span);
}
}
}
-fn lint_for_missing_headers<'tcx>(
- cx: &LateContext<'tcx>,
+fn lint_for_missing_headers(
+ cx: &LateContext<'_>,
def_id: LocalDefId,
- span: impl Into<MultiSpan> + Copy,
sig: &hir::FnSig<'_>,
headers: DocHeaders,
body_id: Option<hir::BodyId>,
@@ -359,13 +384,21 @@ fn lint_for_missing_headers<'tcx>(
return;
}
- if !headers.safety && sig.header.unsafety == hir::Unsafety::Unsafe {
- span_lint(
+ let span = cx.tcx.def_span(def_id);
+ match (headers.safety, sig.header.unsafety) {
+ (false, hir::Unsafety::Unsafe) => span_lint(
cx,
MISSING_SAFETY_DOC,
span,
"unsafe function's docs miss `# Safety` section",
- );
+ ),
+ (true, hir::Unsafety::Normal) => span_lint(
+ cx,
+ UNNECESSARY_SAFETY_DOC,
+ span,
+ "safe function's docs have unnecessary `# Safety` section",
+ ),
+ _ => (),
}
if !headers.panics && panic_span.is_some() {
span_lint_and_note(
@@ -394,9 +427,7 @@ fn lint_for_missing_headers<'tcx>(
let body = cx.tcx.hir().body(body_id);
let ret_ty = typeck.expr_ty(body.value);
if implements_trait(cx, ret_ty, future, &[]);
- if let ty::Opaque(_, subs) = ret_ty.kind();
- if let Some(gen) = subs.types().next();
- if let ty::Generator(_, subs, _) = gen.kind();
+ if let ty::Generator(_, subs, _) = ret_ty.kind();
if is_type_diagnostic_item(cx, subs.as_generator().return_ty(), sym::Result);
then {
span_lint(
@@ -467,7 +498,7 @@ struct DocHeaders {
panics: bool,
}
-fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &'a [Attribute]) -> DocHeaders {
+fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[Attribute]) -> Option<DocHeaders> {
use pulldown_cmark::{BrokenLink, CowStr, Options};
/// 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
@@ -488,11 +519,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
} else if attr.has_name(sym::doc) {
// ignore mix of sugared and non-sugared doc
// don't trigger the safety or errors check
- return DocHeaders {
- safety: true,
- errors: true,
- panics: true,
- };
+ return None;
}
}
@@ -504,7 +531,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
}
if doc.is_empty() {
- return DocHeaders::default();
+ return Some(DocHeaders::default());
}
let mut cb = fake_broken_link_callback;
@@ -527,7 +554,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
(previous, current) => Err(((previous, previous_range), (current, current_range))),
}
});
- check_doc(cx, valid_idents, events, &spans)
+ Some(check_doc(cx, valid_idents, events, &spans))
}
const RUST_CODE: &[&str] = &["rust", "no_run", "should_panic", "compile_fail"];
@@ -691,6 +718,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
false,
None,
false,
+ false,
);
let handler = Handler::with_emitter(false, None, Box::new(emitter));
let sess = ParseSess::with_span_handler(handler, sm);
diff --git a/src/tools/clippy/clippy_lints/src/double_parens.rs b/src/tools/clippy/clippy_lints/src/double_parens.rs
index 0f1d70186..29425b2e5 100644
--- a/src/tools/clippy/clippy_lints/src/double_parens.rs
+++ b/src/tools/clippy/clippy_lints/src/double_parens.rs
@@ -61,10 +61,10 @@ impl EarlyLintPass for DoubleParens {
}
}
},
- ExprKind::MethodCall(_, _, ref params, _) => {
- if let [ref param] = params[..] {
- if let ExprKind::Paren(_) = param.kind {
- span_lint(cx, DOUBLE_PARENS, param.span, msg);
+ ExprKind::MethodCall(ref call) => {
+ if let [ref arg] = call.args[..] {
+ if let ExprKind::Paren(_) = arg.kind {
+ span_lint(cx, DOUBLE_PARENS, arg.span, msg);
}
}
},
diff --git a/src/tools/clippy/clippy_lints/src/enum_variants.rs b/src/tools/clippy/clippy_lints/src/enum_variants.rs
index 223545fa7..b77b5621b 100644
--- a/src/tools/clippy/clippy_lints/src/enum_variants.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_variants.rs
@@ -250,7 +250,7 @@ impl LateLintPass<'_> for EnumVariantNames {
let item_name = item.ident.name.as_str();
let item_camel = to_camel_case(item_name);
if !item.span.from_expansion() && is_present_in_source(cx, item.span) {
- if let Some(&(ref mod_name, ref mod_camel)) = self.modules.last() {
+ if let Some((mod_name, mod_camel)) = self.modules.last() {
// constants don't have surrounding modules
if !mod_camel.is_empty() {
if mod_name == &item.ident.name {
diff --git a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
index b40cb7cdd..c691e6c54 100644
--- a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
+++ b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
@@ -1,7 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::implements_trait;
-use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Pat, PatKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -67,16 +66,14 @@ fn is_structural_partial_eq<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: T
impl<'tcx> LateLintPass<'tcx> for PatternEquality {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
- if_chain! {
- if !in_external_macro(cx.sess(), expr.span);
- if let ExprKind::Let(let_expr) = expr.kind;
- if unary_pattern(let_expr.pat);
+ if !in_external_macro(cx.sess(), expr.span)
+ && let ExprKind::Let(let_expr) = expr.kind
+ && unary_pattern(let_expr.pat) {
let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
- if is_structural_partial_eq(cx, exp_ty, pat_ty);
- then {
+ let mut applicability = Applicability::MachineApplicable;
- let mut applicability = Applicability::MachineApplicable;
+ if is_structural_partial_eq(cx, exp_ty, pat_ty) {
let pat_str = match let_expr.pat.kind {
PatKind::Struct(..) => format!(
"({})",
@@ -96,6 +93,20 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
),
applicability,
);
+ } else {
+ span_lint_and_sugg(
+ cx,
+ EQUATABLE_IF_LET,
+ expr.span,
+ "this pattern matching can be expressed using `matches!`",
+ "try",
+ format!(
+ "matches!({}, {})",
+ snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
+ snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
+ ),
+ applicability,
+ );
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index 7f1a4c4be..1d09adec1 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -176,13 +176,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
}
}
- fn fake_read(
- &mut self,
- _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>,
- _: FakeReadCause,
- _: HirId,
- ) {
- }
+ fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
}
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index 7b9786d7e..3543910c3 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -11,7 +11,7 @@ use rustc_hir::{Closure, Expr, ExprKind, Param, PatKind, Unsafety};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::binding::BindingMode;
-use rustc_middle::ty::{self, Ty, TypeVisitable};
+use rustc_middle::ty::{self, EarlyBinder, SubstsRef, Ty, TypeVisitable};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::sym;
@@ -119,11 +119,18 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
let callee_ty_unadjusted = cx.typeck_results().expr_ty(callee).peel_refs();
if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc);
if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc);
+ if let ty::Closure(_, substs) = *closure_ty.kind();
then {
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| {
if let Some(mut snippet) = snippet_opt(cx, callee.span) {
if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait()
- && implements_trait(cx, callee_ty.peel_refs(), fn_mut_id, &[])
+ && let args = cx.tcx.erase_late_bound_regions(substs.as_closure().sig()).inputs()
+ && implements_trait(
+ cx,
+ callee_ty.peel_refs(),
+ fn_mut_id,
+ &args.iter().copied().map(Into::into).collect::<Vec<_>>(),
+ )
&& path_to_local(callee).map_or(false, |l| local_used_after_expr(cx, l, expr))
{
// Mutable closure is used after current expr; we cannot consume it.
@@ -150,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
if check_sig(cx, closure_ty, call_ty);
then {
span_lint_and_then(cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, "redundant closure", |diag| {
- let name = get_ufcs_type_name(cx, method_def_id);
+ let name = get_ufcs_type_name(cx, method_def_id, substs);
diag.span_suggestion(
expr.span,
"replace the closure with the method itself",
@@ -220,7 +227,7 @@ fn check_sig<'tcx>(cx: &LateContext<'tcx>, closure_ty: Ty<'tcx>, call_ty: Ty<'tc
cx.tcx.erase_late_bound_regions(closure_sig) == cx.tcx.erase_late_bound_regions(call_sig)
}
-fn get_ufcs_type_name(cx: &LateContext<'_>, method_def_id: DefId) -> String {
+fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, substs: SubstsRef<'tcx>) -> String {
let assoc_item = cx.tcx.associated_item(method_def_id);
let def_id = assoc_item.container_id(cx.tcx);
match assoc_item.container {
@@ -229,6 +236,15 @@ fn get_ufcs_type_name(cx: &LateContext<'_>, method_def_id: DefId) -> String {
let ty = cx.tcx.type_of(def_id);
match ty.kind() {
ty::Adt(adt, _) => cx.tcx.def_path_str(adt.did()),
+ ty::Array(..)
+ | ty::Dynamic(..)
+ | ty::Never
+ | ty::RawPtr(_)
+ | ty::Ref(..)
+ | ty::Slice(_)
+ | ty::Tuple(_) => {
+ format!("<{}>", EarlyBinder(ty).subst(cx.tcx, substs))
+ },
_ => ty.to_string(),
}
},
diff --git a/src/tools/clippy/clippy_lints/src/excessive_bools.rs b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
index 453471c8c..fc2912f69 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_bools.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
@@ -1,8 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_ast::ast::{AssocItemKind, Extern, Fn, FnSig, Impl, Item, ItemKind, Trait, Ty, TyKind};
-use rustc_lint::{EarlyContext, EarlyLintPass};
+use clippy_utils::{get_parent_as_impl, has_repr_attr, is_bool};
+use rustc_hir::intravisit::FnKind;
+use rustc_hir::{Body, FnDecl, HirId, Item, ItemKind, TraitFn, TraitItem, TraitItemKind, Ty};
+use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::{sym, Span};
+use rustc_span::Span;
+use rustc_target::spec::abi::Abi;
declare_clippy_lint! {
/// ### What it does
@@ -83,6 +86,12 @@ pub struct ExcessiveBools {
max_fn_params_bools: u64,
}
+#[derive(Eq, PartialEq, Debug, Copy, Clone)]
+enum Kind {
+ Struct,
+ Fn,
+}
+
impl ExcessiveBools {
#[must_use]
pub fn new(max_struct_bools: u64, max_fn_params_bools: u64) -> Self {
@@ -92,21 +101,20 @@ impl ExcessiveBools {
}
}
- fn check_fn_sig(&self, cx: &EarlyContext<'_>, fn_sig: &FnSig, span: Span) {
- match fn_sig.header.ext {
- Extern::Implicit(_) | Extern::Explicit(_, _) => return,
- Extern::None => (),
+ fn too_many_bools<'tcx>(&self, tys: impl Iterator<Item = &'tcx Ty<'tcx>>, kind: Kind) -> bool {
+ if let Ok(bools) = tys.filter(|ty| is_bool(ty)).count().try_into() {
+ (if Kind::Fn == kind {
+ self.max_fn_params_bools
+ } else {
+ self.max_struct_bools
+ }) < bools
+ } else {
+ false
}
+ }
- let fn_sig_bools = fn_sig
- .decl
- .inputs
- .iter()
- .filter(|param| is_bool_ty(&param.ty))
- .count()
- .try_into()
- .unwrap();
- if self.max_fn_params_bools < fn_sig_bools {
+ fn check_fn_sig(&self, cx: &LateContext<'_>, fn_decl: &FnDecl<'_>, span: Span) {
+ if !span.from_expansion() && self.too_many_bools(fn_decl.inputs.iter(), Kind::Fn) {
span_lint_and_help(
cx,
FN_PARAMS_EXCESSIVE_BOOLS,
@@ -121,56 +129,55 @@ impl ExcessiveBools {
impl_lint_pass!(ExcessiveBools => [STRUCT_EXCESSIVE_BOOLS, FN_PARAMS_EXCESSIVE_BOOLS]);
-fn is_bool_ty(ty: &Ty) -> bool {
- if let TyKind::Path(None, path) = &ty.kind {
- if let [name] = path.segments.as_slice() {
- return name.ident.name == sym::bool;
+impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
+ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+ if item.span.from_expansion() {
+ return;
+ }
+ if let ItemKind::Struct(variant_data, _) = &item.kind {
+ if has_repr_attr(cx, item.hir_id()) {
+ return;
+ }
+
+ if self.too_many_bools(variant_data.fields().iter().map(|field| field.ty), Kind::Struct) {
+ span_lint_and_help(
+ cx,
+ STRUCT_EXCESSIVE_BOOLS,
+ item.span,
+ &format!("more than {} bools in a struct", self.max_struct_bools),
+ None,
+ "consider using a state machine or refactoring bools into two-variant enums",
+ );
+ }
}
}
- false
-}
-impl EarlyLintPass for ExcessiveBools {
- fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
- if item.span.from_expansion() {
- return;
+ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'tcx>) {
+ // functions with a body are already checked by `check_fn`
+ if let TraitItemKind::Fn(fn_sig, TraitFn::Required(_)) = &trait_item.kind
+ && fn_sig.header.abi == Abi::Rust
+ {
+ self.check_fn_sig(cx, fn_sig.decl, fn_sig.span);
}
- match &item.kind {
- ItemKind::Struct(variant_data, _) => {
- if item.attrs.iter().any(|attr| attr.has_name(sym::repr)) {
- return;
- }
+ }
- let struct_bools = variant_data
- .fields()
- .iter()
- .filter(|field| is_bool_ty(&field.ty))
- .count()
- .try_into()
- .unwrap();
- if self.max_struct_bools < struct_bools {
- span_lint_and_help(
- cx,
- STRUCT_EXCESSIVE_BOOLS,
- item.span,
- &format!("more than {} bools in a struct", self.max_struct_bools),
- None,
- "consider using a state machine or refactoring bools into two-variant enums",
- );
- }
- },
- ItemKind::Impl(box Impl {
- of_trait: None, items, ..
- })
- | ItemKind::Trait(box Trait { items, .. }) => {
- for item in items {
- if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
- self.check_fn_sig(cx, sig, item.span);
- }
- }
- },
- ItemKind::Fn(box Fn { sig, .. }) => self.check_fn_sig(cx, sig, item.span),
- _ => (),
+ fn check_fn(
+ &mut self,
+ cx: &LateContext<'tcx>,
+ fn_kind: FnKind<'tcx>,
+ fn_decl: &'tcx FnDecl<'tcx>,
+ _: &'tcx Body<'tcx>,
+ span: Span,
+ hir_id: HirId,
+ ) {
+ if let Some(fn_header) = fn_kind.header()
+ && fn_header.abi == Abi::Rust
+ && get_parent_as_impl(cx.tcx, hir_id)
+ .map_or(true,
+ |impl_item| impl_item.of_trait.is_none()
+ )
+ {
+ self.check_fn_sig(cx, fn_decl, span);
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs
index 407dd1b39..9c8b0d076 100644
--- a/src/tools/clippy/clippy_lints/src/exit.rs
+++ b/src/tools/clippy/clippy_lints/src/exit.rs
@@ -7,21 +7,34 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
/// ### What it does
- /// `exit()` terminates the program and doesn't provide a
- /// stack trace.
+ /// Detects calls to the `exit()` function which terminates the program.
///
/// ### Why is this bad?
- /// Ideally a program is terminated by finishing
+ /// Exit terminates the program at the location it is called. For unrecoverable
+ /// errors `panics` should be used to provide a stacktrace and potentualy other
+ /// information. A normal termination or one with an error code should happen in
/// the main function.
///
/// ### Example
- /// ```ignore
+ /// ```
/// std::process::exit(0)
/// ```
+ ///
+ /// Use instead:
+ ///
+ /// ```ignore
+ /// // To provide a stacktrace and additional information
+ /// panic!("message");
+ ///
+ /// // or a main method with a return
+ /// fn main() -> Result<(), i32> {
+ /// Ok(())
+ /// }
+ /// ```
#[clippy::version = "1.41.0"]
pub EXIT,
restriction,
- "`std::process::exit` is called, terminating the program"
+ "detects `std::process::exit` calls"
}
declare_lint_pass!(Exit => [EXIT]);
diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
index 0a633f242..9a1058470 100644
--- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
+++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
@@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom {
}
}
-fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[hir::ImplItemRef]) {
+fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::ImplItemRef]) {
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Expr, ImplItemKind};
diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs
index bc0c68f53..d0fab6949 100644
--- a/src/tools/clippy/clippy_lints/src/format.rs
+++ b/src/tools/clippy/clippy_lints/src/format.rs
@@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
if format_args.format_string.parts == [kw::Empty];
if arg.format.is_default();
if match cx.typeck_results().expr_ty(value).peel_refs().kind() {
- ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did()),
+ ty::Adt(adt, _) => Some(adt.did()) == cx.tcx.lang_items().string(),
ty::Str => true,
_ => false,
};
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index f0fe845d3..658fe2680 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -1,19 +1,22 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::macros::FormatParamKind::{Implicit, Named, Numbered, Starred};
+use clippy_utils::is_diag_trait_item;
+use clippy_utils::macros::FormatParamKind::{Implicit, Named, NamedInline, Numbered, Starred};
use clippy_utils::macros::{
is_format_macro, is_panic, root_macro_call, Count, FormatArg, FormatArgsExpn, FormatParam, FormatParamUsage,
};
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
-use clippy_utils::{is_diag_trait_item, meets_msrv, msrvs};
use if_chain::if_chain;
use itertools::Itertools;
-use rustc_errors::Applicability;
+use rustc_errors::{
+ Applicability,
+ SuggestionStyle::{CompletelyHidden, ShowCode},
+};
use rustc_hir::{Expr, ExprKind, HirId, QPath};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
use rustc_middle::ty::Ty;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::def_id::DefId;
use rustc_span::edition::Edition::Edition2021;
@@ -103,14 +106,20 @@ declare_clippy_lint! {
/// format!("{var:.prec$}");
/// ```
///
- /// ### Known Problems
- ///
- /// There may be a false positive if the format string is expanded from certain proc macros:
- ///
- /// ```ignore
- /// println!(indoc!("{}"), var);
+ /// If allow-mixed-uninlined-format-args is set to false in clippy.toml,
+ /// the following code will also trigger the lint:
+ /// ```rust
+ /// # let var = 42;
+ /// format!("{} {}", var, 1+2);
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// # let var = 42;
+ /// format!("{var} {}", 1+2);
/// ```
///
+ /// ### Known Problems
+ ///
/// If a format string contains a numbered argument that cannot be inlined
/// nothing will be suggested, e.g. `println!("{0}={1}", var, 1+2)`.
#[clippy::version = "1.65.0"]
@@ -158,13 +167,17 @@ impl_lint_pass!(FormatArgs => [
]);
pub struct FormatArgs {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
+ ignore_mixed: bool,
}
impl FormatArgs {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
- Self { msrv }
+ pub fn new(msrv: Msrv, allow_mixed_uninlined_format_args: bool) -> Self {
+ Self {
+ msrv,
+ ignore_mixed: allow_mixed_uninlined_format_args,
+ }
}
}
@@ -188,8 +201,8 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
check_format_in_format_args(cx, outermost_expn_data.call_site, name, arg.param.value);
check_to_string_in_format_args(cx, name, arg.param.value);
}
- if meets_msrv(self.msrv, msrvs::FORMAT_ARGS_CAPTURE) {
- check_uninlined_args(cx, &format_args, outermost_expn_data.call_site, macro_def_id);
+ if self.msrv.meets(msrvs::FORMAT_ARGS_CAPTURE) {
+ check_uninlined_args(cx, &format_args, outermost_expn_data.call_site, macro_def_id, self.ignore_mixed);
}
}
}
@@ -267,7 +280,13 @@ fn check_unused_format_specifier(cx: &LateContext<'_>, arg: &FormatArg<'_>) {
}
}
-fn check_uninlined_args(cx: &LateContext<'_>, args: &FormatArgsExpn<'_>, call_site: Span, def_id: DefId) {
+fn check_uninlined_args(
+ cx: &LateContext<'_>,
+ args: &FormatArgsExpn<'_>,
+ call_site: Span,
+ def_id: DefId,
+ ignore_mixed: bool,
+) {
if args.format_string.span.from_expansion() {
return;
}
@@ -282,14 +301,13 @@ fn check_uninlined_args(cx: &LateContext<'_>, args: &FormatArgsExpn<'_>, call_si
// we cannot remove any other arguments in the format string,
// because the index numbers might be wrong after inlining.
// Example of an un-inlinable format: print!("{}{1}", foo, 2)
- if !args.params().all(|p| check_one_arg(args, &p, &mut fixes)) || fixes.is_empty() {
+ if !args.params().all(|p| check_one_arg(args, &p, &mut fixes, ignore_mixed)) || fixes.is_empty() {
return;
}
- // Temporarily ignore multiline spans: https://github.com/rust-lang/rust/pull/102729#discussion_r988704308
- if fixes.iter().any(|(span, _)| cx.sess().source_map().is_multiline(*span)) {
- return;
- }
+ // multiline span display suggestion is sometimes broken: https://github.com/rust-lang/rust/pull/102729#discussion_r988704308
+ // in those cases, make the code suggestion hidden
+ let multiline_fix = fixes.iter().any(|(span, _)| cx.sess().source_map().is_multiline(*span));
span_lint_and_then(
cx,
@@ -297,12 +315,22 @@ fn check_uninlined_args(cx: &LateContext<'_>, args: &FormatArgsExpn<'_>, call_si
call_site,
"variables can be used directly in the `format!` string",
|diag| {
- diag.multipart_suggestion("change this to", fixes, Applicability::MachineApplicable);
+ diag.multipart_suggestion_with_style(
+ "change this to",
+ fixes,
+ Applicability::MachineApplicable,
+ if multiline_fix { CompletelyHidden } else { ShowCode },
+ );
},
);
}
-fn check_one_arg(args: &FormatArgsExpn<'_>, param: &FormatParam<'_>, fixes: &mut Vec<(Span, String)>) -> bool {
+fn check_one_arg(
+ args: &FormatArgsExpn<'_>,
+ param: &FormatParam<'_>,
+ fixes: &mut Vec<(Span, String)>,
+ ignore_mixed: bool,
+) -> bool {
if matches!(param.kind, Implicit | Starred | Named(_) | Numbered)
&& let ExprKind::Path(QPath::Resolved(None, path)) = param.value.kind
&& let [segment] = path.segments
@@ -317,8 +345,10 @@ fn check_one_arg(args: &FormatArgsExpn<'_>, param: &FormatParam<'_>, fixes: &mut
fixes.push((arg_span, String::new()));
true // successful inlining, continue checking
} else {
- // if we can't inline a numbered argument, we can't continue
- param.kind != Numbered
+ // Do not continue inlining (return false) in case
+ // * if we can't inline a numbered argument, e.g. `print!("{0} ...", foo.bar, ...)`
+ // * if allow_mixed_uninlined_format_args is false and this arg hasn't been inlined already
+ param.kind != Numbered && (!ignore_mixed || matches!(param.kind, NamedInline(_)))
}
}
diff --git a/src/tools/clippy/clippy_lints/src/format_push_string.rs b/src/tools/clippy/clippy_lints/src/format_push_string.rs
index 9b9f1872b..68c5c3673 100644
--- a/src/tools/clippy/clippy_lints/src/format_push_string.rs
+++ b/src/tools/clippy/clippy_lints/src/format_push_string.rs
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{match_def_path, paths, peel_hir_expr_refs};
-use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
@@ -41,7 +41,7 @@ declare_clippy_lint! {
declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]);
fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
- is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), sym::String)
+ is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
}
fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
if let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id {
diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs
index 8b24a4962..0634b2798 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -1,7 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::macros::span_is_local;
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::path_def_id;
use clippy_utils::source::snippet_opt;
-use clippy_utils::{meets_msrv, msrvs, path_def_id};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_path, Visitor};
use rustc_hir::{
@@ -10,7 +11,6 @@ use rustc_hir::{
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter::OnlyBodies;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::{kw, sym};
use rustc_span::{Span, Symbol};
@@ -49,12 +49,12 @@ declare_clippy_lint! {
}
pub struct FromOverInto {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl FromOverInto {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
FromOverInto { msrv }
}
}
@@ -63,7 +63,7 @@ impl_lint_pass!(FromOverInto => [FROM_OVER_INTO]);
impl<'tcx> LateLintPass<'tcx> for FromOverInto {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
- if !meets_msrv(self.msrv, msrvs::RE_REBALANCING_COHERENCE) || !span_is_local(item.span) {
+ if !self.msrv.meets(msrvs::RE_REBALANCING_COHERENCE) || !span_is_local(item.span) {
return;
}
@@ -126,7 +126,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SelfFinder<'a, 'tcx> {
self.cx.tcx.hir()
}
- fn visit_path(&mut self, path: &'tcx Path<'tcx>, _id: HirId) {
+ fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
for segment in path.segments {
match segment.ident.name {
kw::SelfLower => self.lower.push(segment.ident.span),
diff --git a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs
new file mode 100644
index 000000000..00f5ba564
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs
@@ -0,0 +1,77 @@
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::ty::is_c_void;
+use clippy_utils::{match_def_path, path_def_id, paths};
+use rustc_hir::def_id::DefId;
+use rustc_hir::{Expr, ExprKind, QPath};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::RawPtr;
+use rustc_middle::ty::TypeAndMut;
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::sym;
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks if we're passing a `c_void` raw pointer to `{Box,Rc,Arc,Weak}::from_raw(_)`
+ ///
+ /// ### Why is this bad?
+ /// When dealing with `c_void` raw pointers in FFI, it is easy to run into the pitfall of calling `from_raw` with the `c_void` pointer.
+ /// The type signature of `Box::from_raw` is `fn from_raw(raw: *mut T) -> Box<T>`, so if you pass a `*mut c_void` you will get a `Box<c_void>` (and similarly for `Rc`, `Arc` and `Weak`).
+ /// For this to be safe, `c_void` would need to have the same memory layout as the original type, which is often not the case.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # use std::ffi::c_void;
+ /// let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;
+ /// let _ = unsafe { Box::from_raw(ptr) };
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// # use std::ffi::c_void;
+ /// # let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;
+ /// let _ = unsafe { Box::from_raw(ptr as *mut usize) };
+ /// ```
+ ///
+ #[clippy::version = "1.66.0"]
+ pub FROM_RAW_WITH_VOID_PTR,
+ suspicious,
+ "creating a `Box` from a void raw pointer"
+}
+declare_lint_pass!(FromRawWithVoidPtr => [FROM_RAW_WITH_VOID_PTR]);
+
+impl LateLintPass<'_> for FromRawWithVoidPtr {
+ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+ if let ExprKind::Call(box_from_raw, [arg]) = expr.kind
+ && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_from_raw.kind
+ && seg.ident.name == sym!(from_raw)
+ && let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id))
+ && let arg_kind = cx.typeck_results().expr_ty(arg).kind()
+ && let RawPtr(TypeAndMut { ty, .. }) = arg_kind
+ && is_c_void(cx, *ty) {
+ let msg = format!("creating a `{type_str}` from a void raw pointer");
+ span_lint_and_help(cx, FROM_RAW_WITH_VOID_PTR, expr.span, &msg, Some(arg.span), "cast this to a pointer of the appropriate type");
+ }
+ }
+}
+
+/// Checks whether a `DefId` matches `Box`, `Rc`, `Arc`, or one of the `Weak` types.
+/// Returns a static string slice with the name of the type, if one was found.
+fn def_id_matches_type(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static str> {
+ // Box
+ if Some(def_id) == cx.tcx.lang_items().owned_box() {
+ return Some("Box");
+ }
+
+ if let Some(symbol) = cx.tcx.get_diagnostic_name(def_id) {
+ if symbol == sym::Arc {
+ return Some("Arc");
+ } else if symbol == sym::Rc {
+ return Some("Rc");
+ }
+ }
+
+ if match_def_path(cx, def_id, &paths::WEAK_RC) || match_def_path(cx, def_id, &paths::WEAK_ARC) {
+ Some("Weak")
+ } else {
+ None
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs b/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
index cf8b7acd6..74a60b6a0 100644
--- a/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
+++ b/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
@@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_integer_literal;
use clippy_utils::sugg::Sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use if_chain::if_chain;
use rustc_errors::Applicability;
-use rustc_hir::{def, Expr, ExprKind, PrimTy, QPath, TyKind};
+use rustc_hir::{def, Expr, ExprKind, LangItem, PrimTy, QPath, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -98,5 +98,5 @@ impl<'tcx> LateLintPass<'tcx> for FromStrRadix10 {
/// Checks if a Ty is `String` or `&str`
fn is_ty_stringish(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
- is_type_diagnostic_item(cx, ty, sym::String) || is_type_diagnostic_item(cx, ty, sym::str)
+ is_type_lang_item(cx, ty, LangItem::String) || is_type_diagnostic_item(cx, ty, sym::str)
}
diff --git a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs
new file mode 100644
index 000000000..27acad45c
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs
@@ -0,0 +1,125 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::snippet;
+use rustc_errors::Applicability;
+use rustc_hir::{intravisit::FnKind, Body, ExprKind, FnDecl, HirId, ImplicitSelfKind, Unsafety};
+use rustc_lint::LateContext;
+use rustc_middle::ty;
+use rustc_span::Span;
+
+use std::iter;
+
+use super::MISNAMED_GETTERS;
+
+pub fn check_fn(
+ cx: &LateContext<'_>,
+ kind: FnKind<'_>,
+ decl: &FnDecl<'_>,
+ body: &Body<'_>,
+ span: Span,
+ _hir_id: HirId,
+) {
+ let FnKind::Method(ref ident, sig) = kind else {
+ return;
+ };
+
+ // Takes only &(mut) self
+ if decl.inputs.len() != 1 {
+ return;
+ }
+
+ let name = ident.name.as_str();
+
+ let name = match decl.implicit_self {
+ ImplicitSelfKind::MutRef => {
+ let Some(name) = name.strip_suffix("_mut") else {
+ return;
+ };
+ name
+ },
+ ImplicitSelfKind::Imm | ImplicitSelfKind::Mut | ImplicitSelfKind::ImmRef => name,
+ ImplicitSelfKind::None => return,
+ };
+
+ let name = if sig.header.unsafety == Unsafety::Unsafe {
+ name.strip_suffix("_unchecked").unwrap_or(name)
+ } else {
+ name
+ };
+
+ // Body must be &(mut) <self_data>.name
+ // self_data is not neccessarilly self, to also lint sub-getters, etc…
+
+ let block_expr = if_chain! {
+ if let ExprKind::Block(block,_) = body.value.kind;
+ if block.stmts.is_empty();
+ if let Some(block_expr) = block.expr;
+ then {
+ block_expr
+ } else {
+ return;
+ }
+ };
+ let expr_span = block_expr.span;
+
+ // Accept &<expr>, &mut <expr> and <expr>
+ let expr = if let ExprKind::AddrOf(_, _, tmp) = block_expr.kind {
+ tmp
+ } else {
+ block_expr
+ };
+ let (self_data, used_ident) = if_chain! {
+ if let ExprKind::Field(self_data, ident) = expr.kind;
+ if ident.name.as_str() != name;
+ then {
+ (self_data, ident)
+ } else {
+ return;
+ }
+ };
+
+ let mut used_field = None;
+ let mut correct_field = None;
+ let typeck_results = cx.typeck_results();
+ for adjusted_type in iter::once(typeck_results.expr_ty(self_data))
+ .chain(typeck_results.expr_adjustments(self_data).iter().map(|adj| adj.target))
+ {
+ let ty::Adt(def,_) = adjusted_type.kind() else {
+ continue;
+ };
+
+ for f in def.all_fields() {
+ if f.name.as_str() == name {
+ correct_field = Some(f);
+ }
+ if f.name == used_ident.name {
+ used_field = Some(f);
+ }
+ }
+ }
+
+ let Some(used_field) = used_field else {
+ // Can happen if the field access is a tuple. We don't lint those because the getter name could not start with a number.
+ return;
+ };
+
+ let Some(correct_field) = correct_field else {
+ // There is no field corresponding to the getter name.
+ // FIXME: This can be a false positive if the correct field is reachable trought deeper autodereferences than used_field is
+ return;
+ };
+
+ if cx.tcx.type_of(used_field.did) == cx.tcx.type_of(correct_field.did) {
+ let left_span = block_expr.span.until(used_ident.span);
+ let snippet = snippet(cx, left_span, "..");
+ let sugg = format!("{snippet}{name}");
+ span_lint_and_then(
+ cx,
+ MISNAMED_GETTERS,
+ span,
+ "getter function appears to return the wrong field",
+ |diag| {
+ diag.span_suggestion(expr_span, "consider using", sugg, Applicability::MaybeIncorrect);
+ },
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/functions/mod.rs b/src/tools/clippy/clippy_lints/src/functions/mod.rs
index 90911e0bf..91e6ffe64 100644
--- a/src/tools/clippy/clippy_lints/src/functions/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/mod.rs
@@ -1,3 +1,4 @@
+mod misnamed_getters;
mod must_use;
mod not_unsafe_ptr_arg_deref;
mod result;
@@ -254,12 +255,54 @@ declare_clippy_lint! {
/// Ok(())
/// }
/// ```
- #[clippy::version = "1.64.0"]
+ #[clippy::version = "1.65.0"]
pub RESULT_LARGE_ERR,
perf,
"function returning `Result` with large `Err` type"
}
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for getter methods that return a field that doesn't correspond
+ /// to the name of the method, when there is a field's whose name matches that of the method.
+ ///
+ /// ### Why is this bad?
+ /// It is most likely that such a method is a bug caused by a typo or by copy-pasting.
+ ///
+ /// ### Example
+
+ /// ```rust
+ /// struct A {
+ /// a: String,
+ /// b: String,
+ /// }
+ ///
+ /// impl A {
+ /// fn a(&self) -> &str{
+ /// &self.b
+ /// }
+ /// }
+
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// struct A {
+ /// a: String,
+ /// b: String,
+ /// }
+ ///
+ /// impl A {
+ /// fn a(&self) -> &str{
+ /// &self.a
+ /// }
+ /// }
+ /// ```
+ #[clippy::version = "1.67.0"]
+ pub MISNAMED_GETTERS,
+ suspicious,
+ "getter method returning the wrong field"
+}
+
#[derive(Copy, Clone)]
pub struct Functions {
too_many_arguments_threshold: u64,
@@ -286,6 +329,7 @@ impl_lint_pass!(Functions => [
MUST_USE_CANDIDATE,
RESULT_UNIT_ERR,
RESULT_LARGE_ERR,
+ MISNAMED_GETTERS,
]);
impl<'tcx> LateLintPass<'tcx> for Functions {
@@ -301,6 +345,7 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
too_many_arguments::check_fn(cx, kind, decl, span, hir_id, self.too_many_arguments_threshold);
too_many_lines::check_fn(cx, kind, span, body, self.too_many_lines_threshold);
not_unsafe_ptr_arg_deref::check_fn(cx, kind, decl, body, hir_id);
+ misnamed_getters::check_fn(cx, kind, decl, body, span, hir_id);
}
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index bff69f915..d22bede36 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -50,7 +50,9 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
if let Some(attr) = attr {
check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
- } else if is_public && !is_proc_macro(cx.sess(), attrs) && trait_ref_of_method(cx, item.owner_id.def_id).is_none()
+ } else if is_public
+ && !is_proc_macro(cx.sess(), attrs)
+ && trait_ref_of_method(cx, item.owner_id.def_id).is_none()
{
check_must_use_candidate(
cx,
@@ -175,7 +177,7 @@ fn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut DefIdSet)
return false; // ignore `_` patterns
}
if cx.tcx.has_typeck_results(pat.hir_id.owner.to_def_id()) {
- is_mutable_ty(cx, cx.tcx.typeck(pat.hir_id.owner.def_id).pat_ty(pat), pat.span, tys)
+ is_mutable_ty(cx, cx.tcx.typeck(pat.hir_id.owner.def_id).pat_ty(pat), tys)
} else {
false
}
@@ -183,7 +185,7 @@ fn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut DefIdSet)
static KNOWN_WRAPPER_TYS: &[Symbol] = &[sym::Rc, sym::Arc];
-fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, tys: &mut DefIdSet) -> bool {
+fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet) -> bool {
match *ty.kind() {
// primitive types are never mutable
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
@@ -192,12 +194,12 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, tys: &m
|| KNOWN_WRAPPER_TYS
.iter()
.any(|&sym| cx.tcx.is_diagnostic_item(sym, adt.did()))
- && substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys))
+ && substs.types().any(|ty| is_mutable_ty(cx, ty, tys))
},
- ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, span, tys)),
- ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, span, tys),
+ ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, tys)),
+ ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, tys),
ty::RawPtr(ty::TypeAndMut { ty, mutbl }) | ty::Ref(_, ty, mutbl) => {
- mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, span, tys)
+ mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys)
},
// calling something constitutes a side effect, so return true on all callables
// also never calls need not be used, so return true for them, too
@@ -225,12 +227,7 @@ fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bo
let mut tys = DefIdSet::default();
for arg in args {
if cx.tcx.has_typeck_results(arg.hir_id.owner.to_def_id())
- && is_mutable_ty(
- cx,
- cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg),
- arg.span,
- &mut tys,
- )
+ && is_mutable_ty(cx, cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg), &mut tys)
&& is_mutated_static(arg)
{
return ControlFlow::Break(());
@@ -243,12 +240,7 @@ fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bo
let mut tys = DefIdSet::default();
for arg in std::iter::once(receiver).chain(args.iter()) {
if cx.tcx.has_typeck_results(arg.hir_id.owner.to_def_id())
- && is_mutable_ty(
- cx,
- cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg),
- arg.span,
- &mut tys,
- )
+ && is_mutable_ty(cx, cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg), &mut tys)
&& is_mutated_static(arg)
{
return ControlFlow::Break(());
diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs
index 5c63fb2ac..23da145d0 100644
--- a/src/tools/clippy/clippy_lints/src/functions/result.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/result.rs
@@ -2,12 +2,12 @@ use rustc_errors::Diagnostic;
use rustc_hir as hir;
use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::{self, Adt, Ty};
use rustc_span::{sym, Span};
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
use clippy_utils::trait_ref_of_method;
-use clippy_utils::ty::{approx_ty_size, is_type_diagnostic_item};
+use clippy_utils::ty::{approx_ty_size, is_type_diagnostic_item, AdtVariantInfo};
use super::{RESULT_LARGE_ERR, RESULT_UNIT_ERR};
@@ -84,17 +84,59 @@ fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: S
}
fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty_span: Span, large_err_threshold: u64) {
- let ty_size = approx_ty_size(cx, err_ty);
- if ty_size >= large_err_threshold {
- span_lint_and_then(
- cx,
- RESULT_LARGE_ERR,
- hir_ty_span,
- "the `Err`-variant returned from this function is very large",
- |diag: &mut Diagnostic| {
- diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes"));
- diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
- },
- );
+ if_chain! {
+ if let Adt(adt, subst) = err_ty.kind();
+ if let Some(local_def_id) = err_ty.ty_adt_def().expect("already checked this is adt").did().as_local();
+ if let Some(hir::Node::Item(item)) = cx
+ .tcx
+ .hir()
+ .find_by_def_id(local_def_id);
+ if let hir::ItemKind::Enum(ref def, _) = item.kind;
+ then {
+ let variants_size = AdtVariantInfo::new(cx, *adt, subst);
+ if let Some((first_variant, variants)) = variants_size.split_first()
+ && first_variant.size >= large_err_threshold
+ {
+ span_lint_and_then(
+ cx,
+ RESULT_LARGE_ERR,
+ hir_ty_span,
+ "the `Err`-variant returned from this function is very large",
+ |diag| {
+ diag.span_label(
+ def.variants[first_variant.ind].span,
+ format!("the largest variant contains at least {} bytes", variants_size[0].size),
+ );
+
+ for variant in variants {
+ if variant.size >= large_err_threshold {
+ let variant_def = &def.variants[variant.ind];
+ diag.span_label(
+ variant_def.span,
+ format!("the variant `{}` contains at least {} bytes", variant_def.ident, variant.size),
+ );
+ }
+ }
+
+ diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
+ }
+ );
+ }
+ }
+ else {
+ let ty_size = approx_ty_size(cx, err_ty);
+ if ty_size >= large_err_threshold {
+ span_lint_and_then(
+ cx,
+ RESULT_LARGE_ERR,
+ hir_ty_span,
+ "the `Err`-variant returned from this function is very large",
+ |diag: &mut Diagnostic| {
+ diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes"));
+ diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
+ },
+ );
+ }
+ }
}
}
diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs
index 0519f9ac2..61934a914 100644
--- a/src/tools/clippy/clippy_lints/src/future_not_send.rs
+++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs
@@ -4,7 +4,7 @@ use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, FnDecl, HirId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{EarlyBinder, Opaque, PredicateKind::Trait};
+use rustc_middle::ty::{Clause, EarlyBinder, Opaque, PredicateKind};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, Span};
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
@@ -91,7 +91,9 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
infcx
.err_ctxt()
.maybe_note_obligation_cause_for_async_await(db, &obligation);
- if let Trait(trait_pred) = obligation.predicate.kind().skip_binder() {
+ if let PredicateKind::Clause(Clause::Trait(trait_pred)) =
+ obligation.predicate.kind().skip_binder()
+ {
db.note(&format!(
"`{}` doesn't implement `{}`",
trait_pred.self_ty(),
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 0d6718c16..9cadaaa49 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
@@ -1,14 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_macro_callsite;
-use clippy_utils::{
- contains_return, higher, is_else_clause, is_res_lang_ctor, meets_msrv, msrvs, path_res, peel_blocks,
-};
+use clippy_utils::{contains_return, higher, is_else_clause, is_res_lang_ctor, path_res, peel_blocks};
use rustc_hir::LangItem::{OptionNone, OptionSome};
use rustc_hir::{Expr, ExprKind, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! {
@@ -47,12 +45,12 @@ declare_clippy_lint! {
}
pub struct IfThenSomeElseNone {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl IfThenSomeElseNone {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -61,7 +59,7 @@ impl_lint_pass!(IfThenSomeElseNone => [IF_THEN_SOME_ELSE_NONE]);
impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
- if !meets_msrv(self.msrv, msrvs::BOOL_THEN) {
+ if !self.msrv.meets(msrvs::BOOL_THEN) {
return;
}
@@ -94,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
} else {
format!("{{ /* snippet */ {arg_snip} }}")
};
- let method_name = if switch_to_eager_eval(cx, expr) && meets_msrv(self.msrv, msrvs::BOOL_THEN_SOME) {
+ let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(msrvs::BOOL_THEN_SOME) {
"then_some"
} else {
method_body.insert_str(0, "|| ");
diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
index 94e06cf70..64a4a3fa7 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
@@ -66,8 +66,8 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
use rustc_span::BytePos;
- fn suggestion<'tcx>(
- cx: &LateContext<'tcx>,
+ fn suggestion(
+ cx: &LateContext<'_>,
diag: &mut Diagnostic,
generics_span: Span,
generics_suggestion_span: Span,
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index c7b5badaa..cf35b1f17 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -1,8 +1,9 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::IfLet;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::is_copy;
-use clippy_utils::{is_expn_of, is_lint_allowed, meets_msrv, msrvs, path_to_local};
+use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local};
use if_chain::if_chain;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_errors::Applicability;
@@ -11,7 +12,6 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{symbol::Ident, Span};
@@ -47,18 +47,17 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "1.59.0"]
pub INDEX_REFUTABLE_SLICE,
- nursery,
+ pedantic,
"avoid indexing on slices which could be destructed"
}
-#[derive(Copy, Clone)]
pub struct IndexRefutableSlice {
max_suggested_slice: u64,
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl IndexRefutableSlice {
- pub fn new(max_suggested_slice_pattern_length: u64, msrv: Option<RustcVersion>) -> Self {
+ pub fn new(max_suggested_slice_pattern_length: u64, msrv: Msrv) -> Self {
Self {
max_suggested_slice: max_suggested_slice_pattern_length,
msrv,
@@ -74,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexRefutableSlice {
if !expr.span.from_expansion() || is_expn_of(expr.span, "if_chain").is_some();
if let Some(IfLet {let_pat, if_then, ..}) = IfLet::hir(cx, expr);
if !is_lint_allowed(cx, INDEX_REFUTABLE_SLICE, expr.hir_id);
- if meets_msrv(self.msrv, msrvs::SLICE_PATTERNS);
+ if self.msrv.meets(msrvs::SLICE_PATTERNS);
let found_slices = find_slice_values(cx, let_pat);
if !found_slices.is_empty();
@@ -207,8 +206,8 @@ impl SliceLintInformation {
}
}
-fn filter_lintable_slices<'a, 'tcx>(
- cx: &'a LateContext<'tcx>,
+fn filter_lintable_slices<'tcx>(
+ cx: &LateContext<'tcx>,
slice_lint_info: FxIndexMap<hir::HirId, SliceLintInformation>,
max_suggested_slice: u64,
scope: &'tcx hir::Expr<'tcx>,
diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
index af40a5a81..4cd7dff4c 100644
--- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
@@ -171,11 +171,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
/// Returns a tuple of options with the start and end (exclusive) values of
/// the range. If the start or end is not constant, None is returned.
-fn to_const_range<'tcx>(
- cx: &LateContext<'tcx>,
- range: higher::Range<'_>,
- array_size: u128,
-) -> (Option<u128>, Option<u128>) {
+fn to_const_range(cx: &LateContext<'_>, range: higher::Range<'_>, array_size: u128) -> (Option<u128>, Option<u128>) {
let s = range
.start
.map(|expr| constant(cx, cx.typeck_results(), expr).map(|(c, _)| c));
diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
index 14a37f535..aaecc4fa8 100644
--- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
@@ -1,8 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
+use clippy_utils::ty::{implements_trait, is_type_lang_item};
use clippy_utils::{return_ty, trait_ref_of_method};
use if_chain::if_chain;
-use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind};
+use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
@@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }));
// Check if return type is String
- if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::String);
+ if is_type_lang_item(cx, return_ty(cx, impl_item.hir_id()), LangItem::String);
// Filters instances of to_string which are required by a trait
if trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none();
diff --git a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
new file mode 100644
index 000000000..dd1b23e7d
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
@@ -0,0 +1,182 @@
+use clippy_utils::diagnostics::{self, span_lint_and_sugg};
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::source;
+use clippy_utils::sugg::Sugg;
+use clippy_utils::ty;
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{source_map::Spanned, sym};
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Lints subtraction between `Instant::now()` and another `Instant`.
+ ///
+ /// ### Why is this bad?
+ /// It is easy to accidentally write `prev_instant - Instant::now()`, which will always be 0ns
+ /// as `Instant` subtraction saturates.
+ ///
+ /// `prev_instant.elapsed()` also more clearly signals intention.
+ ///
+ /// ### Example
+ /// ```rust
+ /// use std::time::Instant;
+ /// let prev_instant = Instant::now();
+ /// let duration = Instant::now() - prev_instant;
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// use std::time::Instant;
+ /// let prev_instant = Instant::now();
+ /// let duration = prev_instant.elapsed();
+ /// ```
+ #[clippy::version = "1.65.0"]
+ pub MANUAL_INSTANT_ELAPSED,
+ pedantic,
+ "subtraction between `Instant::now()` and previous `Instant`"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Lints subtraction between an [`Instant`] and a [`Duration`].
+ ///
+ /// ### Why is this bad?
+ /// Unchecked subtraction could cause underflow on certain platforms, leading to
+ /// unintentional panics.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # use std::time::{Instant, Duration};
+ /// let time_passed = Instant::now() - Duration::from_secs(5);
+ /// ```
+ ///
+ /// Use instead:
+ /// ```rust
+ /// # use std::time::{Instant, Duration};
+ /// let time_passed = Instant::now().checked_sub(Duration::from_secs(5));
+ /// ```
+ ///
+ /// [`Duration`]: std::time::Duration
+ /// [`Instant::now()`]: std::time::Instant::now;
+ #[clippy::version = "1.65.0"]
+ pub UNCHECKED_DURATION_SUBTRACTION,
+ suspicious,
+ "finds unchecked subtraction of a 'Duration' from an 'Instant'"
+}
+
+pub struct InstantSubtraction {
+ msrv: Msrv,
+}
+
+impl InstantSubtraction {
+ #[must_use]
+ pub fn new(msrv: Msrv) -> Self {
+ Self { msrv }
+ }
+}
+
+impl_lint_pass!(InstantSubtraction => [MANUAL_INSTANT_ELAPSED, UNCHECKED_DURATION_SUBTRACTION]);
+
+impl LateLintPass<'_> for InstantSubtraction {
+ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
+ if let ExprKind::Binary(
+ Spanned {
+ node: BinOpKind::Sub, ..
+ },
+ lhs,
+ rhs,
+ ) = expr.kind
+ {
+ if_chain! {
+ if is_instant_now_call(cx, lhs);
+
+ if is_an_instant(cx, rhs);
+ if let Some(sugg) = Sugg::hir_opt(cx, rhs);
+
+ then {
+ print_manual_instant_elapsed_sugg(cx, expr, sugg)
+ } else {
+ if_chain! {
+ if !expr.span.from_expansion();
+ if self.msrv.meets(msrvs::TRY_FROM);
+
+ if is_an_instant(cx, lhs);
+ if is_a_duration(cx, rhs);
+
+ then {
+ print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ extract_msrv_attr!(LateContext);
+}
+
+fn is_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool {
+ if let ExprKind::Call(fn_expr, []) = expr_block.kind
+ && let Some(fn_id) = clippy_utils::path_def_id(cx, fn_expr)
+ && clippy_utils::match_def_path(cx, fn_id, &clippy_utils::paths::INSTANT_NOW)
+ {
+ true
+ } else {
+ false
+ }
+}
+
+fn is_an_instant(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+ let expr_ty = cx.typeck_results().expr_ty(expr);
+
+ match expr_ty.kind() {
+ rustc_middle::ty::Adt(def, _) => clippy_utils::match_def_path(cx, def.did(), &clippy_utils::paths::INSTANT),
+ _ => false,
+ }
+}
+
+fn is_a_duration(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+ let expr_ty = cx.typeck_results().expr_ty(expr);
+ ty::is_type_diagnostic_item(cx, expr_ty, sym::Duration)
+}
+
+fn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, sugg: Sugg<'_>) {
+ span_lint_and_sugg(
+ cx,
+ MANUAL_INSTANT_ELAPSED,
+ expr.span,
+ "manual implementation of `Instant::elapsed`",
+ "try",
+ format!("{}.elapsed()", sugg.maybe_par()),
+ Applicability::MachineApplicable,
+ );
+}
+
+fn print_unchecked_duration_subtraction_sugg(
+ cx: &LateContext<'_>,
+ left_expr: &Expr<'_>,
+ right_expr: &Expr<'_>,
+ expr: &Expr<'_>,
+) {
+ let mut applicability = Applicability::MachineApplicable;
+
+ let left_expr =
+ source::snippet_with_applicability(cx, left_expr.span, "std::time::Instant::now()", &mut applicability);
+ let right_expr = source::snippet_with_applicability(
+ cx,
+ right_expr.span,
+ "std::time::Duration::from_secs(1)",
+ &mut applicability,
+ );
+
+ diagnostics::span_lint_and_sugg(
+ cx,
+ UNCHECKED_DURATION_SUBTRACTION,
+ expr.span,
+ "unchecked subtraction of a 'Duration' from an 'Instant'",
+ "try",
+ format!("{left_expr}.checked_sub({right_expr}).unwrap()"),
+ applicability,
+ );
+}
diff --git a/src/tools/clippy/clippy_lints/src/int_plus_one.rs b/src/tools/clippy/clippy_lints/src/int_plus_one.rs
index 33491da3f..1b14e525d 100644
--- a/src/tools/clippy/clippy_lints/src/int_plus_one.rs
+++ b/src/tools/clippy/clippy_lints/src/int_plus_one.rs
@@ -2,7 +2,8 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_opt;
-use rustc_ast::ast::{BinOpKind, Expr, ExprKind, Lit, LitKind};
+use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind};
+use rustc_ast::token;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -52,8 +53,8 @@ enum Side {
impl IntPlusOne {
#[expect(clippy::cast_sign_loss)]
- fn check_lit(lit: &Lit, target_value: i128) -> bool {
- if let LitKind::Int(value, ..) = lit.kind {
+ fn check_lit(token_lit: token::Lit, target_value: i128) -> bool {
+ if let Ok(LitKind::Int(value, ..)) = LitKind::from_token_lit(token_lit) {
return value == (target_value as u128);
}
false
@@ -62,58 +63,54 @@ impl IntPlusOne {
fn check_binop(cx: &EarlyContext<'_>, binop: BinOpKind, lhs: &Expr, rhs: &Expr) -> Option<String> {
match (binop, &lhs.kind, &rhs.kind) {
// case where `x - 1 >= ...` or `-1 + x >= ...`
- (BinOpKind::Ge, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _) => {
+ (BinOpKind::Ge, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) => {
match (lhskind.node, &lhslhs.kind, &lhsrhs.kind) {
// `-1 + x`
- (BinOpKind::Add, &ExprKind::Lit(ref lit), _) if Self::check_lit(lit, -1) => {
+ (BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(*lit, -1) => {
Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs)
},
// `x - 1`
- (BinOpKind::Sub, _, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
+ (BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs)
},
_ => None,
}
},
// case where `... >= y + 1` or `... >= 1 + y`
- (BinOpKind::Ge, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs))
- if rhskind.node == BinOpKind::Add =>
- {
+ (BinOpKind::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => {
match (&rhslhs.kind, &rhsrhs.kind) {
// `y + 1` and `1 + y`
- (&ExprKind::Lit(ref lit), _) if Self::check_lit(lit, 1) => {
+ (ExprKind::Lit(lit), _) if Self::check_lit(*lit, 1) => {
Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs)
},
- (_, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
+ (_, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs)
},
_ => None,
}
},
// case where `x + 1 <= ...` or `1 + x <= ...`
- (BinOpKind::Le, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _)
- if lhskind.node == BinOpKind::Add =>
- {
+ (BinOpKind::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => {
match (&lhslhs.kind, &lhsrhs.kind) {
// `1 + x` and `x + 1`
- (&ExprKind::Lit(ref lit), _) if Self::check_lit(lit, 1) => {
+ (ExprKind::Lit(lit), _) if Self::check_lit(*lit, 1) => {
Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs)
},
- (_, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
+ (_, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs)
},
_ => None,
}
},
// case where `... >= y - 1` or `... >= -1 + y`
- (BinOpKind::Le, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs)) => {
+ (BinOpKind::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => {
match (rhskind.node, &rhslhs.kind, &rhsrhs.kind) {
// `-1 + y`
- (BinOpKind::Add, &ExprKind::Lit(ref lit), _) if Self::check_lit(lit, -1) => {
+ (BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(*lit, -1) => {
Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs)
},
// `y - 1`
- (BinOpKind::Sub, _, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
+ (BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs)
},
_ => None,
diff --git a/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs b/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs
index 0ef77e03d..6ea637412 100644
--- a/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs
@@ -38,7 +38,7 @@ declare_clippy_lint! {
declare_lint_pass!(InvalidUpcastComparisons => [INVALID_UPCAST_COMPARISONS]);
-fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<(FullInt, FullInt)> {
+fn numeric_cast_precast_bounds(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(FullInt, FullInt)> {
if let ExprKind::Cast(cast_exp, _) = expr.kind {
let pre_cast_ty = cx.typeck_results().expr_ty(cast_exp);
let cast_ty = cx.typeck_results().expr_ty(expr);
diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
index 06e957285..b18456ee5 100644
--- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
+++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
@@ -1,12 +1,15 @@
//! lint when there is a large size difference between variants on an enum
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{diagnostics::span_lint_and_then, ty::approx_ty_size, ty::is_copy};
+use clippy_utils::{
+ diagnostics::span_lint_and_then,
+ ty::{approx_ty_size, is_copy, AdtVariantInfo},
+};
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::{Adt, AdtDef, GenericArg, List, Ty};
+use rustc_middle::ty::{Adt, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
@@ -72,49 +75,6 @@ impl LargeEnumVariant {
}
}
-struct FieldInfo {
- ind: usize,
- size: u64,
-}
-
-struct VariantInfo {
- ind: usize,
- size: u64,
- fields_size: Vec<FieldInfo>,
-}
-
-fn variants_size<'tcx>(
- cx: &LateContext<'tcx>,
- adt: AdtDef<'tcx>,
- subst: &'tcx List<GenericArg<'tcx>>,
-) -> Vec<VariantInfo> {
- let mut variants_size = adt
- .variants()
- .iter()
- .enumerate()
- .map(|(i, variant)| {
- let mut fields_size = variant
- .fields
- .iter()
- .enumerate()
- .map(|(i, f)| FieldInfo {
- ind: i,
- size: approx_ty_size(cx, f.ty(cx.tcx, subst)),
- })
- .collect::<Vec<_>>();
- fields_size.sort_by(|a, b| (a.size.cmp(&b.size)));
-
- VariantInfo {
- ind: i,
- size: fields_size.iter().map(|info| info.size).sum(),
- fields_size,
- }
- })
- .collect::<Vec<_>>();
- variants_size.sort_by(|a, b| (b.size.cmp(&a.size)));
- variants_size
-}
-
impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]);
impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
@@ -130,7 +90,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
if adt.variants().len() <= 1 {
return;
}
- let variants_size = variants_size(cx, *adt, subst);
+ let variants_size = AdtVariantInfo::new(cx, *adt, subst);
let mut difference = variants_size[0].size - variants_size[1].size;
if difference > self.maximum_size_difference_allowed {
@@ -173,16 +133,16 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
.fields_size
.iter()
.rev()
- .map_while(|val| {
+ .map_while(|&(ind, size)| {
if difference > self.maximum_size_difference_allowed {
- difference = difference.saturating_sub(val.size);
+ difference = difference.saturating_sub(size);
Some((
- fields[val.ind].ty.span,
+ fields[ind].ty.span,
format!(
"Box<{}>",
snippet_with_applicability(
cx,
- fields[val.ind].ty.span,
+ fields[ind].ty.span,
"..",
&mut applicability
)
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index b0cba40c2..4c133c06a 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -366,8 +366,7 @@ fn check_for_is_empty<'tcx>(
}
fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) {
- if let (&ExprKind::MethodCall(method_path, receiver, args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind)
- {
+ if let (&ExprKind::MethodCall(method_path, receiver, args, _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) {
// check if we are in an is_empty() method
if let Some(name) = get_item_name(cx, method) {
if name.as_str() == "is_empty" {
diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs
index b7798b1c1..61f87b914 100644
--- a/src/tools/clippy/clippy_lints/src/let_underscore.rs
+++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs
@@ -1,13 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::{is_must_use_ty, is_type_diagnostic_item, match_type};
+use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
use clippy_utils::{is_must_use_func_call, paths};
-use if_chain::if_chain;
use rustc_hir::{Local, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::{sym, Symbol};
declare_clippy_lint! {
/// ### What it does
@@ -30,13 +28,14 @@ declare_clippy_lint! {
#[clippy::version = "1.42.0"]
pub LET_UNDERSCORE_MUST_USE,
restriction,
- "non-binding let on a `#[must_use]` expression"
+ "non-binding `let` on a `#[must_use]` expression"
}
declare_clippy_lint! {
/// ### What it does
- /// Checks for `let _ = sync_lock`.
- /// This supports `mutex` and `rwlock` in `std::sync` and `parking_lot`.
+ /// Checks for `let _ = sync_lock`. This supports `mutex` and `rwlock` in
+ /// `parking_lot`. For `std` locks see the `rustc` lint
+ /// [`let_underscore_lock`](https://doc.rust-lang.org/nightly/rustc/lints/listing/deny-by-default.html#let-underscore-lock)
///
/// ### Why is this bad?
/// This statement immediately drops the lock instead of
@@ -57,50 +56,41 @@ declare_clippy_lint! {
#[clippy::version = "1.43.0"]
pub LET_UNDERSCORE_LOCK,
correctness,
- "non-binding let on a synchronization lock"
+ "non-binding `let` on a synchronization lock"
}
declare_clippy_lint! {
/// ### What it does
- /// Checks for `let _ = <expr>`
- /// where expr has a type that implements `Drop`
+ /// Checks for `let _ = <expr>` where the resulting type of expr implements `Future`
///
/// ### Why is this bad?
- /// This statement immediately drops the initializer
- /// expression instead of extending its lifetime to the end of the scope, which
- /// is often not intended. To extend the expression's lifetime to the end of the
- /// scope, use an underscore-prefixed name instead (i.e. _var). If you want to
- /// explicitly drop the expression, `std::mem::drop` conveys your intention
- /// better and is less error-prone.
+ /// Futures must be polled for work to be done. The original intention was most likely to await the future
+ /// and ignore the resulting value.
///
/// ### Example
/// ```rust
- /// # struct DroppableItem;
- /// {
- /// let _ = DroppableItem;
- /// // ^ dropped here
- /// /* more code */
+ /// async fn foo() -> Result<(), ()> {
+ /// Ok(())
/// }
+ /// let _ = foo();
/// ```
///
/// Use instead:
/// ```rust
- /// # struct DroppableItem;
- /// {
- /// let _droppable = DroppableItem;
- /// /* more code */
- /// // dropped at end of scope
+ /// # async fn context() {
+ /// async fn foo() -> Result<(), ()> {
+ /// Ok(())
/// }
+ /// let _ = foo().await;
+ /// # }
/// ```
- #[clippy::version = "1.50.0"]
- pub LET_UNDERSCORE_DROP,
- pedantic,
- "non-binding let on a type that implements `Drop`"
+ #[clippy::version = "1.66"]
+ pub LET_UNDERSCORE_FUTURE,
+ suspicious,
+ "non-binding `let` on a future"
}
-declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK, LET_UNDERSCORE_DROP]);
-
-const SYNC_GUARD_SYMS: [Symbol; 3] = [sym::MutexGuard, sym::RwLockReadGuard, sym::RwLockWriteGuard];
+declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK, LET_UNDERSCORE_FUTURE]);
const SYNC_GUARD_PATHS: [&[&str]; 3] = [
&paths::PARKING_LOT_MUTEX_GUARD,
@@ -110,64 +100,53 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [
impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) {
- if in_external_macro(cx.tcx.sess, local.span) {
- return;
- }
-
- if_chain! {
- if let PatKind::Wild = local.pat.kind;
- if let Some(init) = local.init;
- then {
- let init_ty = cx.typeck_results().expr_ty(init);
- let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
- GenericArgKind::Type(inner_ty) => {
- SYNC_GUARD_SYMS
- .iter()
- .any(|&sym| is_type_diagnostic_item(cx, inner_ty, sym))
- || SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path))
- },
-
- GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
- });
- if contains_sync_guard {
- span_lint_and_help(
- cx,
- LET_UNDERSCORE_LOCK,
- local.span,
- "non-binding let on a synchronization lock",
- None,
- "consider using an underscore-prefixed named \
- binding or dropping explicitly with `std::mem::drop`",
- );
- } else if init_ty.needs_drop(cx.tcx, cx.param_env) {
- span_lint_and_help(
- cx,
- LET_UNDERSCORE_DROP,
- local.span,
- "non-binding `let` on a type that implements `Drop`",
- None,
- "consider using an underscore-prefixed named \
+ if !in_external_macro(cx.tcx.sess, local.span)
+ && let PatKind::Wild = local.pat.kind
+ && let Some(init) = local.init
+ {
+ let init_ty = cx.typeck_results().expr_ty(init);
+ let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
+ GenericArgKind::Type(inner_ty) => SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path)),
+ GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
+ });
+ if contains_sync_guard {
+ span_lint_and_help(
+ cx,
+ LET_UNDERSCORE_LOCK,
+ local.span,
+ "non-binding `let` on a synchronization lock",
+ None,
+ "consider using an underscore-prefixed named \
binding or dropping explicitly with `std::mem::drop`",
- );
- } else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) {
- span_lint_and_help(
- cx,
- LET_UNDERSCORE_MUST_USE,
- local.span,
- "non-binding let on an expression with `#[must_use]` type",
- None,
- "consider explicitly using expression value",
- );
- } else if is_must_use_func_call(cx, init) {
- span_lint_and_help(
- cx,
- LET_UNDERSCORE_MUST_USE,
- local.span,
- "non-binding let on a result of a `#[must_use]` function",
- None,
- "consider explicitly using function result",
- );
- }
+ );
+ } else if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait()
+ && implements_trait(cx, cx.typeck_results().expr_ty(init), future_trait_def_id, &[]) {
+ span_lint_and_help(
+ cx,
+ LET_UNDERSCORE_FUTURE,
+ local.span,
+ "non-binding `let` on a future",
+ None,
+ "consider awaiting the future or dropping explicitly with `std::mem::drop`"
+ );
+ } else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) {
+ span_lint_and_help(
+ cx,
+ LET_UNDERSCORE_MUST_USE,
+ local.span,
+ "non-binding `let` on an expression with `#[must_use]` type",
+ None,
+ "consider explicitly using expression value",
+ );
+ } else if is_must_use_func_call(cx, init) {
+ span_lint_and_help(
+ cx,
+ LET_UNDERSCORE_MUST_USE,
+ local.span,
+ "non-binding `let` on a result of a `#[must_use]` function",
+ None,
+ "consider explicitly using function result",
+ );
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_all.rs b/src/tools/clippy/clippy_lints/src/lib.register_all.rs
deleted file mode 100644
index c455e1561..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_all.rs
+++ /dev/null
@@ -1,368 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::all", Some("clippy_all"), vec![
- LintId::of(almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE),
- LintId::of(approx_const::APPROX_CONSTANT),
- LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
- LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
- LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
- LintId::of(attrs::DEPRECATED_CFG_ATTR),
- LintId::of(attrs::DEPRECATED_SEMVER),
- LintId::of(attrs::MISMATCHED_TARGET_OS),
- LintId::of(attrs::USELESS_ATTRIBUTE),
- LintId::of(await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE),
- LintId::of(await_holding_invalid::AWAIT_HOLDING_LOCK),
- LintId::of(await_holding_invalid::AWAIT_HOLDING_REFCELL_REF),
- LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
- LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
- LintId::of(bool_to_int_with_if::BOOL_TO_INT_WITH_IF),
- LintId::of(booleans::NONMINIMAL_BOOL),
- LintId::of(booleans::OVERLY_COMPLEX_BOOL_EXPR),
- LintId::of(borrow_deref_ref::BORROW_DEREF_REF),
- LintId::of(box_default::BOX_DEFAULT),
- LintId::of(casts::CAST_ABS_TO_UNSIGNED),
- LintId::of(casts::CAST_ENUM_CONSTRUCTOR),
- LintId::of(casts::CAST_ENUM_TRUNCATION),
- LintId::of(casts::CAST_NAN_TO_INT),
- LintId::of(casts::CAST_REF_TO_MUT),
- LintId::of(casts::CAST_SLICE_DIFFERENT_SIZES),
- LintId::of(casts::CAST_SLICE_FROM_RAW_PARTS),
- LintId::of(casts::CHAR_LIT_AS_U8),
- LintId::of(casts::FN_TO_NUMERIC_CAST),
- LintId::of(casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
- LintId::of(casts::UNNECESSARY_CAST),
- LintId::of(collapsible_if::COLLAPSIBLE_ELSE_IF),
- LintId::of(collapsible_if::COLLAPSIBLE_IF),
- LintId::of(comparison_chain::COMPARISON_CHAIN),
- LintId::of(copies::IFS_SAME_COND),
- LintId::of(copies::IF_SAME_THEN_ELSE),
- LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF),
- LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
- LintId::of(default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY),
- LintId::of(dereference::EXPLICIT_AUTO_DEREF),
- LintId::of(dereference::NEEDLESS_BORROW),
- LintId::of(derivable_impls::DERIVABLE_IMPLS),
- LintId::of(derive::DERIVE_HASH_XOR_EQ),
- LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
- LintId::of(disallowed_macros::DISALLOWED_MACROS),
- LintId::of(disallowed_methods::DISALLOWED_METHODS),
- LintId::of(disallowed_names::DISALLOWED_NAMES),
- LintId::of(disallowed_types::DISALLOWED_TYPES),
- LintId::of(doc::MISSING_SAFETY_DOC),
- LintId::of(doc::NEEDLESS_DOCTEST_MAIN),
- LintId::of(double_parens::DOUBLE_PARENS),
- LintId::of(drop_forget_ref::DROP_COPY),
- LintId::of(drop_forget_ref::DROP_NON_DROP),
- LintId::of(drop_forget_ref::DROP_REF),
- LintId::of(drop_forget_ref::FORGET_COPY),
- LintId::of(drop_forget_ref::FORGET_NON_DROP),
- LintId::of(drop_forget_ref::FORGET_REF),
- LintId::of(drop_forget_ref::UNDROPPED_MANUALLY_DROPS),
- LintId::of(duplicate_mod::DUPLICATE_MOD),
- LintId::of(entry::MAP_ENTRY),
- LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
- LintId::of(enum_variants::ENUM_VARIANT_NAMES),
- LintId::of(enum_variants::MODULE_INCEPTION),
- LintId::of(escape::BOXED_LOCAL),
- LintId::of(eta_reduction::REDUNDANT_CLOSURE),
- LintId::of(explicit_write::EXPLICIT_WRITE),
- LintId::of(float_literal::EXCESSIVE_PRECISION),
- LintId::of(format::USELESS_FORMAT),
- LintId::of(format_args::FORMAT_IN_FORMAT_ARGS),
- LintId::of(format_args::TO_STRING_IN_FORMAT_ARGS),
- LintId::of(format_args::UNUSED_FORMAT_SPECS),
- LintId::of(format_impl::PRINT_IN_FORMAT_IMPL),
- LintId::of(format_impl::RECURSIVE_FORMAT_IMPL),
- LintId::of(formatting::POSSIBLE_MISSING_COMMA),
- LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
- LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
- LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
- LintId::of(from_over_into::FROM_OVER_INTO),
- LintId::of(from_str_radix_10::FROM_STR_RADIX_10),
- LintId::of(functions::DOUBLE_MUST_USE),
- LintId::of(functions::MUST_USE_UNIT),
- LintId::of(functions::NOT_UNSAFE_PTR_ARG_DEREF),
- LintId::of(functions::RESULT_LARGE_ERR),
- LintId::of(functions::RESULT_UNIT_ERR),
- LintId::of(functions::TOO_MANY_ARGUMENTS),
- LintId::of(if_let_mutex::IF_LET_MUTEX),
- LintId::of(implicit_saturating_add::IMPLICIT_SATURATING_ADD),
- LintId::of(implicit_saturating_sub::IMPLICIT_SATURATING_SUB),
- LintId::of(indexing_slicing::OUT_OF_BOUNDS_INDEXING),
- LintId::of(infinite_iter::INFINITE_ITER),
- LintId::of(inherent_to_string::INHERENT_TO_STRING),
- LintId::of(inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY),
- LintId::of(init_numbered_fields::INIT_NUMBERED_FIELDS),
- LintId::of(inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
- LintId::of(int_plus_one::INT_PLUS_ONE),
- LintId::of(invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED),
- LintId::of(large_const_arrays::LARGE_CONST_ARRAYS),
- LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
- LintId::of(len_zero::COMPARISON_TO_EMPTY),
- LintId::of(len_zero::LEN_WITHOUT_IS_EMPTY),
- LintId::of(len_zero::LEN_ZERO),
- LintId::of(let_underscore::LET_UNDERSCORE_LOCK),
- LintId::of(lifetimes::EXTRA_UNUSED_LIFETIMES),
- LintId::of(lifetimes::NEEDLESS_LIFETIMES),
- LintId::of(literal_representation::INCONSISTENT_DIGIT_GROUPING),
- LintId::of(literal_representation::MISTYPED_LITERAL_SUFFIXES),
- LintId::of(literal_representation::UNUSUAL_BYTE_GROUPINGS),
- LintId::of(loops::EMPTY_LOOP),
- LintId::of(loops::EXPLICIT_COUNTER_LOOP),
- LintId::of(loops::FOR_KV_MAP),
- LintId::of(loops::ITER_NEXT_LOOP),
- LintId::of(loops::MANUAL_FIND),
- LintId::of(loops::MANUAL_FLATTEN),
- LintId::of(loops::MANUAL_MEMCPY),
- LintId::of(loops::MISSING_SPIN_LOOP),
- LintId::of(loops::MUT_RANGE_BOUND),
- LintId::of(loops::NEEDLESS_COLLECT),
- LintId::of(loops::NEEDLESS_RANGE_LOOP),
- LintId::of(loops::NEVER_LOOP),
- LintId::of(loops::SAME_ITEM_PUSH),
- LintId::of(loops::SINGLE_ELEMENT_LOOP),
- LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
- LintId::of(loops::WHILE_LET_LOOP),
- LintId::of(loops::WHILE_LET_ON_ITERATOR),
- LintId::of(main_recursion::MAIN_RECURSION),
- LintId::of(manual_async_fn::MANUAL_ASYNC_FN),
- LintId::of(manual_bits::MANUAL_BITS),
- LintId::of(manual_clamp::MANUAL_CLAMP),
- LintId::of(manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
- LintId::of(manual_rem_euclid::MANUAL_REM_EUCLID),
- LintId::of(manual_retain::MANUAL_RETAIN),
- LintId::of(manual_strip::MANUAL_STRIP),
- LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
- LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
- LintId::of(match_result_ok::MATCH_RESULT_OK),
- LintId::of(matches::COLLAPSIBLE_MATCH),
- LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
- LintId::of(matches::MANUAL_FILTER),
- LintId::of(matches::MANUAL_MAP),
- LintId::of(matches::MANUAL_UNWRAP_OR),
- LintId::of(matches::MATCH_AS_REF),
- LintId::of(matches::MATCH_LIKE_MATCHES_MACRO),
- LintId::of(matches::MATCH_OVERLAPPING_ARM),
- LintId::of(matches::MATCH_REF_PATS),
- LintId::of(matches::MATCH_SINGLE_BINDING),
- LintId::of(matches::MATCH_STR_CASE_MISMATCH),
- LintId::of(matches::NEEDLESS_MATCH),
- LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
- LintId::of(matches::SINGLE_MATCH),
- LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
- LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
- LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
- LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
- LintId::of(methods::BIND_INSTEAD_OF_MAP),
- LintId::of(methods::BYTES_COUNT_TO_LEN),
- LintId::of(methods::BYTES_NTH),
- LintId::of(methods::CHARS_LAST_CMP),
- LintId::of(methods::CHARS_NEXT_CMP),
- LintId::of(methods::CLONE_DOUBLE_REF),
- LintId::of(methods::CLONE_ON_COPY),
- LintId::of(methods::COLLAPSIBLE_STR_REPLACE),
- LintId::of(methods::ERR_EXPECT),
- LintId::of(methods::EXPECT_FUN_CALL),
- LintId::of(methods::EXTEND_WITH_DRAIN),
- LintId::of(methods::FILTER_MAP_IDENTITY),
- LintId::of(methods::FILTER_NEXT),
- LintId::of(methods::FLAT_MAP_IDENTITY),
- LintId::of(methods::GET_FIRST),
- LintId::of(methods::GET_LAST_WITH_LEN),
- LintId::of(methods::INSPECT_FOR_EACH),
- LintId::of(methods::INTO_ITER_ON_REF),
- LintId::of(methods::IS_DIGIT_ASCII_RADIX),
- LintId::of(methods::ITERATOR_STEP_BY_ZERO),
- LintId::of(methods::ITER_CLONED_COLLECT),
- LintId::of(methods::ITER_COUNT),
- LintId::of(methods::ITER_KV_MAP),
- LintId::of(methods::ITER_NEXT_SLICE),
- LintId::of(methods::ITER_NTH),
- LintId::of(methods::ITER_NTH_ZERO),
- LintId::of(methods::ITER_OVEREAGER_CLONED),
- LintId::of(methods::ITER_SKIP_NEXT),
- LintId::of(methods::MANUAL_FILTER_MAP),
- LintId::of(methods::MANUAL_FIND_MAP),
- LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
- LintId::of(methods::MANUAL_SPLIT_ONCE),
- LintId::of(methods::MANUAL_STR_REPEAT),
- LintId::of(methods::MAP_CLONE),
- LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
- LintId::of(methods::MAP_FLATTEN),
- LintId::of(methods::MAP_IDENTITY),
- LintId::of(methods::MUT_MUTEX_LOCK),
- LintId::of(methods::NEEDLESS_OPTION_AS_DEREF),
- LintId::of(methods::NEEDLESS_OPTION_TAKE),
- LintId::of(methods::NEEDLESS_SPLITN),
- LintId::of(methods::NEW_RET_NO_SELF),
- LintId::of(methods::NONSENSICAL_OPEN_OPTIONS),
- LintId::of(methods::NO_EFFECT_REPLACE),
- LintId::of(methods::OBFUSCATED_IF_ELSE),
- LintId::of(methods::OK_EXPECT),
- LintId::of(methods::OPTION_AS_REF_DEREF),
- LintId::of(methods::OPTION_FILTER_MAP),
- LintId::of(methods::OPTION_MAP_OR_NONE),
- LintId::of(methods::OR_FUN_CALL),
- LintId::of(methods::OR_THEN_UNWRAP),
- LintId::of(methods::RANGE_ZIP_WITH_LEN),
- LintId::of(methods::REPEAT_ONCE),
- LintId::of(methods::RESULT_MAP_OR_INTO_OPTION),
- LintId::of(methods::SEARCH_IS_SOME),
- LintId::of(methods::SHOULD_IMPLEMENT_TRAIT),
- LintId::of(methods::SINGLE_CHAR_ADD_STR),
- LintId::of(methods::SINGLE_CHAR_PATTERN),
- LintId::of(methods::SKIP_WHILE_NEXT),
- LintId::of(methods::STRING_EXTEND_CHARS),
- LintId::of(methods::SUSPICIOUS_MAP),
- LintId::of(methods::SUSPICIOUS_SPLITN),
- LintId::of(methods::SUSPICIOUS_TO_OWNED),
- LintId::of(methods::UNINIT_ASSUMED_INIT),
- LintId::of(methods::UNIT_HASH),
- LintId::of(methods::UNNECESSARY_FILTER_MAP),
- LintId::of(methods::UNNECESSARY_FIND_MAP),
- LintId::of(methods::UNNECESSARY_FOLD),
- LintId::of(methods::UNNECESSARY_LAZY_EVALUATIONS),
- LintId::of(methods::UNNECESSARY_SORT_BY),
- LintId::of(methods::UNNECESSARY_TO_OWNED),
- LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
- LintId::of(methods::USELESS_ASREF),
- LintId::of(methods::VEC_RESIZE_TO_ZERO),
- LintId::of(methods::WRONG_SELF_CONVENTION),
- LintId::of(methods::ZST_OFFSET),
- LintId::of(minmax::MIN_MAX),
- LintId::of(misc::SHORT_CIRCUIT_STATEMENT),
- LintId::of(misc::TOPLEVEL_REF_ARG),
- LintId::of(misc::ZERO_PTR),
- LintId::of(misc_early::BUILTIN_TYPE_SHADOW),
- LintId::of(misc_early::DOUBLE_NEG),
- LintId::of(misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
- LintId::of(misc_early::MIXED_CASE_HEX_LITERALS),
- LintId::of(misc_early::REDUNDANT_PATTERN),
- LintId::of(misc_early::UNNEEDED_WILDCARD_PATTERN),
- LintId::of(misc_early::ZERO_PREFIXED_LITERAL),
- LintId::of(mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION),
- LintId::of(multi_assignments::MULTI_ASSIGNMENTS),
- LintId::of(mut_key::MUTABLE_KEY_TYPE),
- LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
- LintId::of(needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
- LintId::of(needless_bool::BOOL_COMPARISON),
- LintId::of(needless_bool::NEEDLESS_BOOL),
- LintId::of(needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
- LintId::of(needless_late_init::NEEDLESS_LATE_INIT),
- LintId::of(needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS),
- LintId::of(needless_question_mark::NEEDLESS_QUESTION_MARK),
- LintId::of(needless_update::NEEDLESS_UPDATE),
- LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
- LintId::of(neg_multiply::NEG_MULTIPLY),
- LintId::of(new_without_default::NEW_WITHOUT_DEFAULT),
- LintId::of(no_effect::NO_EFFECT),
- LintId::of(no_effect::UNNECESSARY_OPERATION),
- LintId::of(non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
- LintId::of(non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
- LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
- LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
- LintId::of(octal_escapes::OCTAL_ESCAPES),
- LintId::of(only_used_in_recursion::ONLY_USED_IN_RECURSION),
- LintId::of(operators::ABSURD_EXTREME_COMPARISONS),
- LintId::of(operators::ASSIGN_OP_PATTERN),
- LintId::of(operators::BAD_BIT_MASK),
- LintId::of(operators::CMP_NAN),
- LintId::of(operators::CMP_OWNED),
- LintId::of(operators::DOUBLE_COMPARISONS),
- LintId::of(operators::DURATION_SUBSEC),
- LintId::of(operators::EQ_OP),
- LintId::of(operators::ERASING_OP),
- LintId::of(operators::FLOAT_EQUALITY_WITHOUT_ABS),
- LintId::of(operators::IDENTITY_OP),
- LintId::of(operators::INEFFECTIVE_BIT_MASK),
- LintId::of(operators::MISREFACTORED_ASSIGN_OP),
- LintId::of(operators::MODULO_ONE),
- LintId::of(operators::OP_REF),
- LintId::of(operators::PTR_EQ),
- LintId::of(operators::SELF_ASSIGNMENT),
- LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
- LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
- LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
- LintId::of(partialeq_to_none::PARTIALEQ_TO_NONE),
- LintId::of(precedence::PRECEDENCE),
- LintId::of(ptr::CMP_NULL),
- LintId::of(ptr::INVALID_NULL_PTR_USAGE),
- LintId::of(ptr::MUT_FROM_REF),
- LintId::of(ptr::PTR_ARG),
- LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
- LintId::of(question_mark::QUESTION_MARK),
- LintId::of(ranges::MANUAL_RANGE_CONTAINS),
- LintId::of(ranges::REVERSED_EMPTY_RANGES),
- LintId::of(rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT),
- LintId::of(read_zero_byte_vec::READ_ZERO_BYTE_VEC),
- LintId::of(redundant_clone::REDUNDANT_CLONE),
- LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
- LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES),
- LintId::of(redundant_slicing::REDUNDANT_SLICING),
- LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
- LintId::of(reference::DEREF_ADDROF),
- LintId::of(regex::INVALID_REGEX),
- LintId::of(returns::LET_AND_RETURN),
- LintId::of(returns::NEEDLESS_RETURN),
- LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
- LintId::of(serde_api::SERDE_API_MISUSE),
- LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
- LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
- LintId::of(slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
- LintId::of(strings::STRING_FROM_UTF8_AS_BYTES),
- LintId::of(strings::TRIM_SPLIT_WHITESPACE),
- LintId::of(strlen_on_c_strings::STRLEN_ON_C_STRINGS),
- LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
- LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
- LintId::of(swap::ALMOST_SWAPPED),
- LintId::of(swap::MANUAL_SWAP),
- LintId::of(swap_ptr_to_ref::SWAP_PTR_TO_REF),
- LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
- LintId::of(temporary_assignment::TEMPORARY_ASSIGNMENT),
- LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
- LintId::of(transmute::CROSSPOINTER_TRANSMUTE),
- LintId::of(transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS),
- LintId::of(transmute::TRANSMUTE_BYTES_TO_STR),
- LintId::of(transmute::TRANSMUTE_FLOAT_TO_INT),
- LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
- LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
- LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
- LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES),
- LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
- LintId::of(transmute::TRANSMUTING_NULL),
- LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
- LintId::of(transmute::USELESS_TRANSMUTE),
- LintId::of(transmute::WRONG_TRANSMUTE),
- LintId::of(types::BORROWED_BOX),
- LintId::of(types::BOX_COLLECTION),
- LintId::of(types::REDUNDANT_ALLOCATION),
- LintId::of(types::TYPE_COMPLEXITY),
- LintId::of(types::VEC_BOX),
- LintId::of(unicode::INVISIBLE_CHARACTERS),
- LintId::of(uninit_vec::UNINIT_VEC),
- LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
- LintId::of(unit_types::LET_UNIT_VALUE),
- LintId::of(unit_types::UNIT_ARG),
- LintId::of(unit_types::UNIT_CMP),
- LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
- LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
- LintId::of(unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS),
- LintId::of(unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
- LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
- LintId::of(unused_unit::UNUSED_UNIT),
- LintId::of(unwrap::PANICKING_UNWRAP),
- LintId::of(unwrap::UNNECESSARY_UNWRAP),
- LintId::of(upper_case_acronyms::UPPER_CASE_ACRONYMS),
- LintId::of(useless_conversion::USELESS_CONVERSION),
- LintId::of(vec::USELESS_VEC),
- LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
- LintId::of(write::PRINTLN_EMPTY_STRING),
- LintId::of(write::PRINT_LITERAL),
- LintId::of(write::PRINT_WITH_NEWLINE),
- LintId::of(write::WRITELN_EMPTY_STRING),
- LintId::of(write::WRITE_LITERAL),
- LintId::of(write::WRITE_WITH_NEWLINE),
- LintId::of(zero_div_zero::ZERO_DIVIDED_BY_ZERO),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_cargo.rs b/src/tools/clippy/clippy_lints/src/lib.register_cargo.rs
deleted file mode 100644
index c890523fe..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_cargo.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::cargo", Some("clippy_cargo"), vec![
- LintId::of(cargo::CARGO_COMMON_METADATA),
- LintId::of(cargo::MULTIPLE_CRATE_VERSIONS),
- LintId::of(cargo::NEGATIVE_FEATURE_NAMES),
- LintId::of(cargo::REDUNDANT_FEATURE_NAMES),
- LintId::of(cargo::WILDCARD_DEPENDENCIES),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs b/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs
deleted file mode 100644
index 8be9dc4ba..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec![
- LintId::of(attrs::DEPRECATED_CFG_ATTR),
- LintId::of(booleans::NONMINIMAL_BOOL),
- LintId::of(borrow_deref_ref::BORROW_DEREF_REF),
- LintId::of(casts::CHAR_LIT_AS_U8),
- LintId::of(casts::UNNECESSARY_CAST),
- LintId::of(dereference::EXPLICIT_AUTO_DEREF),
- LintId::of(derivable_impls::DERIVABLE_IMPLS),
- LintId::of(double_parens::DOUBLE_PARENS),
- LintId::of(explicit_write::EXPLICIT_WRITE),
- LintId::of(format::USELESS_FORMAT),
- LintId::of(format_args::UNUSED_FORMAT_SPECS),
- LintId::of(functions::TOO_MANY_ARGUMENTS),
- LintId::of(int_plus_one::INT_PLUS_ONE),
- LintId::of(lifetimes::EXTRA_UNUSED_LIFETIMES),
- LintId::of(lifetimes::NEEDLESS_LIFETIMES),
- LintId::of(loops::EXPLICIT_COUNTER_LOOP),
- LintId::of(loops::MANUAL_FIND),
- LintId::of(loops::MANUAL_FLATTEN),
- LintId::of(loops::SINGLE_ELEMENT_LOOP),
- LintId::of(loops::WHILE_LET_LOOP),
- LintId::of(manual_clamp::MANUAL_CLAMP),
- LintId::of(manual_rem_euclid::MANUAL_REM_EUCLID),
- LintId::of(manual_strip::MANUAL_STRIP),
- LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
- LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
- LintId::of(matches::MANUAL_FILTER),
- LintId::of(matches::MANUAL_UNWRAP_OR),
- LintId::of(matches::MATCH_AS_REF),
- LintId::of(matches::MATCH_SINGLE_BINDING),
- LintId::of(matches::NEEDLESS_MATCH),
- LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
- LintId::of(methods::BIND_INSTEAD_OF_MAP),
- LintId::of(methods::BYTES_COUNT_TO_LEN),
- LintId::of(methods::CLONE_ON_COPY),
- LintId::of(methods::FILTER_MAP_IDENTITY),
- LintId::of(methods::FILTER_NEXT),
- LintId::of(methods::FLAT_MAP_IDENTITY),
- LintId::of(methods::GET_LAST_WITH_LEN),
- LintId::of(methods::INSPECT_FOR_EACH),
- LintId::of(methods::ITER_COUNT),
- LintId::of(methods::ITER_KV_MAP),
- LintId::of(methods::MANUAL_FILTER_MAP),
- LintId::of(methods::MANUAL_FIND_MAP),
- LintId::of(methods::MANUAL_SPLIT_ONCE),
- LintId::of(methods::MAP_FLATTEN),
- LintId::of(methods::MAP_IDENTITY),
- LintId::of(methods::NEEDLESS_OPTION_AS_DEREF),
- LintId::of(methods::NEEDLESS_OPTION_TAKE),
- LintId::of(methods::NEEDLESS_SPLITN),
- LintId::of(methods::OPTION_AS_REF_DEREF),
- LintId::of(methods::OPTION_FILTER_MAP),
- LintId::of(methods::OR_THEN_UNWRAP),
- LintId::of(methods::RANGE_ZIP_WITH_LEN),
- LintId::of(methods::REPEAT_ONCE),
- LintId::of(methods::SEARCH_IS_SOME),
- LintId::of(methods::SKIP_WHILE_NEXT),
- LintId::of(methods::UNNECESSARY_FILTER_MAP),
- LintId::of(methods::UNNECESSARY_FIND_MAP),
- LintId::of(methods::UNNECESSARY_SORT_BY),
- LintId::of(methods::USELESS_ASREF),
- LintId::of(misc::SHORT_CIRCUIT_STATEMENT),
- LintId::of(misc_early::UNNEEDED_WILDCARD_PATTERN),
- LintId::of(misc_early::ZERO_PREFIXED_LITERAL),
- LintId::of(mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION),
- LintId::of(needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
- LintId::of(needless_bool::BOOL_COMPARISON),
- LintId::of(needless_bool::NEEDLESS_BOOL),
- LintId::of(needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
- LintId::of(needless_question_mark::NEEDLESS_QUESTION_MARK),
- LintId::of(needless_update::NEEDLESS_UPDATE),
- LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
- LintId::of(no_effect::NO_EFFECT),
- LintId::of(no_effect::UNNECESSARY_OPERATION),
- LintId::of(only_used_in_recursion::ONLY_USED_IN_RECURSION),
- LintId::of(operators::DOUBLE_COMPARISONS),
- LintId::of(operators::DURATION_SUBSEC),
- LintId::of(operators::IDENTITY_OP),
- LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
- LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
- LintId::of(precedence::PRECEDENCE),
- LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
- LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
- LintId::of(redundant_slicing::REDUNDANT_SLICING),
- LintId::of(reference::DEREF_ADDROF),
- LintId::of(strings::STRING_FROM_UTF8_AS_BYTES),
- LintId::of(strlen_on_c_strings::STRLEN_ON_C_STRINGS),
- LintId::of(swap::MANUAL_SWAP),
- LintId::of(temporary_assignment::TEMPORARY_ASSIGNMENT),
- LintId::of(transmute::CROSSPOINTER_TRANSMUTE),
- LintId::of(transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS),
- LintId::of(transmute::TRANSMUTE_BYTES_TO_STR),
- LintId::of(transmute::TRANSMUTE_FLOAT_TO_INT),
- LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
- LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
- LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
- LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES),
- LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
- LintId::of(transmute::USELESS_TRANSMUTE),
- LintId::of(types::BORROWED_BOX),
- LintId::of(types::TYPE_COMPLEXITY),
- LintId::of(types::VEC_BOX),
- LintId::of(unit_types::UNIT_ARG),
- LintId::of(unwrap::UNNECESSARY_UNWRAP),
- LintId::of(useless_conversion::USELESS_CONVERSION),
- LintId::of(zero_div_zero::ZERO_DIVIDED_BY_ZERO),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs b/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
deleted file mode 100644
index bb94037ec..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![
- LintId::of(approx_const::APPROX_CONSTANT),
- LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
- LintId::of(attrs::DEPRECATED_SEMVER),
- LintId::of(attrs::MISMATCHED_TARGET_OS),
- LintId::of(attrs::USELESS_ATTRIBUTE),
- LintId::of(booleans::OVERLY_COMPLEX_BOOL_EXPR),
- LintId::of(casts::CAST_REF_TO_MUT),
- LintId::of(casts::CAST_SLICE_DIFFERENT_SIZES),
- LintId::of(copies::IFS_SAME_COND),
- LintId::of(copies::IF_SAME_THEN_ELSE),
- LintId::of(derive::DERIVE_HASH_XOR_EQ),
- LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
- LintId::of(drop_forget_ref::DROP_COPY),
- LintId::of(drop_forget_ref::DROP_REF),
- LintId::of(drop_forget_ref::FORGET_COPY),
- LintId::of(drop_forget_ref::FORGET_REF),
- LintId::of(drop_forget_ref::UNDROPPED_MANUALLY_DROPS),
- LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
- LintId::of(format_impl::RECURSIVE_FORMAT_IMPL),
- LintId::of(formatting::POSSIBLE_MISSING_COMMA),
- LintId::of(functions::NOT_UNSAFE_PTR_ARG_DEREF),
- LintId::of(if_let_mutex::IF_LET_MUTEX),
- LintId::of(indexing_slicing::OUT_OF_BOUNDS_INDEXING),
- LintId::of(infinite_iter::INFINITE_ITER),
- LintId::of(inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY),
- LintId::of(inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
- LintId::of(invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED),
- LintId::of(let_underscore::LET_UNDERSCORE_LOCK),
- LintId::of(literal_representation::MISTYPED_LITERAL_SUFFIXES),
- LintId::of(loops::ITER_NEXT_LOOP),
- LintId::of(loops::NEVER_LOOP),
- LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
- LintId::of(matches::MATCH_STR_CASE_MISMATCH),
- LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
- LintId::of(methods::CLONE_DOUBLE_REF),
- LintId::of(methods::ITERATOR_STEP_BY_ZERO),
- LintId::of(methods::NONSENSICAL_OPEN_OPTIONS),
- LintId::of(methods::SUSPICIOUS_SPLITN),
- LintId::of(methods::UNINIT_ASSUMED_INIT),
- LintId::of(methods::UNIT_HASH),
- LintId::of(methods::VEC_RESIZE_TO_ZERO),
- LintId::of(methods::ZST_OFFSET),
- LintId::of(minmax::MIN_MAX),
- LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
- LintId::of(operators::ABSURD_EXTREME_COMPARISONS),
- LintId::of(operators::BAD_BIT_MASK),
- LintId::of(operators::CMP_NAN),
- LintId::of(operators::EQ_OP),
- LintId::of(operators::ERASING_OP),
- LintId::of(operators::INEFFECTIVE_BIT_MASK),
- LintId::of(operators::MODULO_ONE),
- LintId::of(operators::SELF_ASSIGNMENT),
- LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
- LintId::of(ptr::INVALID_NULL_PTR_USAGE),
- LintId::of(ptr::MUT_FROM_REF),
- LintId::of(ranges::REVERSED_EMPTY_RANGES),
- LintId::of(read_zero_byte_vec::READ_ZERO_BYTE_VEC),
- LintId::of(regex::INVALID_REGEX),
- LintId::of(serde_api::SERDE_API_MISUSE),
- LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
- LintId::of(swap::ALMOST_SWAPPED),
- LintId::of(transmute::TRANSMUTING_NULL),
- LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
- LintId::of(transmute::WRONG_TRANSMUTE),
- LintId::of(unicode::INVISIBLE_CHARACTERS),
- LintId::of(uninit_vec::UNINIT_VEC),
- LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
- LintId::of(unit_types::UNIT_CMP),
- LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
- LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
- LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
- LintId::of(unwrap::PANICKING_UNWRAP),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_internal.rs b/src/tools/clippy/clippy_lints/src/lib.register_internal.rs
deleted file mode 100644
index 40c94c6e8..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_internal.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::internal", Some("clippy_internal"), vec![
- LintId::of(utils::internal_lints::clippy_lints_internal::CLIPPY_LINTS_INTERNAL),
- LintId::of(utils::internal_lints::collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS),
- LintId::of(utils::internal_lints::compiler_lint_functions::COMPILER_LINT_FUNCTIONS),
- LintId::of(utils::internal_lints::if_chain_style::IF_CHAIN_STYLE),
- LintId::of(utils::internal_lints::interning_defined_symbol::INTERNING_DEFINED_SYMBOL),
- LintId::of(utils::internal_lints::interning_defined_symbol::UNNECESSARY_SYMBOL_STR),
- LintId::of(utils::internal_lints::invalid_paths::INVALID_PATHS),
- LintId::of(utils::internal_lints::lint_without_lint_pass::DEFAULT_DEPRECATION_REASON),
- LintId::of(utils::internal_lints::lint_without_lint_pass::DEFAULT_LINT),
- LintId::of(utils::internal_lints::lint_without_lint_pass::INVALID_CLIPPY_VERSION_ATTRIBUTE),
- LintId::of(utils::internal_lints::lint_without_lint_pass::LINT_WITHOUT_LINT_PASS),
- LintId::of(utils::internal_lints::lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE),
- LintId::of(utils::internal_lints::msrv_attr_impl::MISSING_MSRV_ATTR_IMPL),
- LintId::of(utils::internal_lints::outer_expn_data_pass::OUTER_EXPN_EXPN_DATA),
- LintId::of(utils::internal_lints::produce_ice::PRODUCE_ICE),
- LintId::of(utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_lints.rs b/src/tools/clippy/clippy_lints/src/lib.register_lints.rs
deleted file mode 100644
index 800e3a876..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_lints.rs
+++ /dev/null
@@ -1,620 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_lints(&[
- #[cfg(feature = "internal")]
- utils::internal_lints::clippy_lints_internal::CLIPPY_LINTS_INTERNAL,
- #[cfg(feature = "internal")]
- utils::internal_lints::collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS,
- #[cfg(feature = "internal")]
- utils::internal_lints::compiler_lint_functions::COMPILER_LINT_FUNCTIONS,
- #[cfg(feature = "internal")]
- utils::internal_lints::if_chain_style::IF_CHAIN_STYLE,
- #[cfg(feature = "internal")]
- utils::internal_lints::interning_defined_symbol::INTERNING_DEFINED_SYMBOL,
- #[cfg(feature = "internal")]
- utils::internal_lints::interning_defined_symbol::UNNECESSARY_SYMBOL_STR,
- #[cfg(feature = "internal")]
- utils::internal_lints::invalid_paths::INVALID_PATHS,
- #[cfg(feature = "internal")]
- utils::internal_lints::lint_without_lint_pass::DEFAULT_DEPRECATION_REASON,
- #[cfg(feature = "internal")]
- utils::internal_lints::lint_without_lint_pass::DEFAULT_LINT,
- #[cfg(feature = "internal")]
- utils::internal_lints::lint_without_lint_pass::INVALID_CLIPPY_VERSION_ATTRIBUTE,
- #[cfg(feature = "internal")]
- utils::internal_lints::lint_without_lint_pass::LINT_WITHOUT_LINT_PASS,
- #[cfg(feature = "internal")]
- utils::internal_lints::lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE,
- #[cfg(feature = "internal")]
- utils::internal_lints::msrv_attr_impl::MISSING_MSRV_ATTR_IMPL,
- #[cfg(feature = "internal")]
- utils::internal_lints::outer_expn_data_pass::OUTER_EXPN_EXPN_DATA,
- #[cfg(feature = "internal")]
- utils::internal_lints::produce_ice::PRODUCE_ICE,
- #[cfg(feature = "internal")]
- utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH,
- almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE,
- approx_const::APPROX_CONSTANT,
- as_conversions::AS_CONVERSIONS,
- asm_syntax::INLINE_ASM_X86_ATT_SYNTAX,
- asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX,
- assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
- assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES,
- async_yields_async::ASYNC_YIELDS_ASYNC,
- attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON,
- attrs::BLANKET_CLIPPY_RESTRICTION_LINTS,
- attrs::DEPRECATED_CFG_ATTR,
- attrs::DEPRECATED_SEMVER,
- attrs::EMPTY_LINE_AFTER_OUTER_ATTR,
- attrs::INLINE_ALWAYS,
- attrs::MISMATCHED_TARGET_OS,
- attrs::USELESS_ATTRIBUTE,
- await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE,
- await_holding_invalid::AWAIT_HOLDING_LOCK,
- await_holding_invalid::AWAIT_HOLDING_REFCELL_REF,
- blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS,
- bool_assert_comparison::BOOL_ASSERT_COMPARISON,
- bool_to_int_with_if::BOOL_TO_INT_WITH_IF,
- booleans::NONMINIMAL_BOOL,
- booleans::OVERLY_COMPLEX_BOOL_EXPR,
- borrow_deref_ref::BORROW_DEREF_REF,
- box_default::BOX_DEFAULT,
- cargo::CARGO_COMMON_METADATA,
- cargo::MULTIPLE_CRATE_VERSIONS,
- cargo::NEGATIVE_FEATURE_NAMES,
- cargo::REDUNDANT_FEATURE_NAMES,
- cargo::WILDCARD_DEPENDENCIES,
- casts::AS_PTR_CAST_MUT,
- casts::AS_UNDERSCORE,
- casts::BORROW_AS_PTR,
- casts::CAST_ABS_TO_UNSIGNED,
- casts::CAST_ENUM_CONSTRUCTOR,
- casts::CAST_ENUM_TRUNCATION,
- casts::CAST_LOSSLESS,
- casts::CAST_NAN_TO_INT,
- casts::CAST_POSSIBLE_TRUNCATION,
- casts::CAST_POSSIBLE_WRAP,
- casts::CAST_PRECISION_LOSS,
- casts::CAST_PTR_ALIGNMENT,
- casts::CAST_REF_TO_MUT,
- casts::CAST_SIGN_LOSS,
- casts::CAST_SLICE_DIFFERENT_SIZES,
- casts::CAST_SLICE_FROM_RAW_PARTS,
- casts::CHAR_LIT_AS_U8,
- casts::FN_TO_NUMERIC_CAST,
- casts::FN_TO_NUMERIC_CAST_ANY,
- casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
- casts::PTR_AS_PTR,
- casts::UNNECESSARY_CAST,
- checked_conversions::CHECKED_CONVERSIONS,
- cognitive_complexity::COGNITIVE_COMPLEXITY,
- collapsible_if::COLLAPSIBLE_ELSE_IF,
- collapsible_if::COLLAPSIBLE_IF,
- comparison_chain::COMPARISON_CHAIN,
- copies::BRANCHES_SHARING_CODE,
- copies::IFS_SAME_COND,
- copies::IF_SAME_THEN_ELSE,
- copies::SAME_FUNCTIONS_IN_IF_CONDITION,
- copy_iterator::COPY_ITERATOR,
- crate_in_macro_def::CRATE_IN_MACRO_DEF,
- create_dir::CREATE_DIR,
- dbg_macro::DBG_MACRO,
- default::DEFAULT_TRAIT_ACCESS,
- default::FIELD_REASSIGN_WITH_DEFAULT,
- default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY,
- default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK,
- default_union_representation::DEFAULT_UNION_REPRESENTATION,
- dereference::EXPLICIT_AUTO_DEREF,
- dereference::EXPLICIT_DEREF_METHODS,
- dereference::NEEDLESS_BORROW,
- dereference::REF_BINDING_TO_REFERENCE,
- derivable_impls::DERIVABLE_IMPLS,
- derive::DERIVE_HASH_XOR_EQ,
- derive::DERIVE_ORD_XOR_PARTIAL_ORD,
- derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ,
- derive::EXPL_IMPL_CLONE_ON_COPY,
- derive::UNSAFE_DERIVE_DESERIALIZE,
- disallowed_macros::DISALLOWED_MACROS,
- disallowed_methods::DISALLOWED_METHODS,
- disallowed_names::DISALLOWED_NAMES,
- disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS,
- disallowed_types::DISALLOWED_TYPES,
- doc::DOC_LINK_WITH_QUOTES,
- doc::DOC_MARKDOWN,
- doc::MISSING_ERRORS_DOC,
- doc::MISSING_PANICS_DOC,
- doc::MISSING_SAFETY_DOC,
- doc::NEEDLESS_DOCTEST_MAIN,
- double_parens::DOUBLE_PARENS,
- drop_forget_ref::DROP_COPY,
- drop_forget_ref::DROP_NON_DROP,
- drop_forget_ref::DROP_REF,
- drop_forget_ref::FORGET_COPY,
- drop_forget_ref::FORGET_NON_DROP,
- drop_forget_ref::FORGET_REF,
- drop_forget_ref::UNDROPPED_MANUALLY_DROPS,
- duplicate_mod::DUPLICATE_MOD,
- else_if_without_else::ELSE_IF_WITHOUT_ELSE,
- empty_drop::EMPTY_DROP,
- empty_enum::EMPTY_ENUM,
- empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS,
- entry::MAP_ENTRY,
- enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT,
- enum_variants::ENUM_VARIANT_NAMES,
- enum_variants::MODULE_INCEPTION,
- enum_variants::MODULE_NAME_REPETITIONS,
- equatable_if_let::EQUATABLE_IF_LET,
- escape::BOXED_LOCAL,
- eta_reduction::REDUNDANT_CLOSURE,
- eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
- excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS,
- excessive_bools::STRUCT_EXCESSIVE_BOOLS,
- exhaustive_items::EXHAUSTIVE_ENUMS,
- exhaustive_items::EXHAUSTIVE_STRUCTS,
- exit::EXIT,
- explicit_write::EXPLICIT_WRITE,
- fallible_impl_from::FALLIBLE_IMPL_FROM,
- float_literal::EXCESSIVE_PRECISION,
- float_literal::LOSSY_FLOAT_LITERAL,
- floating_point_arithmetic::IMPRECISE_FLOPS,
- floating_point_arithmetic::SUBOPTIMAL_FLOPS,
- format::USELESS_FORMAT,
- format_args::FORMAT_IN_FORMAT_ARGS,
- format_args::TO_STRING_IN_FORMAT_ARGS,
- format_args::UNINLINED_FORMAT_ARGS,
- format_args::UNUSED_FORMAT_SPECS,
- format_impl::PRINT_IN_FORMAT_IMPL,
- format_impl::RECURSIVE_FORMAT_IMPL,
- format_push_string::FORMAT_PUSH_STRING,
- formatting::POSSIBLE_MISSING_COMMA,
- formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING,
- formatting::SUSPICIOUS_ELSE_FORMATTING,
- formatting::SUSPICIOUS_UNARY_OP_FORMATTING,
- from_over_into::FROM_OVER_INTO,
- from_str_radix_10::FROM_STR_RADIX_10,
- functions::DOUBLE_MUST_USE,
- functions::MUST_USE_CANDIDATE,
- functions::MUST_USE_UNIT,
- functions::NOT_UNSAFE_PTR_ARG_DEREF,
- functions::RESULT_LARGE_ERR,
- functions::RESULT_UNIT_ERR,
- functions::TOO_MANY_ARGUMENTS,
- functions::TOO_MANY_LINES,
- future_not_send::FUTURE_NOT_SEND,
- if_let_mutex::IF_LET_MUTEX,
- if_not_else::IF_NOT_ELSE,
- if_then_some_else_none::IF_THEN_SOME_ELSE_NONE,
- implicit_hasher::IMPLICIT_HASHER,
- implicit_return::IMPLICIT_RETURN,
- implicit_saturating_add::IMPLICIT_SATURATING_ADD,
- implicit_saturating_sub::IMPLICIT_SATURATING_SUB,
- inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR,
- index_refutable_slice::INDEX_REFUTABLE_SLICE,
- indexing_slicing::INDEXING_SLICING,
- indexing_slicing::OUT_OF_BOUNDS_INDEXING,
- infinite_iter::INFINITE_ITER,
- infinite_iter::MAYBE_INFINITE_ITER,
- inherent_impl::MULTIPLE_INHERENT_IMPL,
- inherent_to_string::INHERENT_TO_STRING,
- inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY,
- init_numbered_fields::INIT_NUMBERED_FIELDS,
- inline_fn_without_body::INLINE_FN_WITHOUT_BODY,
- int_plus_one::INT_PLUS_ONE,
- invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS,
- invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED,
- items_after_statements::ITEMS_AFTER_STATEMENTS,
- iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR,
- large_const_arrays::LARGE_CONST_ARRAYS,
- large_enum_variant::LARGE_ENUM_VARIANT,
- large_include_file::LARGE_INCLUDE_FILE,
- large_stack_arrays::LARGE_STACK_ARRAYS,
- len_zero::COMPARISON_TO_EMPTY,
- len_zero::LEN_WITHOUT_IS_EMPTY,
- len_zero::LEN_ZERO,
- let_if_seq::USELESS_LET_IF_SEQ,
- let_underscore::LET_UNDERSCORE_DROP,
- let_underscore::LET_UNDERSCORE_LOCK,
- let_underscore::LET_UNDERSCORE_MUST_USE,
- lifetimes::EXTRA_UNUSED_LIFETIMES,
- lifetimes::NEEDLESS_LIFETIMES,
- literal_representation::DECIMAL_LITERAL_REPRESENTATION,
- literal_representation::INCONSISTENT_DIGIT_GROUPING,
- literal_representation::LARGE_DIGIT_GROUPS,
- literal_representation::MISTYPED_LITERAL_SUFFIXES,
- literal_representation::UNREADABLE_LITERAL,
- literal_representation::UNUSUAL_BYTE_GROUPINGS,
- loops::EMPTY_LOOP,
- loops::EXPLICIT_COUNTER_LOOP,
- loops::EXPLICIT_INTO_ITER_LOOP,
- loops::EXPLICIT_ITER_LOOP,
- loops::FOR_KV_MAP,
- loops::ITER_NEXT_LOOP,
- loops::MANUAL_FIND,
- loops::MANUAL_FLATTEN,
- loops::MANUAL_MEMCPY,
- loops::MISSING_SPIN_LOOP,
- loops::MUT_RANGE_BOUND,
- loops::NEEDLESS_COLLECT,
- loops::NEEDLESS_RANGE_LOOP,
- loops::NEVER_LOOP,
- loops::SAME_ITEM_PUSH,
- loops::SINGLE_ELEMENT_LOOP,
- loops::WHILE_IMMUTABLE_CONDITION,
- loops::WHILE_LET_LOOP,
- loops::WHILE_LET_ON_ITERATOR,
- macro_use::MACRO_USE_IMPORTS,
- main_recursion::MAIN_RECURSION,
- manual_assert::MANUAL_ASSERT,
- manual_async_fn::MANUAL_ASYNC_FN,
- manual_bits::MANUAL_BITS,
- manual_clamp::MANUAL_CLAMP,
- manual_instant_elapsed::MANUAL_INSTANT_ELAPSED,
- manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE,
- manual_rem_euclid::MANUAL_REM_EUCLID,
- manual_retain::MANUAL_RETAIN,
- manual_string_new::MANUAL_STRING_NEW,
- manual_strip::MANUAL_STRIP,
- map_unit_fn::OPTION_MAP_UNIT_FN,
- map_unit_fn::RESULT_MAP_UNIT_FN,
- match_result_ok::MATCH_RESULT_OK,
- matches::COLLAPSIBLE_MATCH,
- matches::INFALLIBLE_DESTRUCTURING_MATCH,
- matches::MANUAL_FILTER,
- matches::MANUAL_MAP,
- matches::MANUAL_UNWRAP_OR,
- matches::MATCH_AS_REF,
- matches::MATCH_BOOL,
- matches::MATCH_LIKE_MATCHES_MACRO,
- matches::MATCH_ON_VEC_ITEMS,
- matches::MATCH_OVERLAPPING_ARM,
- matches::MATCH_REF_PATS,
- matches::MATCH_SAME_ARMS,
- matches::MATCH_SINGLE_BINDING,
- matches::MATCH_STR_CASE_MISMATCH,
- matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
- matches::MATCH_WILD_ERR_ARM,
- matches::NEEDLESS_MATCH,
- matches::REDUNDANT_PATTERN_MATCHING,
- matches::REST_PAT_IN_FULLY_BOUND_STRUCTS,
- matches::SIGNIFICANT_DROP_IN_SCRUTINEE,
- matches::SINGLE_MATCH,
- matches::SINGLE_MATCH_ELSE,
- matches::TRY_ERR,
- matches::WILDCARD_ENUM_MATCH_ARM,
- matches::WILDCARD_IN_OR_PATTERNS,
- mem_forget::MEM_FORGET,
- mem_replace::MEM_REPLACE_OPTION_WITH_NONE,
- mem_replace::MEM_REPLACE_WITH_DEFAULT,
- mem_replace::MEM_REPLACE_WITH_UNINIT,
- methods::BIND_INSTEAD_OF_MAP,
- methods::BYTES_COUNT_TO_LEN,
- methods::BYTES_NTH,
- methods::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
- methods::CHARS_LAST_CMP,
- methods::CHARS_NEXT_CMP,
- methods::CLONED_INSTEAD_OF_COPIED,
- methods::CLONE_DOUBLE_REF,
- methods::CLONE_ON_COPY,
- methods::CLONE_ON_REF_PTR,
- methods::COLLAPSIBLE_STR_REPLACE,
- methods::ERR_EXPECT,
- methods::EXPECT_FUN_CALL,
- methods::EXPECT_USED,
- methods::EXTEND_WITH_DRAIN,
- methods::FILETYPE_IS_FILE,
- methods::FILTER_MAP_IDENTITY,
- methods::FILTER_MAP_NEXT,
- methods::FILTER_NEXT,
- methods::FLAT_MAP_IDENTITY,
- methods::FLAT_MAP_OPTION,
- methods::FROM_ITER_INSTEAD_OF_COLLECT,
- methods::GET_FIRST,
- methods::GET_LAST_WITH_LEN,
- methods::GET_UNWRAP,
- methods::IMPLICIT_CLONE,
- methods::INEFFICIENT_TO_STRING,
- methods::INSPECT_FOR_EACH,
- methods::INTO_ITER_ON_REF,
- methods::IS_DIGIT_ASCII_RADIX,
- methods::ITERATOR_STEP_BY_ZERO,
- methods::ITER_CLONED_COLLECT,
- methods::ITER_COUNT,
- methods::ITER_KV_MAP,
- methods::ITER_NEXT_SLICE,
- methods::ITER_NTH,
- methods::ITER_NTH_ZERO,
- methods::ITER_ON_EMPTY_COLLECTIONS,
- methods::ITER_ON_SINGLE_ITEMS,
- methods::ITER_OVEREAGER_CLONED,
- methods::ITER_SKIP_NEXT,
- methods::ITER_WITH_DRAIN,
- methods::MANUAL_FILTER_MAP,
- methods::MANUAL_FIND_MAP,
- methods::MANUAL_OK_OR,
- methods::MANUAL_SATURATING_ARITHMETIC,
- methods::MANUAL_SPLIT_ONCE,
- methods::MANUAL_STR_REPEAT,
- methods::MAP_CLONE,
- methods::MAP_COLLECT_RESULT_UNIT,
- methods::MAP_ERR_IGNORE,
- methods::MAP_FLATTEN,
- methods::MAP_IDENTITY,
- methods::MAP_UNWRAP_OR,
- methods::MUT_MUTEX_LOCK,
- methods::NAIVE_BYTECOUNT,
- methods::NEEDLESS_OPTION_AS_DEREF,
- methods::NEEDLESS_OPTION_TAKE,
- methods::NEEDLESS_SPLITN,
- methods::NEW_RET_NO_SELF,
- methods::NONSENSICAL_OPEN_OPTIONS,
- methods::NO_EFFECT_REPLACE,
- methods::OBFUSCATED_IF_ELSE,
- methods::OK_EXPECT,
- methods::OPTION_AS_REF_DEREF,
- methods::OPTION_FILTER_MAP,
- methods::OPTION_MAP_OR_NONE,
- methods::OR_FUN_CALL,
- methods::OR_THEN_UNWRAP,
- methods::PATH_BUF_PUSH_OVERWRITE,
- methods::RANGE_ZIP_WITH_LEN,
- methods::REPEAT_ONCE,
- methods::RESULT_MAP_OR_INTO_OPTION,
- methods::SEARCH_IS_SOME,
- methods::SHOULD_IMPLEMENT_TRAIT,
- methods::SINGLE_CHAR_ADD_STR,
- methods::SINGLE_CHAR_PATTERN,
- methods::SKIP_WHILE_NEXT,
- methods::STABLE_SORT_PRIMITIVE,
- methods::STRING_EXTEND_CHARS,
- methods::SUSPICIOUS_MAP,
- methods::SUSPICIOUS_SPLITN,
- methods::SUSPICIOUS_TO_OWNED,
- methods::UNINIT_ASSUMED_INIT,
- methods::UNIT_HASH,
- methods::UNNECESSARY_FILTER_MAP,
- methods::UNNECESSARY_FIND_MAP,
- methods::UNNECESSARY_FOLD,
- methods::UNNECESSARY_JOIN,
- methods::UNNECESSARY_LAZY_EVALUATIONS,
- methods::UNNECESSARY_SORT_BY,
- methods::UNNECESSARY_TO_OWNED,
- methods::UNWRAP_OR_ELSE_DEFAULT,
- methods::UNWRAP_USED,
- methods::USELESS_ASREF,
- methods::VEC_RESIZE_TO_ZERO,
- methods::VERBOSE_FILE_READS,
- methods::WRONG_SELF_CONVENTION,
- methods::ZST_OFFSET,
- minmax::MIN_MAX,
- misc::SHORT_CIRCUIT_STATEMENT,
- misc::TOPLEVEL_REF_ARG,
- misc::USED_UNDERSCORE_BINDING,
- misc::ZERO_PTR,
- misc_early::BUILTIN_TYPE_SHADOW,
- misc_early::DOUBLE_NEG,
- misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
- misc_early::MIXED_CASE_HEX_LITERALS,
- misc_early::REDUNDANT_PATTERN,
- misc_early::SEPARATED_LITERAL_SUFFIX,
- misc_early::UNNEEDED_FIELD_PATTERN,
- misc_early::UNNEEDED_WILDCARD_PATTERN,
- misc_early::UNSEPARATED_LITERAL_SUFFIX,
- misc_early::ZERO_PREFIXED_LITERAL,
- mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER,
- missing_const_for_fn::MISSING_CONST_FOR_FN,
- missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS,
- missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES,
- missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS,
- missing_trait_methods::MISSING_TRAIT_METHODS,
- mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION,
- mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION,
- module_style::MOD_MODULE_FILES,
- module_style::SELF_NAMED_MODULE_FILES,
- multi_assignments::MULTI_ASSIGNMENTS,
- mut_key::MUTABLE_KEY_TYPE,
- mut_mut::MUT_MUT,
- mut_reference::UNNECESSARY_MUT_PASSED,
- mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL,
- mutex_atomic::MUTEX_ATOMIC,
- mutex_atomic::MUTEX_INTEGER,
- needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE,
- needless_bool::BOOL_COMPARISON,
- needless_bool::NEEDLESS_BOOL,
- needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE,
- needless_continue::NEEDLESS_CONTINUE,
- needless_for_each::NEEDLESS_FOR_EACH,
- needless_late_init::NEEDLESS_LATE_INIT,
- needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS,
- needless_pass_by_value::NEEDLESS_PASS_BY_VALUE,
- needless_question_mark::NEEDLESS_QUESTION_MARK,
- needless_update::NEEDLESS_UPDATE,
- neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD,
- neg_multiply::NEG_MULTIPLY,
- new_without_default::NEW_WITHOUT_DEFAULT,
- no_effect::NO_EFFECT,
- no_effect::NO_EFFECT_UNDERSCORE_BINDING,
- no_effect::UNNECESSARY_OPERATION,
- non_copy_const::BORROW_INTERIOR_MUTABLE_CONST,
- non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST,
- non_expressive_names::JUST_UNDERSCORES_AND_DIGITS,
- non_expressive_names::MANY_SINGLE_CHAR_NAMES,
- non_expressive_names::SIMILAR_NAMES,
- non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS,
- non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY,
- nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES,
- octal_escapes::OCTAL_ESCAPES,
- only_used_in_recursion::ONLY_USED_IN_RECURSION,
- operators::ABSURD_EXTREME_COMPARISONS,
- operators::ARITHMETIC_SIDE_EFFECTS,
- operators::ASSIGN_OP_PATTERN,
- operators::BAD_BIT_MASK,
- operators::CMP_NAN,
- operators::CMP_OWNED,
- operators::DOUBLE_COMPARISONS,
- operators::DURATION_SUBSEC,
- operators::EQ_OP,
- operators::ERASING_OP,
- operators::FLOAT_ARITHMETIC,
- operators::FLOAT_CMP,
- operators::FLOAT_CMP_CONST,
- operators::FLOAT_EQUALITY_WITHOUT_ABS,
- operators::IDENTITY_OP,
- operators::INEFFECTIVE_BIT_MASK,
- operators::INTEGER_ARITHMETIC,
- operators::INTEGER_DIVISION,
- operators::MISREFACTORED_ASSIGN_OP,
- operators::MODULO_ARITHMETIC,
- operators::MODULO_ONE,
- operators::NEEDLESS_BITWISE_BOOL,
- operators::OP_REF,
- operators::PTR_EQ,
- operators::SELF_ASSIGNMENT,
- operators::VERBOSE_BIT_MASK,
- option_env_unwrap::OPTION_ENV_UNWRAP,
- option_if_let_else::OPTION_IF_LET_ELSE,
- overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
- panic_in_result_fn::PANIC_IN_RESULT_FN,
- panic_unimplemented::PANIC,
- panic_unimplemented::TODO,
- panic_unimplemented::UNIMPLEMENTED,
- panic_unimplemented::UNREACHABLE,
- partial_pub_fields::PARTIAL_PUB_FIELDS,
- partialeq_ne_impl::PARTIALEQ_NE_IMPL,
- partialeq_to_none::PARTIALEQ_TO_NONE,
- pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE,
- pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF,
- pattern_type_mismatch::PATTERN_TYPE_MISMATCH,
- precedence::PRECEDENCE,
- ptr::CMP_NULL,
- ptr::INVALID_NULL_PTR_USAGE,
- ptr::MUT_FROM_REF,
- ptr::PTR_ARG,
- ptr_offset_with_cast::PTR_OFFSET_WITH_CAST,
- pub_use::PUB_USE,
- question_mark::QUESTION_MARK,
- ranges::MANUAL_RANGE_CONTAINS,
- ranges::RANGE_MINUS_ONE,
- ranges::RANGE_PLUS_ONE,
- ranges::REVERSED_EMPTY_RANGES,
- rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT,
- read_zero_byte_vec::READ_ZERO_BYTE_VEC,
- redundant_clone::REDUNDANT_CLONE,
- redundant_closure_call::REDUNDANT_CLOSURE_CALL,
- redundant_else::REDUNDANT_ELSE,
- redundant_field_names::REDUNDANT_FIELD_NAMES,
- redundant_pub_crate::REDUNDANT_PUB_CRATE,
- redundant_slicing::DEREF_BY_SLICING,
- redundant_slicing::REDUNDANT_SLICING,
- redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
- ref_option_ref::REF_OPTION_REF,
- reference::DEREF_ADDROF,
- regex::INVALID_REGEX,
- regex::TRIVIAL_REGEX,
- return_self_not_must_use::RETURN_SELF_NOT_MUST_USE,
- returns::LET_AND_RETURN,
- returns::NEEDLESS_RETURN,
- same_name_method::SAME_NAME_METHOD,
- self_named_constructors::SELF_NAMED_CONSTRUCTORS,
- semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED,
- serde_api::SERDE_API_MISUSE,
- shadow::SHADOW_REUSE,
- shadow::SHADOW_SAME,
- shadow::SHADOW_UNRELATED,
- single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES,
- single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS,
- size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT,
- slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,
- std_instead_of_core::ALLOC_INSTEAD_OF_CORE,
- std_instead_of_core::STD_INSTEAD_OF_ALLOC,
- std_instead_of_core::STD_INSTEAD_OF_CORE,
- strings::STRING_ADD,
- strings::STRING_ADD_ASSIGN,
- strings::STRING_FROM_UTF8_AS_BYTES,
- strings::STRING_LIT_AS_BYTES,
- strings::STRING_SLICE,
- strings::STRING_TO_STRING,
- strings::STR_TO_STRING,
- strings::TRIM_SPLIT_WHITESPACE,
- strlen_on_c_strings::STRLEN_ON_C_STRINGS,
- suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS,
- suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL,
- suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL,
- swap::ALMOST_SWAPPED,
- swap::MANUAL_SWAP,
- swap_ptr_to_ref::SWAP_PTR_TO_REF,
- tabs_in_doc_comments::TABS_IN_DOC_COMMENTS,
- temporary_assignment::TEMPORARY_ASSIGNMENT,
- to_digit_is_some::TO_DIGIT_IS_SOME,
- trailing_empty_array::TRAILING_EMPTY_ARRAY,
- trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS,
- trait_bounds::TYPE_REPETITION_IN_BOUNDS,
- transmute::CROSSPOINTER_TRANSMUTE,
- transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
- transmute::TRANSMUTE_BYTES_TO_STR,
- transmute::TRANSMUTE_FLOAT_TO_INT,
- transmute::TRANSMUTE_INT_TO_BOOL,
- transmute::TRANSMUTE_INT_TO_CHAR,
- transmute::TRANSMUTE_INT_TO_FLOAT,
- transmute::TRANSMUTE_NUM_TO_BYTES,
- transmute::TRANSMUTE_PTR_TO_PTR,
- transmute::TRANSMUTE_PTR_TO_REF,
- transmute::TRANSMUTE_UNDEFINED_REPR,
- transmute::TRANSMUTING_NULL,
- transmute::UNSOUND_COLLECTION_TRANSMUTE,
- transmute::USELESS_TRANSMUTE,
- transmute::WRONG_TRANSMUTE,
- types::BORROWED_BOX,
- types::BOX_COLLECTION,
- types::LINKEDLIST,
- types::OPTION_OPTION,
- types::RC_BUFFER,
- types::RC_MUTEX,
- types::REDUNDANT_ALLOCATION,
- types::TYPE_COMPLEXITY,
- types::VEC_BOX,
- undocumented_unsafe_blocks::UNDOCUMENTED_UNSAFE_BLOCKS,
- unicode::INVISIBLE_CHARACTERS,
- unicode::NON_ASCII_LITERAL,
- unicode::UNICODE_NOT_NFC,
- uninit_vec::UNINIT_VEC,
- unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD,
- unit_types::LET_UNIT_VALUE,
- unit_types::UNIT_ARG,
- unit_types::UNIT_CMP,
- unnamed_address::FN_ADDRESS_COMPARISONS,
- unnamed_address::VTABLE_ADDRESS_COMPARISONS,
- unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS,
- unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS,
- unnecessary_wraps::UNNECESSARY_WRAPS,
- unnested_or_patterns::UNNESTED_OR_PATTERNS,
- unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
- unused_async::UNUSED_ASYNC,
- unused_io_amount::UNUSED_IO_AMOUNT,
- unused_peekable::UNUSED_PEEKABLE,
- unused_rounding::UNUSED_ROUNDING,
- unused_self::UNUSED_SELF,
- unused_unit::UNUSED_UNIT,
- unwrap::PANICKING_UNWRAP,
- unwrap::UNNECESSARY_UNWRAP,
- unwrap_in_result::UNWRAP_IN_RESULT,
- upper_case_acronyms::UPPER_CASE_ACRONYMS,
- use_self::USE_SELF,
- useless_conversion::USELESS_CONVERSION,
- vec::USELESS_VEC,
- vec_init_then_push::VEC_INIT_THEN_PUSH,
- wildcard_imports::ENUM_GLOB_USE,
- wildcard_imports::WILDCARD_IMPORTS,
- write::PRINTLN_EMPTY_STRING,
- write::PRINT_LITERAL,
- write::PRINT_STDERR,
- write::PRINT_STDOUT,
- write::PRINT_WITH_NEWLINE,
- write::USE_DEBUG,
- write::WRITELN_EMPTY_STRING,
- write::WRITE_LITERAL,
- write::WRITE_WITH_NEWLINE,
- zero_div_zero::ZERO_DIVIDED_BY_ZERO,
- zero_sized_map_values::ZERO_SIZED_MAP_VALUES,
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs b/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs
deleted file mode 100644
index 65616d28d..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
- LintId::of(attrs::EMPTY_LINE_AFTER_OUTER_ATTR),
- LintId::of(casts::AS_PTR_CAST_MUT),
- LintId::of(cognitive_complexity::COGNITIVE_COMPLEXITY),
- LintId::of(copies::BRANCHES_SHARING_CODE),
- LintId::of(derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ),
- LintId::of(equatable_if_let::EQUATABLE_IF_LET),
- LintId::of(fallible_impl_from::FALLIBLE_IMPL_FROM),
- LintId::of(floating_point_arithmetic::IMPRECISE_FLOPS),
- LintId::of(floating_point_arithmetic::SUBOPTIMAL_FLOPS),
- LintId::of(future_not_send::FUTURE_NOT_SEND),
- LintId::of(index_refutable_slice::INDEX_REFUTABLE_SLICE),
- LintId::of(let_if_seq::USELESS_LET_IF_SEQ),
- LintId::of(matches::SIGNIFICANT_DROP_IN_SCRUTINEE),
- LintId::of(methods::ITER_ON_EMPTY_COLLECTIONS),
- LintId::of(methods::ITER_ON_SINGLE_ITEMS),
- LintId::of(methods::ITER_WITH_DRAIN),
- LintId::of(methods::PATH_BUF_PUSH_OVERWRITE),
- LintId::of(missing_const_for_fn::MISSING_CONST_FOR_FN),
- LintId::of(mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL),
- LintId::of(mutex_atomic::MUTEX_ATOMIC),
- LintId::of(mutex_atomic::MUTEX_INTEGER),
- LintId::of(non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY),
- LintId::of(nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES),
- LintId::of(option_if_let_else::OPTION_IF_LET_ELSE),
- LintId::of(redundant_pub_crate::REDUNDANT_PUB_CRATE),
- LintId::of(regex::TRIVIAL_REGEX),
- LintId::of(strings::STRING_LIT_AS_BYTES),
- LintId::of(suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS),
- LintId::of(trailing_empty_array::TRAILING_EMPTY_ARRAY),
- LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
- LintId::of(unused_peekable::UNUSED_PEEKABLE),
- LintId::of(unused_rounding::UNUSED_ROUNDING),
- LintId::of(use_self::USE_SELF),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs b/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs
deleted file mode 100644
index 44e969585..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_pedantic.rs
+++ /dev/null
@@ -1,104 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
- LintId::of(attrs::INLINE_ALWAYS),
- LintId::of(casts::BORROW_AS_PTR),
- LintId::of(casts::CAST_LOSSLESS),
- LintId::of(casts::CAST_POSSIBLE_TRUNCATION),
- LintId::of(casts::CAST_POSSIBLE_WRAP),
- LintId::of(casts::CAST_PRECISION_LOSS),
- LintId::of(casts::CAST_PTR_ALIGNMENT),
- LintId::of(casts::CAST_SIGN_LOSS),
- LintId::of(casts::PTR_AS_PTR),
- LintId::of(checked_conversions::CHECKED_CONVERSIONS),
- LintId::of(copies::SAME_FUNCTIONS_IN_IF_CONDITION),
- LintId::of(copy_iterator::COPY_ITERATOR),
- LintId::of(default::DEFAULT_TRAIT_ACCESS),
- LintId::of(dereference::EXPLICIT_DEREF_METHODS),
- LintId::of(dereference::REF_BINDING_TO_REFERENCE),
- LintId::of(derive::EXPL_IMPL_CLONE_ON_COPY),
- LintId::of(derive::UNSAFE_DERIVE_DESERIALIZE),
- LintId::of(doc::DOC_LINK_WITH_QUOTES),
- LintId::of(doc::DOC_MARKDOWN),
- LintId::of(doc::MISSING_ERRORS_DOC),
- LintId::of(doc::MISSING_PANICS_DOC),
- LintId::of(empty_enum::EMPTY_ENUM),
- LintId::of(enum_variants::MODULE_NAME_REPETITIONS),
- LintId::of(eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS),
- LintId::of(excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS),
- LintId::of(excessive_bools::STRUCT_EXCESSIVE_BOOLS),
- LintId::of(format_args::UNINLINED_FORMAT_ARGS),
- LintId::of(functions::MUST_USE_CANDIDATE),
- LintId::of(functions::TOO_MANY_LINES),
- LintId::of(if_not_else::IF_NOT_ELSE),
- LintId::of(implicit_hasher::IMPLICIT_HASHER),
- LintId::of(inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR),
- LintId::of(infinite_iter::MAYBE_INFINITE_ITER),
- LintId::of(invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS),
- LintId::of(items_after_statements::ITEMS_AFTER_STATEMENTS),
- LintId::of(iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR),
- LintId::of(large_stack_arrays::LARGE_STACK_ARRAYS),
- LintId::of(let_underscore::LET_UNDERSCORE_DROP),
- LintId::of(literal_representation::LARGE_DIGIT_GROUPS),
- LintId::of(literal_representation::UNREADABLE_LITERAL),
- LintId::of(loops::EXPLICIT_INTO_ITER_LOOP),
- LintId::of(loops::EXPLICIT_ITER_LOOP),
- LintId::of(macro_use::MACRO_USE_IMPORTS),
- LintId::of(manual_assert::MANUAL_ASSERT),
- LintId::of(manual_instant_elapsed::MANUAL_INSTANT_ELAPSED),
- LintId::of(manual_string_new::MANUAL_STRING_NEW),
- LintId::of(matches::MATCH_BOOL),
- LintId::of(matches::MATCH_ON_VEC_ITEMS),
- LintId::of(matches::MATCH_SAME_ARMS),
- LintId::of(matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS),
- LintId::of(matches::MATCH_WILD_ERR_ARM),
- LintId::of(matches::SINGLE_MATCH_ELSE),
- LintId::of(methods::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS),
- LintId::of(methods::CLONED_INSTEAD_OF_COPIED),
- LintId::of(methods::FILTER_MAP_NEXT),
- LintId::of(methods::FLAT_MAP_OPTION),
- LintId::of(methods::FROM_ITER_INSTEAD_OF_COLLECT),
- LintId::of(methods::IMPLICIT_CLONE),
- LintId::of(methods::INEFFICIENT_TO_STRING),
- LintId::of(methods::MANUAL_OK_OR),
- LintId::of(methods::MAP_UNWRAP_OR),
- LintId::of(methods::NAIVE_BYTECOUNT),
- LintId::of(methods::STABLE_SORT_PRIMITIVE),
- LintId::of(methods::UNNECESSARY_JOIN),
- LintId::of(misc::USED_UNDERSCORE_BINDING),
- LintId::of(mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER),
- LintId::of(mut_mut::MUT_MUT),
- LintId::of(needless_continue::NEEDLESS_CONTINUE),
- LintId::of(needless_for_each::NEEDLESS_FOR_EACH),
- LintId::of(needless_pass_by_value::NEEDLESS_PASS_BY_VALUE),
- LintId::of(no_effect::NO_EFFECT_UNDERSCORE_BINDING),
- LintId::of(non_expressive_names::MANY_SINGLE_CHAR_NAMES),
- LintId::of(non_expressive_names::SIMILAR_NAMES),
- LintId::of(operators::FLOAT_CMP),
- LintId::of(operators::NEEDLESS_BITWISE_BOOL),
- LintId::of(operators::VERBOSE_BIT_MASK),
- LintId::of(pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE),
- LintId::of(pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF),
- LintId::of(ranges::RANGE_MINUS_ONE),
- LintId::of(ranges::RANGE_PLUS_ONE),
- LintId::of(redundant_else::REDUNDANT_ELSE),
- LintId::of(ref_option_ref::REF_OPTION_REF),
- LintId::of(return_self_not_must_use::RETURN_SELF_NOT_MUST_USE),
- LintId::of(semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED),
- LintId::of(strings::STRING_ADD_ASSIGN),
- LintId::of(trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
- LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
- LintId::of(transmute::TRANSMUTE_PTR_TO_PTR),
- LintId::of(types::LINKEDLIST),
- LintId::of(types::OPTION_OPTION),
- LintId::of(unicode::UNICODE_NOT_NFC),
- LintId::of(unnecessary_wraps::UNNECESSARY_WRAPS),
- LintId::of(unnested_or_patterns::UNNESTED_OR_PATTERNS),
- LintId::of(unused_async::UNUSED_ASYNC),
- LintId::of(unused_self::UNUSED_SELF),
- LintId::of(wildcard_imports::ENUM_GLOB_USE),
- LintId::of(wildcard_imports::WILDCARD_IMPORTS),
- LintId::of(zero_sized_map_values::ZERO_SIZED_MAP_VALUES),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_perf.rs b/src/tools/clippy/clippy_lints/src/lib.register_perf.rs
deleted file mode 100644
index 8e927470e..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_perf.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::perf", Some("clippy_perf"), vec![
- LintId::of(box_default::BOX_DEFAULT),
- LintId::of(entry::MAP_ENTRY),
- LintId::of(escape::BOXED_LOCAL),
- LintId::of(format_args::FORMAT_IN_FORMAT_ARGS),
- LintId::of(format_args::TO_STRING_IN_FORMAT_ARGS),
- LintId::of(functions::RESULT_LARGE_ERR),
- LintId::of(large_const_arrays::LARGE_CONST_ARRAYS),
- LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
- LintId::of(loops::MANUAL_MEMCPY),
- LintId::of(loops::MISSING_SPIN_LOOP),
- LintId::of(loops::NEEDLESS_COLLECT),
- LintId::of(manual_retain::MANUAL_RETAIN),
- LintId::of(methods::COLLAPSIBLE_STR_REPLACE),
- LintId::of(methods::EXPECT_FUN_CALL),
- LintId::of(methods::EXTEND_WITH_DRAIN),
- LintId::of(methods::ITER_NTH),
- LintId::of(methods::ITER_OVEREAGER_CLONED),
- LintId::of(methods::MANUAL_STR_REPEAT),
- LintId::of(methods::OR_FUN_CALL),
- LintId::of(methods::SINGLE_CHAR_PATTERN),
- LintId::of(methods::UNNECESSARY_TO_OWNED),
- LintId::of(operators::CMP_OWNED),
- LintId::of(redundant_clone::REDUNDANT_CLONE),
- LintId::of(slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
- LintId::of(types::BOX_COLLECTION),
- LintId::of(types::REDUNDANT_ALLOCATION),
- LintId::of(vec::USELESS_VEC),
- LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs b/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
deleted file mode 100644
index f62d57af5..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
- LintId::of(as_conversions::AS_CONVERSIONS),
- LintId::of(asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
- LintId::of(asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
- LintId::of(assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES),
- LintId::of(attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON),
- LintId::of(casts::AS_UNDERSCORE),
- LintId::of(casts::FN_TO_NUMERIC_CAST_ANY),
- LintId::of(create_dir::CREATE_DIR),
- LintId::of(dbg_macro::DBG_MACRO),
- LintId::of(default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK),
- LintId::of(default_union_representation::DEFAULT_UNION_REPRESENTATION),
- LintId::of(disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS),
- LintId::of(else_if_without_else::ELSE_IF_WITHOUT_ELSE),
- LintId::of(empty_drop::EMPTY_DROP),
- LintId::of(empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS),
- LintId::of(exhaustive_items::EXHAUSTIVE_ENUMS),
- LintId::of(exhaustive_items::EXHAUSTIVE_STRUCTS),
- LintId::of(exit::EXIT),
- LintId::of(float_literal::LOSSY_FLOAT_LITERAL),
- LintId::of(format_push_string::FORMAT_PUSH_STRING),
- LintId::of(if_then_some_else_none::IF_THEN_SOME_ELSE_NONE),
- LintId::of(implicit_return::IMPLICIT_RETURN),
- LintId::of(indexing_slicing::INDEXING_SLICING),
- LintId::of(inherent_impl::MULTIPLE_INHERENT_IMPL),
- LintId::of(large_include_file::LARGE_INCLUDE_FILE),
- LintId::of(let_underscore::LET_UNDERSCORE_MUST_USE),
- LintId::of(literal_representation::DECIMAL_LITERAL_REPRESENTATION),
- LintId::of(matches::REST_PAT_IN_FULLY_BOUND_STRUCTS),
- LintId::of(matches::TRY_ERR),
- LintId::of(matches::WILDCARD_ENUM_MATCH_ARM),
- LintId::of(mem_forget::MEM_FORGET),
- LintId::of(methods::CLONE_ON_REF_PTR),
- LintId::of(methods::EXPECT_USED),
- LintId::of(methods::FILETYPE_IS_FILE),
- LintId::of(methods::GET_UNWRAP),
- LintId::of(methods::MAP_ERR_IGNORE),
- LintId::of(methods::UNWRAP_USED),
- LintId::of(methods::VERBOSE_FILE_READS),
- LintId::of(misc_early::SEPARATED_LITERAL_SUFFIX),
- LintId::of(misc_early::UNNEEDED_FIELD_PATTERN),
- LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
- LintId::of(missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS),
- LintId::of(missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES),
- LintId::of(missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS),
- LintId::of(missing_trait_methods::MISSING_TRAIT_METHODS),
- LintId::of(mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION),
- LintId::of(module_style::MOD_MODULE_FILES),
- LintId::of(module_style::SELF_NAMED_MODULE_FILES),
- LintId::of(operators::ARITHMETIC_SIDE_EFFECTS),
- LintId::of(operators::FLOAT_ARITHMETIC),
- LintId::of(operators::FLOAT_CMP_CONST),
- LintId::of(operators::INTEGER_ARITHMETIC),
- LintId::of(operators::INTEGER_DIVISION),
- LintId::of(operators::MODULO_ARITHMETIC),
- LintId::of(panic_in_result_fn::PANIC_IN_RESULT_FN),
- LintId::of(panic_unimplemented::PANIC),
- LintId::of(panic_unimplemented::TODO),
- LintId::of(panic_unimplemented::UNIMPLEMENTED),
- LintId::of(panic_unimplemented::UNREACHABLE),
- LintId::of(partial_pub_fields::PARTIAL_PUB_FIELDS),
- LintId::of(pattern_type_mismatch::PATTERN_TYPE_MISMATCH),
- LintId::of(pub_use::PUB_USE),
- LintId::of(redundant_slicing::DEREF_BY_SLICING),
- LintId::of(same_name_method::SAME_NAME_METHOD),
- LintId::of(shadow::SHADOW_REUSE),
- LintId::of(shadow::SHADOW_SAME),
- LintId::of(shadow::SHADOW_UNRELATED),
- LintId::of(single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES),
- LintId::of(std_instead_of_core::ALLOC_INSTEAD_OF_CORE),
- LintId::of(std_instead_of_core::STD_INSTEAD_OF_ALLOC),
- LintId::of(std_instead_of_core::STD_INSTEAD_OF_CORE),
- LintId::of(strings::STRING_ADD),
- LintId::of(strings::STRING_SLICE),
- LintId::of(strings::STRING_TO_STRING),
- LintId::of(strings::STR_TO_STRING),
- LintId::of(types::RC_BUFFER),
- LintId::of(types::RC_MUTEX),
- LintId::of(undocumented_unsafe_blocks::UNDOCUMENTED_UNSAFE_BLOCKS),
- LintId::of(unicode::NON_ASCII_LITERAL),
- LintId::of(unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS),
- LintId::of(unwrap_in_result::UNWRAP_IN_RESULT),
- LintId::of(write::PRINT_STDERR),
- LintId::of(write::PRINT_STDOUT),
- LintId::of(write::USE_DEBUG),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_style.rs b/src/tools/clippy/clippy_lints/src/lib.register_style.rs
deleted file mode 100644
index 3312f5648..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_style.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::style", Some("clippy_style"), vec![
- LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
- LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
- LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
- LintId::of(bool_to_int_with_if::BOOL_TO_INT_WITH_IF),
- LintId::of(casts::FN_TO_NUMERIC_CAST),
- LintId::of(casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
- LintId::of(collapsible_if::COLLAPSIBLE_ELSE_IF),
- LintId::of(collapsible_if::COLLAPSIBLE_IF),
- LintId::of(comparison_chain::COMPARISON_CHAIN),
- LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
- LintId::of(default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY),
- LintId::of(dereference::NEEDLESS_BORROW),
- LintId::of(disallowed_macros::DISALLOWED_MACROS),
- LintId::of(disallowed_methods::DISALLOWED_METHODS),
- LintId::of(disallowed_names::DISALLOWED_NAMES),
- LintId::of(disallowed_types::DISALLOWED_TYPES),
- LintId::of(doc::MISSING_SAFETY_DOC),
- LintId::of(doc::NEEDLESS_DOCTEST_MAIN),
- LintId::of(enum_variants::ENUM_VARIANT_NAMES),
- LintId::of(enum_variants::MODULE_INCEPTION),
- LintId::of(eta_reduction::REDUNDANT_CLOSURE),
- LintId::of(float_literal::EXCESSIVE_PRECISION),
- LintId::of(from_over_into::FROM_OVER_INTO),
- LintId::of(from_str_radix_10::FROM_STR_RADIX_10),
- LintId::of(functions::DOUBLE_MUST_USE),
- LintId::of(functions::MUST_USE_UNIT),
- LintId::of(functions::RESULT_UNIT_ERR),
- LintId::of(implicit_saturating_add::IMPLICIT_SATURATING_ADD),
- LintId::of(implicit_saturating_sub::IMPLICIT_SATURATING_SUB),
- LintId::of(inherent_to_string::INHERENT_TO_STRING),
- LintId::of(init_numbered_fields::INIT_NUMBERED_FIELDS),
- LintId::of(len_zero::COMPARISON_TO_EMPTY),
- LintId::of(len_zero::LEN_WITHOUT_IS_EMPTY),
- LintId::of(len_zero::LEN_ZERO),
- LintId::of(literal_representation::INCONSISTENT_DIGIT_GROUPING),
- LintId::of(literal_representation::UNUSUAL_BYTE_GROUPINGS),
- LintId::of(loops::FOR_KV_MAP),
- LintId::of(loops::NEEDLESS_RANGE_LOOP),
- LintId::of(loops::SAME_ITEM_PUSH),
- LintId::of(loops::WHILE_LET_ON_ITERATOR),
- LintId::of(main_recursion::MAIN_RECURSION),
- LintId::of(manual_async_fn::MANUAL_ASYNC_FN),
- LintId::of(manual_bits::MANUAL_BITS),
- LintId::of(manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
- LintId::of(match_result_ok::MATCH_RESULT_OK),
- LintId::of(matches::COLLAPSIBLE_MATCH),
- LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
- LintId::of(matches::MANUAL_MAP),
- LintId::of(matches::MATCH_LIKE_MATCHES_MACRO),
- LintId::of(matches::MATCH_OVERLAPPING_ARM),
- LintId::of(matches::MATCH_REF_PATS),
- LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
- LintId::of(matches::SINGLE_MATCH),
- LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
- LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
- LintId::of(methods::BYTES_NTH),
- LintId::of(methods::CHARS_LAST_CMP),
- LintId::of(methods::CHARS_NEXT_CMP),
- LintId::of(methods::ERR_EXPECT),
- LintId::of(methods::GET_FIRST),
- LintId::of(methods::INTO_ITER_ON_REF),
- LintId::of(methods::IS_DIGIT_ASCII_RADIX),
- LintId::of(methods::ITER_CLONED_COLLECT),
- LintId::of(methods::ITER_NEXT_SLICE),
- LintId::of(methods::ITER_NTH_ZERO),
- LintId::of(methods::ITER_SKIP_NEXT),
- LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
- LintId::of(methods::MAP_CLONE),
- LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
- LintId::of(methods::MUT_MUTEX_LOCK),
- LintId::of(methods::NEW_RET_NO_SELF),
- LintId::of(methods::OBFUSCATED_IF_ELSE),
- LintId::of(methods::OK_EXPECT),
- LintId::of(methods::OPTION_MAP_OR_NONE),
- LintId::of(methods::RESULT_MAP_OR_INTO_OPTION),
- LintId::of(methods::SHOULD_IMPLEMENT_TRAIT),
- LintId::of(methods::SINGLE_CHAR_ADD_STR),
- LintId::of(methods::STRING_EXTEND_CHARS),
- LintId::of(methods::UNNECESSARY_FOLD),
- LintId::of(methods::UNNECESSARY_LAZY_EVALUATIONS),
- LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
- LintId::of(methods::WRONG_SELF_CONVENTION),
- LintId::of(misc::TOPLEVEL_REF_ARG),
- LintId::of(misc::ZERO_PTR),
- LintId::of(misc_early::BUILTIN_TYPE_SHADOW),
- LintId::of(misc_early::DOUBLE_NEG),
- LintId::of(misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
- LintId::of(misc_early::MIXED_CASE_HEX_LITERALS),
- LintId::of(misc_early::REDUNDANT_PATTERN),
- LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
- LintId::of(needless_late_init::NEEDLESS_LATE_INIT),
- LintId::of(needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS),
- LintId::of(neg_multiply::NEG_MULTIPLY),
- LintId::of(new_without_default::NEW_WITHOUT_DEFAULT),
- LintId::of(non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
- LintId::of(non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
- LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
- LintId::of(operators::ASSIGN_OP_PATTERN),
- LintId::of(operators::OP_REF),
- LintId::of(operators::PTR_EQ),
- LintId::of(partialeq_to_none::PARTIALEQ_TO_NONE),
- LintId::of(ptr::CMP_NULL),
- LintId::of(ptr::PTR_ARG),
- LintId::of(question_mark::QUESTION_MARK),
- LintId::of(ranges::MANUAL_RANGE_CONTAINS),
- LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES),
- LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
- LintId::of(returns::LET_AND_RETURN),
- LintId::of(returns::NEEDLESS_RETURN),
- LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
- LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
- LintId::of(strings::TRIM_SPLIT_WHITESPACE),
- LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
- LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
- LintId::of(unit_types::LET_UNIT_VALUE),
- LintId::of(unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS),
- LintId::of(unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
- LintId::of(unused_unit::UNUSED_UNIT),
- LintId::of(upper_case_acronyms::UPPER_CASE_ACRONYMS),
- LintId::of(write::PRINTLN_EMPTY_STRING),
- LintId::of(write::PRINT_LITERAL),
- LintId::of(write::PRINT_WITH_NEWLINE),
- LintId::of(write::WRITELN_EMPTY_STRING),
- LintId::of(write::WRITE_LITERAL),
- LintId::of(write::WRITE_WITH_NEWLINE),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs b/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs
deleted file mode 100644
index b70c4bb73..000000000
--- a/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec![
- LintId::of(almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE),
- LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
- LintId::of(await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE),
- LintId::of(await_holding_invalid::AWAIT_HOLDING_LOCK),
- LintId::of(await_holding_invalid::AWAIT_HOLDING_REFCELL_REF),
- LintId::of(casts::CAST_ABS_TO_UNSIGNED),
- LintId::of(casts::CAST_ENUM_CONSTRUCTOR),
- LintId::of(casts::CAST_ENUM_TRUNCATION),
- LintId::of(casts::CAST_NAN_TO_INT),
- LintId::of(casts::CAST_SLICE_FROM_RAW_PARTS),
- LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF),
- LintId::of(drop_forget_ref::DROP_NON_DROP),
- LintId::of(drop_forget_ref::FORGET_NON_DROP),
- LintId::of(duplicate_mod::DUPLICATE_MOD),
- LintId::of(format_impl::PRINT_IN_FORMAT_IMPL),
- LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
- LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
- LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
- LintId::of(loops::EMPTY_LOOP),
- LintId::of(loops::MUT_RANGE_BOUND),
- LintId::of(methods::NO_EFFECT_REPLACE),
- LintId::of(methods::SUSPICIOUS_MAP),
- LintId::of(methods::SUSPICIOUS_TO_OWNED),
- LintId::of(multi_assignments::MULTI_ASSIGNMENTS),
- LintId::of(mut_key::MUTABLE_KEY_TYPE),
- LintId::of(octal_escapes::OCTAL_ESCAPES),
- LintId::of(operators::FLOAT_EQUALITY_WITHOUT_ABS),
- LintId::of(operators::MISREFACTORED_ASSIGN_OP),
- LintId::of(rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT),
- LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
- LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
- LintId::of(swap_ptr_to_ref::SWAP_PTR_TO_REF),
-])
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 1307096b2..7b17d8a15 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -26,14 +26,13 @@
extern crate rustc_arena;
extern crate rustc_ast;
extern crate rustc_ast_pretty;
-extern crate rustc_attr;
extern crate rustc_data_structures;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_hir;
extern crate rustc_hir_analysis;
-extern crate rustc_hir_typeck;
extern crate rustc_hir_pretty;
+extern crate rustc_hir_typeck;
extern crate rustc_index;
extern crate rustc_infer;
extern crate rustc_lexer;
@@ -47,122 +46,23 @@ extern crate rustc_trait_selection;
#[macro_use]
extern crate clippy_utils;
+#[macro_use]
+extern crate declare_clippy_lint;
-use clippy_utils::parse_msrv;
+use std::io;
+use std::path::PathBuf;
+
+use clippy_utils::msrvs::Msrv;
use rustc_data_structures::fx::FxHashSet;
-use rustc_lint::LintId;
-use rustc_semver::RustcVersion;
+use rustc_lint::{Lint, LintId};
use rustc_session::Session;
-/// Macro used to declare a Clippy lint.
-///
-/// Every lint declaration consists of 4 parts:
-///
-/// 1. The documentation, which is used for the website
-/// 2. The `LINT_NAME`. See [lint naming][lint_naming] on lint naming conventions.
-/// 3. The `lint_level`, which is a mapping from *one* of our lint groups to `Allow`, `Warn` or
-/// `Deny`. The lint level here has nothing to do with what lint groups the lint is a part of.
-/// 4. The `description` that contains a short explanation on what's wrong with code where the
-/// lint is triggered.
-///
-/// Currently the categories `style`, `correctness`, `suspicious`, `complexity` and `perf` are
-/// enabled by default. As said in the README.md of this repository, if the lint level mapping
-/// changes, please update README.md.
-///
-/// # Example
-///
-/// ```
-/// #![feature(rustc_private)]
-/// extern crate rustc_session;
-/// use rustc_session::declare_tool_lint;
-/// use clippy_lints::declare_clippy_lint;
-///
-/// declare_clippy_lint! {
-/// /// ### What it does
-/// /// Checks for ... (describe what the lint matches).
-/// ///
-/// /// ### Why is this bad?
-/// /// Supply the reason for linting the code.
-/// ///
-/// /// ### Example
-/// /// ```rust
-/// /// Insert a short example of code that triggers the lint
-/// /// ```
-/// ///
-/// /// Use instead:
-/// /// ```rust
-/// /// Insert a short example of improved code that doesn't trigger the lint
-/// /// ```
-/// pub LINT_NAME,
-/// pedantic,
-/// "description"
-/// }
-/// ```
-/// [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
-#[macro_export]
-macro_rules! declare_clippy_lint {
- { $(#[$attr:meta])* pub $name:tt, style, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
- }
- };
- { $(#[$attr:meta])* pub $name:tt, correctness, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Deny, $description, report_in_external_macro: true
- }
- };
- { $(#[$attr:meta])* pub $name:tt, suspicious, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
- }
- };
- { $(#[$attr:meta])* pub $name:tt, complexity, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
- }
- };
- { $(#[$attr:meta])* pub $name:tt, perf, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
- }
- };
- { $(#[$attr:meta])* pub $name:tt, pedantic, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
- }
- };
- { $(#[$attr:meta])* pub $name:tt, restriction, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
- }
- };
- { $(#[$attr:meta])* pub $name:tt, cargo, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
- }
- };
- { $(#[$attr:meta])* pub $name:tt, nursery, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
- }
- };
- { $(#[$attr:meta])* pub $name:tt, internal, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
- }
- };
- { $(#[$attr:meta])* pub $name:tt, internal_warn, $description:tt } => {
- declare_tool_lint! {
- $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
- }
- };
-}
-
#[cfg(feature = "internal")]
pub mod deprecated_lints;
#[cfg_attr(feature = "internal", allow(clippy::missing_clippy_version_attribute))]
mod utils;
+mod declared_lints;
mod renamed_lints;
// begin lints modules, do not remove this comment, it’s used in `update_lints`
@@ -231,6 +131,7 @@ mod format_impl;
mod format_push_string;
mod formatting;
mod from_over_into;
+mod from_raw_with_void_ptr;
mod from_str_radix_10;
mod functions;
mod future_not_send;
@@ -249,6 +150,7 @@ mod inherent_impl;
mod inherent_to_string;
mod init_numbered_fields;
mod inline_fn_without_body;
+mod instant_subtraction;
mod int_plus_one;
mod invalid_upcast_comparisons;
mod invalid_utf8_in_unchecked;
@@ -270,7 +172,8 @@ mod manual_assert;
mod manual_async_fn;
mod manual_bits;
mod manual_clamp;
-mod manual_instant_elapsed;
+mod manual_is_ascii_check;
+mod manual_let_else;
mod manual_non_exhaustive;
mod manual_rem_euclid;
mod manual_retain;
@@ -365,6 +268,7 @@ mod strings;
mod strlen_on_c_strings;
mod suspicious_operation_groupings;
mod suspicious_trait_impl;
+mod suspicious_xor_used_as_pow;
mod swap;
mod swap_ptr_to_ref;
mod tabs_in_doc_comments;
@@ -404,8 +308,8 @@ mod zero_div_zero;
mod zero_sized_map_values;
// end lints modules, do not remove this comment, it’s used in `update_lints`
-pub use crate::utils::conf::Conf;
use crate::utils::conf::{format_error, TryConf};
+pub use crate::utils::conf::{lookup_conf_file, Conf};
/// Register all pre expansion lints
///
@@ -417,53 +321,15 @@ use crate::utils::conf::{format_error, TryConf};
/// Used in `./src/driver.rs`.
pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore, sess: &Session, conf: &Conf) {
// NOTE: Do not add any more pre-expansion passes. These should be removed eventually.
+ let msrv = Msrv::read(&conf.msrv, sess);
+ let msrv = move || msrv.clone();
- let msrv = conf.msrv.as_ref().and_then(|s| {
- parse_msrv(s, None, None).or_else(|| {
- sess.err(format!(
- "error reading Clippy's configuration file. `{s}` is not a valid Rust version"
- ));
- None
- })
- });
-
- store.register_pre_expansion_pass(move || Box::new(attrs::EarlyAttributes { msrv }));
-}
-
-fn read_msrv(conf: &Conf, sess: &Session) -> Option<RustcVersion> {
- let cargo_msrv = std::env::var("CARGO_PKG_RUST_VERSION")
- .ok()
- .and_then(|v| parse_msrv(&v, None, None));
- let clippy_msrv = conf.msrv.as_ref().and_then(|s| {
- parse_msrv(s, None, None).or_else(|| {
- sess.err(format!(
- "error reading Clippy's configuration file. `{s}` is not a valid Rust version"
- ));
- None
- })
- });
-
- if let Some(cargo_msrv) = cargo_msrv {
- if let Some(clippy_msrv) = clippy_msrv {
- // if both files have an msrv, let's compare them and emit a warning if they differ
- if clippy_msrv != cargo_msrv {
- sess.warn(format!(
- "the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`"
- ));
- }
-
- Some(clippy_msrv)
- } else {
- Some(cargo_msrv)
- }
- } else {
- clippy_msrv
- }
+ store.register_pre_expansion_pass(move || Box::new(attrs::EarlyAttributes { msrv: msrv() }));
}
#[doc(hidden)]
-pub fn read_conf(sess: &Session) -> Conf {
- let file_name = match utils::conf::lookup_conf_file() {
+pub fn read_conf(sess: &Session, path: &io::Result<Option<PathBuf>>) -> Conf {
+ let file_name = match path {
Ok(Some(path)) => path,
Ok(None) => return Conf::default(),
Err(error) => {
@@ -473,7 +339,7 @@ pub fn read_conf(sess: &Session) -> Conf {
},
};
- let TryConf { conf, errors, warnings } = utils::conf::read(&file_name);
+ let TryConf { conf, errors, warnings } = utils::conf::read(file_name);
// all conf errors are non-fatal, we just use the default conf in case of error
for error in errors {
sess.err(format!(
@@ -495,31 +361,121 @@ pub fn read_conf(sess: &Session) -> Conf {
conf
}
+#[derive(Default)]
+struct RegistrationGroups {
+ all: Vec<LintId>,
+ cargo: Vec<LintId>,
+ complexity: Vec<LintId>,
+ correctness: Vec<LintId>,
+ nursery: Vec<LintId>,
+ pedantic: Vec<LintId>,
+ perf: Vec<LintId>,
+ restriction: Vec<LintId>,
+ style: Vec<LintId>,
+ suspicious: Vec<LintId>,
+ #[cfg(feature = "internal")]
+ internal: Vec<LintId>,
+}
+
+impl RegistrationGroups {
+ #[rustfmt::skip]
+ fn register(self, store: &mut rustc_lint::LintStore) {
+ store.register_group(true, "clippy::all", Some("clippy_all"), self.all);
+ store.register_group(true, "clippy::cargo", Some("clippy_cargo"), self.cargo);
+ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), self.complexity);
+ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), self.correctness);
+ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), self.nursery);
+ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), self.pedantic);
+ store.register_group(true, "clippy::perf", Some("clippy_perf"), self.perf);
+ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), self.restriction);
+ store.register_group(true, "clippy::style", Some("clippy_style"), self.style);
+ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), self.suspicious);
+ #[cfg(feature = "internal")]
+ store.register_group(true, "clippy::internal", Some("clippy_internal"), self.internal);
+ }
+}
+
+#[derive(Copy, Clone)]
+pub(crate) enum LintCategory {
+ Cargo,
+ Complexity,
+ Correctness,
+ Nursery,
+ Pedantic,
+ Perf,
+ Restriction,
+ Style,
+ Suspicious,
+ #[cfg(feature = "internal")]
+ Internal,
+}
+#[allow(clippy::enum_glob_use)]
+use LintCategory::*;
+
+impl LintCategory {
+ fn is_all(self) -> bool {
+ matches!(self, Correctness | Suspicious | Style | Complexity | Perf)
+ }
+
+ fn group(self, groups: &mut RegistrationGroups) -> &mut Vec<LintId> {
+ match self {
+ Cargo => &mut groups.cargo,
+ Complexity => &mut groups.complexity,
+ Correctness => &mut groups.correctness,
+ Nursery => &mut groups.nursery,
+ Pedantic => &mut groups.pedantic,
+ Perf => &mut groups.perf,
+ Restriction => &mut groups.restriction,
+ Style => &mut groups.style,
+ Suspicious => &mut groups.suspicious,
+ #[cfg(feature = "internal")]
+ Internal => &mut groups.internal,
+ }
+ }
+}
+
+pub(crate) struct LintInfo {
+ /// Double reference to maintain pointer equality
+ lint: &'static &'static Lint,
+ category: LintCategory,
+ explanation: &'static str,
+}
+
+pub fn explain(name: &str) {
+ let target = format!("clippy::{}", name.to_ascii_uppercase());
+ match declared_lints::LINTS.iter().find(|info| info.lint.name == target) {
+ Some(info) => print!("{}", info.explanation),
+ None => println!("unknown lint: {name}"),
+ }
+}
+
+fn register_categories(store: &mut rustc_lint::LintStore) {
+ let mut groups = RegistrationGroups::default();
+
+ for LintInfo { lint, category, .. } in declared_lints::LINTS {
+ if category.is_all() {
+ groups.all.push(LintId::of(lint));
+ }
+
+ category.group(&mut groups).push(LintId::of(lint));
+ }
+
+ let lints: Vec<&'static Lint> = declared_lints::LINTS.iter().map(|info| *info.lint).collect();
+
+ store.register_lints(&lints);
+ groups.register(store);
+}
+
/// Register all lints and lint groups with the rustc plugin registry
///
/// Used in `./src/driver.rs`.
#[expect(clippy::too_many_lines)]
pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &Conf) {
register_removed_non_tool_lints(store);
+ register_categories(store);
include!("lib.deprecated.rs");
- include!("lib.register_lints.rs");
- include!("lib.register_restriction.rs");
- include!("lib.register_pedantic.rs");
-
- #[cfg(feature = "internal")]
- include!("lib.register_internal.rs");
-
- include!("lib.register_all.rs");
- include!("lib.register_style.rs");
- include!("lib.register_complexity.rs");
- include!("lib.register_correctness.rs");
- include!("lib.register_suspicious.rs");
- include!("lib.register_perf.rs");
- include!("lib.register_cargo.rs");
- include!("lib.register_nursery.rs");
-
#[cfg(feature = "internal")]
{
if std::env::var("ENABLE_METADATA_COLLECTION").eq(&Ok("1".to_string())) {
@@ -600,41 +556,44 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions));
store.register_early_pass(|| Box::new(unnecessary_self_imports::UnnecessarySelfImports));
- let msrv = read_msrv(conf, sess);
+ let msrv = Msrv::read(&conf.msrv, sess);
+ let msrv = move || msrv.clone();
let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
let allow_expect_in_tests = conf.allow_expect_in_tests;
let allow_unwrap_in_tests = conf.allow_unwrap_in_tests;
- store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv)));
+ store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv())));
store.register_late_pass(move |_| {
Box::new(methods::Methods::new(
avoid_breaking_exported_api,
- msrv,
+ msrv(),
allow_expect_in_tests,
allow_unwrap_in_tests,
))
});
- store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv)));
- store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv)));
- store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv)));
- store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv)));
- store.register_early_pass(move || Box::new(redundant_static_lifetimes::RedundantStaticLifetimes::new(msrv)));
- store.register_early_pass(move || Box::new(redundant_field_names::RedundantFieldNames::new(msrv)));
- store.register_late_pass(move |_| Box::new(checked_conversions::CheckedConversions::new(msrv)));
- store.register_late_pass(move |_| Box::new(mem_replace::MemReplace::new(msrv)));
- store.register_late_pass(move |_| Box::new(ranges::Ranges::new(msrv)));
- store.register_late_pass(move |_| Box::new(from_over_into::FromOverInto::new(msrv)));
- store.register_late_pass(move |_| Box::new(use_self::UseSelf::new(msrv)));
- store.register_late_pass(move |_| Box::new(missing_const_for_fn::MissingConstForFn::new(msrv)));
+ store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv())));
+ let matches_for_let_else = conf.matches_for_let_else;
+ store.register_late_pass(move |_| Box::new(manual_let_else::ManualLetElse::new(msrv(), matches_for_let_else)));
+ store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv())));
+ store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv())));
+ store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv())));
+ store.register_early_pass(move || Box::new(redundant_static_lifetimes::RedundantStaticLifetimes::new(msrv())));
+ store.register_early_pass(move || Box::new(redundant_field_names::RedundantFieldNames::new(msrv())));
+ store.register_late_pass(move |_| Box::new(checked_conversions::CheckedConversions::new(msrv())));
+ store.register_late_pass(move |_| Box::new(mem_replace::MemReplace::new(msrv())));
+ store.register_late_pass(move |_| Box::new(ranges::Ranges::new(msrv())));
+ store.register_late_pass(move |_| Box::new(from_over_into::FromOverInto::new(msrv())));
+ store.register_late_pass(move |_| Box::new(use_self::UseSelf::new(msrv())));
+ store.register_late_pass(move |_| Box::new(missing_const_for_fn::MissingConstForFn::new(msrv())));
store.register_late_pass(move |_| Box::new(needless_question_mark::NeedlessQuestionMark));
- store.register_late_pass(move |_| Box::new(casts::Casts::new(msrv)));
- store.register_early_pass(move || Box::new(unnested_or_patterns::UnnestedOrPatterns::new(msrv)));
+ store.register_late_pass(move |_| Box::new(casts::Casts::new(msrv())));
+ store.register_early_pass(move || Box::new(unnested_or_patterns::UnnestedOrPatterns::new(msrv())));
store.register_late_pass(|_| Box::new(size_of_in_element_count::SizeOfInElementCount));
store.register_late_pass(|_| Box::new(same_name_method::SameNameMethod));
let max_suggested_slice_pattern_length = conf.max_suggested_slice_pattern_length;
store.register_late_pass(move |_| {
Box::new(index_refutable_slice::IndexRefutableSlice::new(
max_suggested_slice_pattern_length,
- msrv,
+ msrv(),
))
});
store.register_late_pass(|_| Box::<shadow::Shadow>::default());
@@ -651,7 +610,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::new(borrow_deref_ref::BorrowDerefRef));
store.register_late_pass(|_| Box::new(no_effect::NoEffect));
store.register_late_pass(|_| Box::new(temporary_assignment::TemporaryAssignment));
- store.register_late_pass(move |_| Box::new(transmute::Transmute::new(msrv)));
+ store.register_late_pass(move |_| Box::new(transmute::Transmute::new(msrv())));
let cognitive_complexity_threshold = conf.cognitive_complexity_threshold;
store.register_late_pass(move |_| {
Box::new(cognitive_complexity::CognitiveComplexity::new(
@@ -735,7 +694,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
let max_trait_bounds = conf.max_trait_bounds;
store.register_late_pass(move |_| Box::new(trait_bounds::TraitBounds::new(max_trait_bounds)));
store.register_late_pass(|_| Box::new(comparison_chain::ComparisonChain));
- store.register_late_pass(|_| Box::new(mut_key::MutableKeyType));
+ let ignore_interior_mutability = conf.ignore_interior_mutability.clone();
+ store.register_late_pass(move |_| Box::new(mut_key::MutableKeyType::new(ignore_interior_mutability.clone())));
store.register_early_pass(|| Box::new(reference::DerefAddrOf));
store.register_early_pass(|| Box::new(double_parens::DoubleParens));
store.register_late_pass(|_| Box::new(format_impl::FormatImpl::new()));
@@ -794,10 +754,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::new(floating_point_arithmetic::FloatingPointArithmetic));
store.register_early_pass(|| Box::new(as_conversions::AsConversions));
store.register_late_pass(|_| Box::new(let_underscore::LetUnderscore));
- store.register_early_pass(|| Box::new(single_component_path_imports::SingleComponentPathImports));
+ store.register_early_pass(|| Box::<single_component_path_imports::SingleComponentPathImports>::default());
let max_fn_params_bools = conf.max_fn_params_bools;
let max_struct_bools = conf.max_struct_bools;
- store.register_early_pass(move || {
+ store.register_late_pass(move |_| {
Box::new(excessive_bools::ExcessiveBools::new(
max_struct_bools,
max_fn_params_bools,
@@ -808,7 +768,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(move |_| Box::new(dereference::Dereferencing::new(msrv())));
store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse));
store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend));
store.register_late_pass(|_| Box::new(if_let_mutex::IfLetMutex));
@@ -842,7 +802,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::<vec_init_then_push::VecInitThenPush>::default());
store.register_late_pass(|_| Box::new(redundant_slicing::RedundantSlicing));
store.register_late_pass(|_| Box::new(from_str_radix_10::FromStrRadix10));
- store.register_late_pass(move |_| Box::new(if_then_some_else_none::IfThenSomeElseNone::new(msrv)));
+ store.register_late_pass(move |_| Box::new(if_then_some_else_none::IfThenSomeElseNone::new(msrv())));
store.register_late_pass(|_| Box::new(bool_assert_comparison::BoolAssertComparison));
store.register_early_pass(move || Box::new(module_style::ModStyle));
store.register_late_pass(|_| Box::new(unused_async::UnusedAsync));
@@ -867,25 +827,27 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
))
});
store.register_late_pass(move |_| Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks));
- store.register_late_pass(move |_| Box::new(format_args::FormatArgs::new(msrv)));
+ let allow_mixed_uninlined = conf.allow_mixed_uninlined_format_args;
+ store.register_late_pass(move |_| Box::new(format_args::FormatArgs::new(msrv(), allow_mixed_uninlined)));
store.register_late_pass(|_| Box::new(trailing_empty_array::TrailingEmptyArray));
store.register_early_pass(|| Box::new(octal_escapes::OctalEscapes));
store.register_late_pass(|_| Box::new(needless_late_init::NeedlessLateInit));
store.register_late_pass(|_| Box::new(return_self_not_must_use::ReturnSelfNotMustUse));
store.register_late_pass(|_| Box::new(init_numbered_fields::NumberedFields));
store.register_early_pass(|| Box::new(single_char_lifetime_names::SingleCharLifetimeNames));
- store.register_late_pass(move |_| Box::new(manual_bits::ManualBits::new(msrv)));
+ store.register_late_pass(move |_| Box::new(manual_bits::ManualBits::new(msrv())));
store.register_late_pass(|_| Box::new(default_union_representation::DefaultUnionRepresentation));
store.register_late_pass(|_| Box::<only_used_in_recursion::OnlyUsedInRecursion>::default());
let allow_dbg_in_tests = conf.allow_dbg_in_tests;
store.register_late_pass(move |_| Box::new(dbg_macro::DbgMacro::new(allow_dbg_in_tests)));
+ let allow_print_in_tests = conf.allow_print_in_tests;
+ store.register_late_pass(move |_| Box::new(write::Write::new(allow_print_in_tests)));
let cargo_ignore_publish = conf.cargo_ignore_publish;
store.register_late_pass(move |_| {
Box::new(cargo::Cargo {
ignore_publish: cargo_ignore_publish,
})
});
- store.register_late_pass(|_| Box::<write::Write>::default());
store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef));
store.register_early_pass(|| Box::new(empty_structs_with_brackets::EmptyStructsWithBrackets));
store.register_late_pass(|_| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings));
@@ -897,20 +859,20 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::new(rc_clone_in_vec_init::RcCloneInVecInit));
store.register_early_pass(|| Box::<duplicate_mod::DuplicateMod>::default());
store.register_early_pass(|| Box::new(unused_rounding::UnusedRounding));
- store.register_early_pass(move || Box::new(almost_complete_letter_range::AlmostCompleteLetterRange::new(msrv)));
+ store.register_early_pass(move || Box::new(almost_complete_letter_range::AlmostCompleteLetterRange::new(msrv())));
store.register_late_pass(|_| Box::new(swap_ptr_to_ref::SwapPtrToRef));
store.register_late_pass(|_| Box::new(mismatching_type_param_order::TypeParamMismatch));
store.register_late_pass(|_| Box::new(read_zero_byte_vec::ReadZeroByteVec));
store.register_late_pass(|_| Box::new(default_instead_of_iter_empty::DefaultIterEmpty));
- store.register_late_pass(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv)));
- store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(msrv)));
+ store.register_late_pass(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv())));
+ store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(msrv())));
let verbose_bit_mask_threshold = conf.verbose_bit_mask_threshold;
store.register_late_pass(move |_| Box::new(operators::Operators::new(verbose_bit_mask_threshold)));
store.register_late_pass(|_| Box::new(invalid_utf8_in_unchecked::InvalidUtf8InUnchecked));
store.register_late_pass(|_| Box::<std_instead_of_core::StdReexports>::default());
- store.register_late_pass(|_| Box::new(manual_instant_elapsed::ManualInstantElapsed));
+ store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(msrv())));
store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));
- store.register_late_pass(move |_| Box::new(manual_clamp::ManualClamp::new(msrv)));
+ store.register_late_pass(move |_| Box::new(manual_clamp::ManualClamp::new(msrv())));
store.register_late_pass(|_| Box::new(manual_string_new::ManualStringNew));
store.register_late_pass(|_| Box::new(unused_peekable::UnusedPeekable));
store.register_early_pass(|| Box::new(multi_assignments::MultiAssignments));
@@ -919,6 +881,9 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::new(implicit_saturating_add::ImplicitSaturatingAdd));
store.register_early_pass(|| Box::new(partial_pub_fields::PartialPubFields));
store.register_late_pass(|_| Box::new(missing_trait_methods::MissingTraitMethods));
+ store.register_late_pass(|_| Box::new(from_raw_with_void_ptr::FromRawWithVoidPtr));
+ store.register_late_pass(|_| Box::new(suspicious_xor_used_as_pow::ConfusingXorAndPow));
+ store.register_late_pass(move |_| Box::new(manual_is_ascii_check::ManualIsAsciiCheck::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/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 3bf2d7e4e..7cf1a6b80 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -1,15 +1,16 @@
-use clippy_utils::diagnostics::span_lint;
+use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
use clippy_utils::trait_ref_of_method;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter};
use rustc_hir::intravisit::{
- walk_fn_decl, walk_generic_param, walk_generics, walk_impl_item_ref, walk_item, walk_param_bound,
+ walk_fn_decl, walk_generic_arg, walk_generic_param, walk_generics, walk_impl_item_ref, walk_item, walk_param_bound,
walk_poly_trait_ref, walk_trait_ref, walk_ty, Visitor,
};
+use rustc_hir::lang_items;
use rustc_hir::FnRetTy::Return;
use rustc_hir::{
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
- ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin, TraitFn,
+ ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, PolyTraitRef, PredicateOrigin, TraitFn,
TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
};
use rustc_lint::{LateContext, LateLintPass};
@@ -151,6 +152,7 @@ fn check_fn_inner<'tcx>(
.params
.iter()
.filter(|param| matches!(param.kind, GenericParamKind::Type { .. }));
+
for typ in types {
for pred in generics.bounds_for_param(cx.tcx.hir().local_def_id(typ.hir_id)) {
if pred.origin == PredicateOrigin::WhereClause {
@@ -178,7 +180,7 @@ fn check_fn_inner<'tcx>(
_ => None,
});
for bound in lifetimes {
- if bound.name != LifetimeName::Static && !bound.is_elided() {
+ if !bound.is_static() && !bound.is_elided() {
return;
}
}
@@ -187,15 +189,30 @@ fn check_fn_inner<'tcx>(
}
}
}
- if could_use_elision(cx, decl, body, trait_sig, generics.params) {
- span_lint(
+
+ if let Some(elidable_lts) = could_use_elision(cx, decl, body, trait_sig, generics.params) {
+ let lts = elidable_lts
+ .iter()
+ // In principle, the result of the call to `Node::ident` could be `unwrap`ped, as `DefId` should refer to a
+ // `Node::GenericParam`.
+ .filter_map(|&(def_id, _)| cx.tcx.hir().get_by_def_id(def_id).ident())
+ .map(|ident| ident.to_string())
+ .collect::<Vec<_>>()
+ .join(", ");
+
+ span_lint_and_then(
cx,
NEEDLESS_LIFETIMES,
span.with_hi(decl.output.span().hi()),
- "explicit lifetimes given in parameter types where they could be elided \
- (or replaced with `'_` if needed by type declaration)",
+ &format!("the following explicit lifetimes could be elided: {lts}"),
+ |diag| {
+ if let Some(span) = elidable_lts.iter().find_map(|&(_, span)| span) {
+ diag.span_help(span, "replace with `'_` in generic arguments such as here");
+ }
+ },
);
}
+
if report_extra_lifetimes {
self::report_extra_lifetimes(cx, decl, generics);
}
@@ -226,7 +243,7 @@ fn could_use_elision<'tcx>(
body: Option<BodyId>,
trait_sig: Option<&[Ident]>,
named_generics: &'tcx [GenericParam<'_>],
-) -> bool {
+) -> Option<Vec<(LocalDefId, Option<Span>)>> {
// There are two scenarios where elision works:
// * no output references, all input references have different LT
// * output references, exactly one input reference with same LT
@@ -253,7 +270,7 @@ fn could_use_elision<'tcx>(
}
if input_visitor.abort() || output_visitor.abort() {
- return false;
+ return None;
}
let input_lts = input_visitor.lts;
@@ -261,7 +278,7 @@ fn could_use_elision<'tcx>(
if let Some(trait_sig) = trait_sig {
if explicit_self_type(cx, func, trait_sig.first().copied()) {
- return false;
+ return None;
}
}
@@ -270,7 +287,7 @@ fn could_use_elision<'tcx>(
let first_ident = body.params.first().and_then(|param| param.pat.simple_ident());
if explicit_self_type(cx, func, first_ident) {
- return false;
+ return None;
}
let mut checker = BodyLifetimeChecker {
@@ -278,14 +295,14 @@ fn could_use_elision<'tcx>(
};
checker.visit_expr(body.value);
if checker.lifetimes_used_in_body {
- return false;
+ return None;
}
}
// check for lifetimes from higher scopes
for lt in input_lts.iter().chain(output_lts.iter()) {
if !allowed_lts.contains(lt) {
- return false;
+ return None;
}
}
@@ -301,48 +318,45 @@ fn could_use_elision<'tcx>(
for lt in input_visitor.nested_elision_site_lts {
if let RefLt::Named(def_id) = lt {
if allowed_lts.contains(&cx.tcx.item_name(def_id.to_def_id())) {
- return false;
+ return None;
}
}
}
for lt in output_visitor.nested_elision_site_lts {
if let RefLt::Named(def_id) = lt {
if allowed_lts.contains(&cx.tcx.item_name(def_id.to_def_id())) {
- return false;
+ return None;
}
}
}
}
- // no input lifetimes? easy case!
- if input_lts.is_empty() {
- false
- } else if output_lts.is_empty() {
- // no output lifetimes, check distinctness of input lifetimes
+ // A lifetime can be newly elided if:
+ // - It occurs only once among the inputs.
+ // - If there are multiple input lifetimes, then the newly elided lifetime does not occur among the
+ // outputs (because eliding such an lifetime would create an ambiguity).
+ let elidable_lts = named_lifetime_occurrences(&input_lts)
+ .into_iter()
+ .filter_map(|(def_id, occurrences)| {
+ if occurrences == 1 && (input_lts.len() == 1 || !output_lts.contains(&RefLt::Named(def_id))) {
+ Some((
+ def_id,
+ input_visitor
+ .lifetime_generic_arg_spans
+ .get(&def_id)
+ .or_else(|| output_visitor.lifetime_generic_arg_spans.get(&def_id))
+ .copied(),
+ ))
+ } else {
+ None
+ }
+ })
+ .collect::<Vec<_>>();
- // only unnamed and static, ok
- let unnamed_and_static = input_lts.iter().all(|lt| *lt == RefLt::Unnamed || *lt == RefLt::Static);
- if unnamed_and_static {
- return false;
- }
- // we have no output reference, so we only need all distinct lifetimes
- input_lts.len() == unique_lifetimes(&input_lts)
+ if elidable_lts.is_empty() {
+ None
} else {
- // we have output references, so we need one input reference,
- // and all output lifetimes must be the same
- if unique_lifetimes(&output_lts) > 1 {
- return false;
- }
- if input_lts.len() == 1 {
- match (&input_lts[0], &output_lts[0]) {
- (&RefLt::Named(n1), &RefLt::Named(n2)) if n1 == n2 => true,
- (&RefLt::Named(_), &RefLt::Unnamed) => true,
- _ => false, /* already elided, different named lifetimes
- * or something static going on */
- }
- } else {
- false
- }
+ Some(elidable_lts)
}
}
@@ -358,18 +372,31 @@ fn allowed_lts_from(tcx: TyCtxt<'_>, named_generics: &[GenericParam<'_>]) -> FxH
allowed_lts
}
-/// Number of unique lifetimes in the given vector.
+/// Number of times each named lifetime occurs in the given slice. Returns a vector to preserve
+/// relative order.
#[must_use]
-fn unique_lifetimes(lts: &[RefLt]) -> usize {
- lts.iter().collect::<FxHashSet<_>>().len()
+fn named_lifetime_occurrences(lts: &[RefLt]) -> Vec<(LocalDefId, usize)> {
+ let mut occurrences = Vec::new();
+ for lt in lts {
+ if let &RefLt::Named(curr_def_id) = lt {
+ if let Some(pair) = occurrences
+ .iter_mut()
+ .find(|(prev_def_id, _)| *prev_def_id == curr_def_id)
+ {
+ pair.1 += 1;
+ } else {
+ occurrences.push((curr_def_id, 1));
+ }
+ }
+ }
+ occurrences
}
-const CLOSURE_TRAIT_BOUNDS: [LangItem; 3] = [LangItem::Fn, LangItem::FnMut, LangItem::FnOnce];
-
/// A visitor usable for `rustc_front::visit::walk_ty()`.
struct RefVisitor<'a, 'tcx> {
cx: &'a LateContext<'tcx>,
lts: Vec<RefLt>,
+ lifetime_generic_arg_spans: FxHashMap<LocalDefId, Span>,
nested_elision_site_lts: Vec<RefLt>,
unelided_trait_object_lifetime: bool,
}
@@ -379,6 +406,7 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
Self {
cx,
lts: Vec::new(),
+ lifetime_generic_arg_spans: FxHashMap::default(),
nested_elision_site_lts: Vec::new(),
unelided_trait_object_lifetime: false,
}
@@ -386,17 +414,13 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
fn record(&mut self, lifetime: &Option<Lifetime>) {
if let Some(ref lt) = *lifetime {
- if lt.name == LifetimeName::Static {
+ if lt.is_static() {
self.lts.push(RefLt::Static);
- } else if let LifetimeName::Param(_, ParamName::Fresh) = lt.name {
+ } else if lt.is_anonymous() {
// Fresh lifetimes generated should be ignored.
self.lts.push(RefLt::Unnamed);
- } else if lt.is_elided() {
- self.lts.push(RefLt::Unnamed);
- } else if let LifetimeName::Param(def_id, _) = lt.name {
+ } else if let LifetimeName::Param(def_id) = lt.res {
self.lts.push(RefLt::Named(def_id));
- } else {
- self.lts.push(RefLt::Unnamed);
}
} else {
self.lts.push(RefLt::Unnamed);
@@ -424,12 +448,8 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>) {
let trait_ref = &poly_tref.trait_ref;
- if CLOSURE_TRAIT_BOUNDS.iter().any(|&item| {
- self.cx
- .tcx
- .lang_items()
- .require(item)
- .map_or(false, |id| Some(id) == trait_ref.trait_def_id())
+ if let Some(id) = trait_ref.trait_def_id() && lang_items::FN_TRAITS.iter().any(|&item| {
+ self.cx.tcx.lang_items().get(item) == Some(id)
}) {
let mut sub_visitor = RefVisitor::new(self.cx);
sub_visitor.visit_trait_ref(trait_ref);
@@ -448,7 +468,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
walk_item(self, item);
self.lts.truncate(len);
self.lts.extend(bounds.iter().filter_map(|bound| match bound {
- GenericArg::Lifetime(l) => Some(if let LifetimeName::Param(def_id, _) = l.name {
+ GenericArg::Lifetime(l) => Some(if let LifetimeName::Param(def_id) = l.res {
RefLt::Named(def_id)
} else {
RefLt::Unnamed
@@ -461,7 +481,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
sub_visitor.visit_fn_decl(decl);
self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
},
- TyKind::TraitObject(bounds, ref lt, _) => {
+ TyKind::TraitObject(bounds, lt, _) => {
if !lt.is_elided() {
self.unelided_trait_object_lifetime = true;
}
@@ -472,6 +492,13 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
_ => walk_ty(self, ty),
}
}
+
+ fn visit_generic_arg(&mut self, generic_arg: &'tcx GenericArg<'tcx>) {
+ if let GenericArg::Lifetime(l) = generic_arg && let LifetimeName::Param(def_id) = l.res {
+ self.lifetime_generic_arg_spans.entry(def_id).or_insert(l.ident.span);
+ }
+ walk_generic_arg(self, generic_arg);
+ }
}
/// Are any lifetimes mentioned in the `where` clause? If so, we don't try to
@@ -537,7 +564,7 @@ where
// for lifetimes as parameters of generics
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
- self.map.remove(&lifetime.name.ident().name);
+ self.map.remove(&lifetime.ident.name);
}
fn visit_generic_param(&mut self, param: &'tcx GenericParam<'_>) {
@@ -561,7 +588,9 @@ fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>,
.params
.iter()
.filter_map(|par| match par.kind {
- GenericParamKind::Lifetime { .. } => Some((par.name.ident().name, par.span)),
+ GenericParamKind::Lifetime {
+ kind: LifetimeParamKind::Explicit,
+ } => Some((par.name.ident().name, par.span)),
_ => None,
})
.collect();
@@ -586,7 +615,9 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
.params
.iter()
.filter_map(|par| match par.kind {
- GenericParamKind::Lifetime { .. } => Some((par.name.ident().name, par.span)),
+ GenericParamKind::Lifetime {
+ kind: LifetimeParamKind::Explicit,
+ } => Some((par.name.ident().name, par.span)),
_ => None,
})
.collect();
@@ -613,7 +644,7 @@ struct BodyLifetimeChecker {
impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker {
// for lifetimes as parameters of generics
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
- if lifetime.name.ident().name != kw::UnderscoreLifetime && lifetime.name.ident().name != kw::StaticLifetime {
+ if !lifetime.is_anonymous() && lifetime.ident.name != kw::StaticLifetime {
self.lifetimes_used_in_body = true;
}
}
diff --git a/src/tools/clippy/clippy_lints/src/literal_representation.rs b/src/tools/clippy/clippy_lints/src/literal_representation.rs
index 25f19b9c6..3a7b7835c 100644
--- a/src/tools/clippy/clippy_lints/src/literal_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/literal_representation.rs
@@ -5,11 +5,13 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::numeric_literal::{NumericLiteral, Radix};
use clippy_utils::source::snippet_opt;
use if_chain::if_chain;
-use rustc_ast::ast::{Expr, ExprKind, Lit, LitKind};
+use rustc_ast::ast::{Expr, ExprKind, LitKind};
+use rustc_ast::token;
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::Span;
use std::iter;
declare_clippy_lint! {
@@ -236,8 +238,8 @@ impl EarlyLintPass for LiteralDigitGrouping {
return;
}
- if let ExprKind::Lit(ref lit) = expr.kind {
- self.check_lit(cx, lit);
+ if let ExprKind::Lit(lit) = expr.kind {
+ self.check_lit(cx, lit, expr.span);
}
}
}
@@ -252,12 +254,13 @@ impl LiteralDigitGrouping {
}
}
- fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) {
+ fn check_lit(self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
if_chain! {
- if let Some(src) = snippet_opt(cx, lit.span);
- if let Some(mut num_lit) = NumericLiteral::from_lit(&src, lit);
+ if let Some(src) = snippet_opt(cx, span);
+ if let Ok(lit_kind) = LitKind::from_token_lit(lit);
+ if let Some(mut num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind);
then {
- if !Self::check_for_mistyped_suffix(cx, lit.span, &mut num_lit) {
+ if !Self::check_for_mistyped_suffix(cx, span, &mut num_lit) {
return;
}
@@ -293,14 +296,14 @@ impl LiteralDigitGrouping {
| WarningType::InconsistentDigitGrouping
| WarningType::UnusualByteGroupings
| WarningType::LargeDigitGroups => {
- !lit.span.from_expansion()
+ !span.from_expansion()
}
WarningType::DecimalRepresentation | WarningType::MistypedLiteralSuffix => {
true
}
};
if should_warn {
- warning_type.display(num_lit.format(), cx, lit.span);
+ warning_type.display(num_lit.format(), cx, span);
}
}
}
@@ -458,8 +461,8 @@ impl EarlyLintPass for DecimalLiteralRepresentation {
return;
}
- if let ExprKind::Lit(ref lit) = expr.kind {
- self.check_lit(cx, lit);
+ if let ExprKind::Lit(lit) = expr.kind {
+ self.check_lit(cx, lit, expr.span);
}
}
}
@@ -469,19 +472,20 @@ impl DecimalLiteralRepresentation {
pub fn new(threshold: u64) -> Self {
Self { threshold }
}
- fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) {
+ fn check_lit(self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
// Lint integral literals.
if_chain! {
- if let LitKind::Int(val, _) = lit.kind;
- if let Some(src) = snippet_opt(cx, lit.span);
- if let Some(num_lit) = NumericLiteral::from_lit(&src, lit);
+ if let Ok(lit_kind) = LitKind::from_token_lit(lit);
+ if let LitKind::Int(val, _) = lit_kind;
+ if let Some(src) = snippet_opt(cx, span);
+ if let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind);
if num_lit.radix == Radix::Decimal;
if val >= u128::from(self.threshold);
then {
let hex = format!("{val:#X}");
let num_lit = NumericLiteral::new(&hex, num_lit.suffix, false);
let _ = Self::do_lint(num_lit.integer).map_err(|warning_type| {
- warning_type.display(num_lit.format(), cx, lit.span);
+ warning_type.display(num_lit.format(), cx, span);
});
}
}
diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs
index bcf278d9c..8e52cac43 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs
@@ -9,7 +9,6 @@ mod manual_flatten;
mod manual_memcpy;
mod missing_spin_loop;
mod mut_range_bound;
-mod needless_collect;
mod needless_range_loop;
mod never_loop;
mod same_item_push;
@@ -207,28 +206,6 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
- /// Checks for functions collecting an iterator when collect
- /// is not needed.
- ///
- /// ### Why is this bad?
- /// `collect` causes the allocation of a new data structure,
- /// when this allocation may not be needed.
- ///
- /// ### Example
- /// ```rust
- /// # let iterator = vec![1].into_iter();
- /// let len = iterator.clone().collect::<Vec<_>>().len();
- /// // should be
- /// let len = iterator.count();
- /// ```
- #[clippy::version = "1.30.0"]
- pub NEEDLESS_COLLECT,
- perf,
- "collecting an iterator when collect is not needed"
-}
-
-declare_clippy_lint! {
- /// ### What it does
/// Checks `for` loops over slices with an explicit counter
/// and suggests the use of `.enumerate()`.
///
@@ -605,7 +582,6 @@ declare_lint_pass!(Loops => [
EXPLICIT_INTO_ITER_LOOP,
ITER_NEXT_LOOP,
WHILE_LET_LOOP,
- NEEDLESS_COLLECT,
EXPLICIT_COUNTER_LOOP,
EMPTY_LOOP,
WHILE_LET_ON_ITERATOR,
@@ -667,8 +643,6 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
while_immutable_condition::check(cx, condition, body);
missing_spin_loop::check(cx, condition, body);
}
-
- needless_collect::check(expr, cx);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
index 91b321c44..4dae93f60 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
@@ -52,8 +52,8 @@ fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId>
None
}
-fn check_for_mutation<'tcx>(
- cx: &LateContext<'tcx>,
+fn check_for_mutation(
+ cx: &LateContext<'_>,
body: &Expr<'_>,
bound_id_start: Option<HirId>,
bound_id_end: Option<HirId>,
@@ -113,13 +113,7 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
}
}
- fn fake_read(
- &mut self,
- _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>,
- _: FakeReadCause,
- _: HirId,
- ) {
- }
+ fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
}
impl MutatePairDelegate<'_, '_> {
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 16b00ad66..14f161f51 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -4,7 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::ForLoop;
use clippy_utils::source::snippet;
use rustc_errors::Applicability;
-use rustc_hir::{Block, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind};
+use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind};
use rustc_lint::LateContext;
use rustc_span::Span;
use std::iter::{once, Iterator};
@@ -16,7 +16,7 @@ pub(super) fn check(
span: Span,
for_loop: Option<&ForLoop<'_>>,
) {
- match never_loop_block(block, loop_id) {
+ match never_loop_block(block, &mut Vec::new(), loop_id) {
NeverLoopResult::AlwaysBreak => {
span_lint_and_then(cx, NEVER_LOOP, span, "this loop never actually loops", |diag| {
if let Some(ForLoop {
@@ -92,35 +92,34 @@ fn combine_branches(b1: NeverLoopResult, b2: NeverLoopResult) -> NeverLoopResult
}
}
-fn never_loop_block(block: &Block<'_>, main_loop_id: HirId) -> NeverLoopResult {
- let mut iter = block
+fn never_loop_block(block: &Block<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: HirId) -> NeverLoopResult {
+ let iter = block
.stmts
.iter()
.filter_map(stmt_to_expr)
.chain(block.expr.map(|expr| (expr, None)));
- never_loop_expr_seq(&mut iter, main_loop_id)
-}
-fn never_loop_expr_seq<'a, T: Iterator<Item = (&'a Expr<'a>, Option<&'a Block<'a>>)>>(
- es: &mut T,
- main_loop_id: HirId,
-) -> NeverLoopResult {
- es.map(|(e, els)| {
- let e = never_loop_expr(e, main_loop_id);
- els.map_or(e, |els| combine_branches(e, never_loop_block(els, main_loop_id)))
+ iter.map(|(e, els)| {
+ let e = never_loop_expr(e, ignore_ids, main_loop_id);
+ // els is an else block in a let...else binding
+ els.map_or(e, |els| {
+ combine_branches(e, never_loop_block(els, ignore_ids, main_loop_id))
+ })
})
.fold(NeverLoopResult::Otherwise, combine_seq)
}
fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'tcx Block<'tcx>>)> {
match stmt.kind {
- StmtKind::Semi(e, ..) | StmtKind::Expr(e, ..) => Some((e, None)),
+ StmtKind::Semi(e) | StmtKind::Expr(e) => Some((e, None)),
+ // add the let...else expression (if present)
StmtKind::Local(local) => local.init.map(|init| (init, local.els)),
StmtKind::Item(..) => None,
}
}
-fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
+#[allow(clippy::too_many_lines)]
+fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: HirId) -> NeverLoopResult {
match expr.kind {
ExprKind::Box(e)
| ExprKind::Unary(_, e)
@@ -129,47 +128,56 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
| ExprKind::Field(e, _)
| ExprKind::AddrOf(_, _, e)
| ExprKind::Repeat(e, _)
- | ExprKind::DropTemps(e) => never_loop_expr(e, main_loop_id),
- ExprKind::Let(let_expr) => never_loop_expr(let_expr.init, main_loop_id),
- ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(&mut es.iter(), main_loop_id),
- ExprKind::MethodCall(_, receiver, es, _) => {
- never_loop_expr_all(&mut std::iter::once(receiver).chain(es.iter()), main_loop_id)
- },
+ | ExprKind::DropTemps(e) => never_loop_expr(e, ignore_ids, main_loop_id),
+ ExprKind::Let(let_expr) => never_loop_expr(let_expr.init, ignore_ids, main_loop_id),
+ ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(&mut es.iter(), ignore_ids, main_loop_id),
+ ExprKind::MethodCall(_, receiver, es, _) => never_loop_expr_all(
+ &mut std::iter::once(receiver).chain(es.iter()),
+ ignore_ids,
+ main_loop_id,
+ ),
ExprKind::Struct(_, fields, base) => {
- let fields = never_loop_expr_all(&mut fields.iter().map(|f| f.expr), main_loop_id);
+ let fields = never_loop_expr_all(&mut fields.iter().map(|f| f.expr), ignore_ids, main_loop_id);
if let Some(base) = base {
- combine_both(fields, never_loop_expr(base, main_loop_id))
+ combine_both(fields, never_loop_expr(base, ignore_ids, main_loop_id))
} else {
fields
}
},
- ExprKind::Call(e, es) => never_loop_expr_all(&mut once(e).chain(es.iter()), main_loop_id),
+ ExprKind::Call(e, es) => never_loop_expr_all(&mut once(e).chain(es.iter()), ignore_ids, main_loop_id),
ExprKind::Binary(_, e1, e2)
| ExprKind::Assign(e1, e2, _)
| ExprKind::AssignOp(_, e1, e2)
- | ExprKind::Index(e1, e2) => never_loop_expr_all(&mut [e1, e2].iter().copied(), main_loop_id),
+ | ExprKind::Index(e1, e2) => never_loop_expr_all(&mut [e1, e2].iter().copied(), ignore_ids, main_loop_id),
ExprKind::Loop(b, _, _, _) => {
// Break can come from the inner loop so remove them.
- absorb_break(never_loop_block(b, main_loop_id))
+ absorb_break(never_loop_block(b, ignore_ids, main_loop_id))
},
ExprKind::If(e, e2, e3) => {
- let e1 = never_loop_expr(e, main_loop_id);
- let e2 = never_loop_expr(e2, main_loop_id);
- let e3 = e3
- .as_ref()
- .map_or(NeverLoopResult::Otherwise, |e| never_loop_expr(e, main_loop_id));
+ let e1 = never_loop_expr(e, ignore_ids, main_loop_id);
+ let e2 = never_loop_expr(e2, ignore_ids, main_loop_id);
+ let e3 = e3.as_ref().map_or(NeverLoopResult::Otherwise, |e| {
+ never_loop_expr(e, ignore_ids, main_loop_id)
+ });
combine_seq(e1, combine_branches(e2, e3))
},
ExprKind::Match(e, arms, _) => {
- let e = never_loop_expr(e, main_loop_id);
+ let e = never_loop_expr(e, ignore_ids, main_loop_id);
if arms.is_empty() {
e
} else {
- let arms = never_loop_expr_branch(&mut arms.iter().map(|a| a.body), main_loop_id);
+ let arms = never_loop_expr_branch(&mut arms.iter().map(|a| a.body), ignore_ids, main_loop_id);
combine_seq(e, arms)
}
},
- ExprKind::Block(b, _) => never_loop_block(b, main_loop_id),
+ ExprKind::Block(b, l) => {
+ if l.is_some() {
+ ignore_ids.push(b.hir_id);
+ }
+ let ret = never_loop_block(b, ignore_ids, main_loop_id);
+ ignore_ids.pop();
+ ret
+ },
ExprKind::Continue(d) => {
let id = d
.target_id
@@ -180,20 +188,32 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
NeverLoopResult::AlwaysBreak
}
},
+ // 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::Otherwise, |e| {
+ combine_seq(never_loop_expr(e, ignore_ids, main_loop_id), NeverLoopResult::Otherwise)
+ }),
ExprKind::Break(_, e) | ExprKind::Ret(e) => e.as_ref().map_or(NeverLoopResult::AlwaysBreak, |e| {
- combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak)
+ combine_seq(
+ never_loop_expr(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(expr, main_loop_id)
+ never_loop_expr(expr, ignore_ids, main_loop_id)
},
- InlineAsmOperand::Out { expr, .. } => never_loop_expr_all(&mut expr.iter().copied(), main_loop_id),
- InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
- never_loop_expr_all(&mut once(*in_expr).chain(out_expr.iter().copied()), main_loop_id)
+ InlineAsmOperand::Out { expr, .. } => {
+ never_loop_expr_all(&mut expr.iter().copied(), ignore_ids, main_loop_id)
},
+ InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => never_loop_expr_all(
+ &mut once(*in_expr).chain(out_expr.iter().copied()),
+ ignore_ids,
+ main_loop_id,
+ ),
InlineAsmOperand::Const { .. }
| InlineAsmOperand::SymFn { .. }
| InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise,
@@ -208,13 +228,21 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
}
}
-fn never_loop_expr_all<'a, T: Iterator<Item = &'a Expr<'a>>>(es: &mut T, main_loop_id: HirId) -> NeverLoopResult {
- es.map(|e| never_loop_expr(e, main_loop_id))
+fn never_loop_expr_all<'a, T: Iterator<Item = &'a Expr<'a>>>(
+ es: &mut T,
+ ignore_ids: &mut Vec<HirId>,
+ main_loop_id: HirId,
+) -> NeverLoopResult {
+ es.map(|e| never_loop_expr(e, ignore_ids, main_loop_id))
.fold(NeverLoopResult::Otherwise, combine_both)
}
-fn never_loop_expr_branch<'a, T: Iterator<Item = &'a Expr<'a>>>(e: &mut T, main_loop_id: HirId) -> NeverLoopResult {
- e.map(|e| never_loop_expr(e, main_loop_id))
+fn never_loop_expr_branch<'a, T: Iterator<Item = &'a Expr<'a>>>(
+ e: &mut T,
+ ignore_ids: &mut Vec<HirId>,
+ main_loop_id: HirId,
+) -> NeverLoopResult {
+ e.map(|e| never_loop_expr(e, ignore_ids, main_loop_id))
.fold(NeverLoopResult::AlwaysBreak, combine_branches)
}
diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs
index 594f6af76..e2e6a87a3 100644
--- a/src/tools/clippy/clippy_lints/src/macro_use.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_use.rs
@@ -94,7 +94,10 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
let hir_id = item.hir_id();
let attrs = cx.tcx.hir().attrs(hir_id);
if let Some(mac_attr) = attrs.iter().find(|attr| attr.has_name(sym::macro_use));
- if let Res::Def(DefKind::Mod, id) = path.res;
+ if let Some(id) = path.res.iter().find_map(|res| match res {
+ Res::Def(DefKind::Mod, id) => Some(id),
+ _ => None,
+ });
if !id.is_local();
then {
for kid in cx.tcx.module_children(id).iter() {
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index 090f9f8ff..075ecbe7e 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{
AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound,
- HirId, IsAsync, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
+ HirId, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
) {
if_chain! {
if let Some(header) = kind.header();
- if header.asyncness == IsAsync::NotAsync;
+ if !header.asyncness.is_async();
// Check that this function returns `impl Future`
if let FnRetTy::Return(ret_ty) = decl.output;
if let Some((trait_ref, output_lifetimes)) = future_trait_ref(cx, ret_ty);
@@ -118,7 +118,7 @@ fn future_trait_ref<'tcx>(
.iter()
.filter_map(|bound| {
if let GenericArg::Lifetime(lt) = bound {
- Some(lt.name)
+ Some(lt.res)
} else {
None
}
@@ -153,7 +153,7 @@ fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName])
.iter()
.filter_map(|ty| {
if let TyKind::Rptr(lt, _) = ty.kind {
- Some(lt.name)
+ Some(lt.res)
} else {
None
}
@@ -177,7 +177,7 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>)
if let Some(args) = cx
.tcx
.lang_items()
- .from_generator_fn()
+ .identity_future_fn()
.and_then(|def_id| match_function_call_with_def_id(cx, block_expr, def_id));
if args.len() == 1;
if let Expr {
diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs
index 6655c92b1..462d73cf0 100644
--- a/src/tools/clippy/clippy_lints/src/manual_bits.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs
@@ -1,12 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::get_parent_expr;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{get_parent_expr, meets_msrv, msrvs};
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, Ty};
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::sym;
@@ -34,12 +34,12 @@ declare_clippy_lint! {
#[derive(Clone)]
pub struct ManualBits {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl ManualBits {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -48,7 +48,7 @@ impl_lint_pass!(ManualBits => [MANUAL_BITS]);
impl<'tcx> LateLintPass<'tcx> for ManualBits {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if !meets_msrv(self.msrv, msrvs::MANUAL_BITS) {
+ if !self.msrv.meets(msrvs::MANUAL_BITS) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/manual_clamp.rs b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
index 02dc8755d..f239736d3 100644
--- a/src/tools/clippy/clippy_lints/src/manual_clamp.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
@@ -1,28 +1,25 @@
+use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
+use clippy_utils::higher::If;
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::sugg::Sugg;
+use clippy_utils::ty::implements_trait;
+use clippy_utils::visitors::is_const_evaluatable;
+use clippy_utils::MaybePath;
+use clippy_utils::{
+ eq_expr_value, is_diag_trait_item, is_trait_method, path_res, path_to_local_id, peel_blocks, peel_blocks_with_stmt,
+};
use itertools::Itertools;
+use rustc_errors::Applicability;
use rustc_errors::Diagnostic;
use rustc_hir::{
def::Res, Arm, BinOpKind, Block, Expr, ExprKind, Guard, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{symbol::sym, Span};
use std::ops::Deref;
-use clippy_utils::{
- diagnostics::{span_lint_and_then, span_lint_hir_and_then},
- eq_expr_value,
- higher::If,
- is_diag_trait_item, is_trait_method, meets_msrv, msrvs, path_res, path_to_local_id, peel_blocks,
- peel_blocks_with_stmt,
- sugg::Sugg,
- ty::implements_trait,
- visitors::is_const_evaluatable,
- MaybePath,
-};
-use rustc_errors::Applicability;
-
declare_clippy_lint! {
/// ### What it does
/// Identifies good opportunities for a clamp function from std or core, and suggests using it.
@@ -38,6 +35,9 @@ declare_clippy_lint! {
/// Some may consider panicking in these situations to be desirable, but it also may
/// introduce panicking where there wasn't any before.
///
+ /// See also [the discussion in the
+ /// PR](https://github.com/rust-lang/rust-clippy/pull/9484#issuecomment-1278922613).
+ ///
/// ### Examples
/// ```rust
/// # let (input, min, max) = (0, -2, 1);
@@ -81,17 +81,17 @@ declare_clippy_lint! {
/// ```
#[clippy::version = "1.66.0"]
pub MANUAL_CLAMP,
- complexity,
+ nursery,
"using a clamp pattern instead of the clamp function"
}
impl_lint_pass!(ManualClamp => [MANUAL_CLAMP]);
pub struct ManualClamp {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl ManualClamp {
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -114,7 +114,7 @@ struct InputMinMax<'tcx> {
impl<'tcx> LateLintPass<'tcx> for ManualClamp {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
- if !meets_msrv(self.msrv, msrvs::CLAMP) {
+ if !self.msrv.meets(msrvs::CLAMP) {
return;
}
if !expr.span.from_expansion() {
@@ -130,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualClamp {
}
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
- if !meets_msrv(self.msrv, msrvs::CLAMP) {
+ if !self.msrv.meets(msrvs::CLAMP) {
return;
}
for suggestion in is_two_if_pattern(cx, block) {
diff --git a/src/tools/clippy/clippy_lints/src/manual_instant_elapsed.rs b/src/tools/clippy/clippy_lints/src/manual_instant_elapsed.rs
deleted file mode 100644
index 331cda1db..000000000
--- a/src/tools/clippy/clippy_lints/src/manual_instant_elapsed.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::Spanned;
-
-declare_clippy_lint! {
- /// ### What it does
- /// Lints subtraction between `Instant::now()` and another `Instant`.
- ///
- /// ### Why is this bad?
- /// It is easy to accidentally write `prev_instant - Instant::now()`, which will always be 0ns
- /// as `Instant` subtraction saturates.
- ///
- /// `prev_instant.elapsed()` also more clearly signals intention.
- ///
- /// ### Example
- /// ```rust
- /// use std::time::Instant;
- /// let prev_instant = Instant::now();
- /// let duration = Instant::now() - prev_instant;
- /// ```
- /// Use instead:
- /// ```rust
- /// use std::time::Instant;
- /// let prev_instant = Instant::now();
- /// let duration = prev_instant.elapsed();
- /// ```
- #[clippy::version = "1.64.0"]
- pub MANUAL_INSTANT_ELAPSED,
- pedantic,
- "subtraction between `Instant::now()` and previous `Instant`"
-}
-
-declare_lint_pass!(ManualInstantElapsed => [MANUAL_INSTANT_ELAPSED]);
-
-impl LateLintPass<'_> for ManualInstantElapsed {
- fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
- if let ExprKind::Binary(Spanned {node: BinOpKind::Sub, ..}, lhs, rhs) = expr.kind
- && check_instant_now_call(cx, lhs)
- && let ty_resolved = cx.typeck_results().expr_ty(rhs)
- && let rustc_middle::ty::Adt(def, _) = ty_resolved.kind()
- && clippy_utils::match_def_path(cx, def.did(), &clippy_utils::paths::INSTANT)
- && let Some(sugg) = clippy_utils::sugg::Sugg::hir_opt(cx, rhs)
- {
- span_lint_and_sugg(
- cx,
- MANUAL_INSTANT_ELAPSED,
- expr.span,
- "manual implementation of `Instant::elapsed`",
- "try",
- format!("{}.elapsed()", sugg.maybe_par()),
- Applicability::MachineApplicable,
- );
- }
- }
-}
-
-fn check_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool {
- if let ExprKind::Call(fn_expr, []) = expr_block.kind
- && let Some(fn_id) = clippy_utils::path_def_id(cx, fn_expr)
- && clippy_utils::match_def_path(cx, fn_id, &clippy_utils::paths::INSTANT_NOW)
- {
- true
- } else {
- false
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
new file mode 100644
index 000000000..5ab049d8d
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
@@ -0,0 +1,155 @@
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::{diagnostics::span_lint_and_sugg, in_constant, macros::root_macro_call, source::snippet};
+use rustc_ast::LitKind::{Byte, Char};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind, PatKind, RangeEnd};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{def_id::DefId, sym};
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Suggests to use dedicated built-in methods,
+ /// `is_ascii_(lowercase|uppercase|digit)` for checking on corresponding ascii range
+ ///
+ /// ### Why is this bad?
+ /// Using the built-in functions is more readable and makes it
+ /// clear that it's not a specific subset of characters, but all
+ /// ASCII (lowercase|uppercase|digit) characters.
+ /// ### Example
+ /// ```rust
+ /// fn main() {
+ /// assert!(matches!('x', 'a'..='z'));
+ /// assert!(matches!(b'X', b'A'..=b'Z'));
+ /// assert!(matches!('2', '0'..='9'));
+ /// assert!(matches!('x', 'A'..='Z' | 'a'..='z'));
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// fn main() {
+ /// assert!('x'.is_ascii_lowercase());
+ /// assert!(b'X'.is_ascii_uppercase());
+ /// assert!('2'.is_ascii_digit());
+ /// assert!('x'.is_ascii_alphabetic());
+ /// }
+ /// ```
+ #[clippy::version = "1.66.0"]
+ pub MANUAL_IS_ASCII_CHECK,
+ style,
+ "use dedicated method to check ascii range"
+}
+impl_lint_pass!(ManualIsAsciiCheck => [MANUAL_IS_ASCII_CHECK]);
+
+pub struct ManualIsAsciiCheck {
+ msrv: Msrv,
+}
+
+impl ManualIsAsciiCheck {
+ #[must_use]
+ pub fn new(msrv: Msrv) -> Self {
+ Self { msrv }
+ }
+}
+
+#[derive(Debug, PartialEq)]
+enum CharRange {
+ /// 'a'..='z' | b'a'..=b'z'
+ LowerChar,
+ /// 'A'..='Z' | b'A'..=b'Z'
+ UpperChar,
+ /// AsciiLower | AsciiUpper
+ FullChar,
+ /// '0..=9'
+ Digit,
+ Otherwise,
+}
+
+impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+ if !self.msrv.meets(msrvs::IS_ASCII_DIGIT) {
+ return;
+ }
+
+ if in_constant(cx, expr.hir_id) && !self.msrv.meets(msrvs::IS_ASCII_DIGIT_CONST) {
+ return;
+ }
+
+ let Some(macro_call) = root_macro_call(expr.span) else { return };
+
+ if is_matches_macro(cx, macro_call.def_id) {
+ if let ExprKind::Match(recv, [arm, ..], _) = expr.kind {
+ let range = check_pat(&arm.pat.kind);
+
+ if let Some(sugg) = match range {
+ CharRange::UpperChar => Some("is_ascii_uppercase"),
+ CharRange::LowerChar => Some("is_ascii_lowercase"),
+ CharRange::FullChar => Some("is_ascii_alphabetic"),
+ CharRange::Digit => Some("is_ascii_digit"),
+ CharRange::Otherwise => None,
+ } {
+ let default_snip = "..";
+ // `snippet_with_applicability` may set applicability to `MaybeIncorrect` for
+ // macro span, so we check applicability manually by comparing `recv` is not default.
+ let recv = snippet(cx, recv.span, default_snip);
+
+ let applicability = if recv == default_snip {
+ Applicability::HasPlaceholders
+ } else {
+ Applicability::MachineApplicable
+ };
+
+ span_lint_and_sugg(
+ cx,
+ MANUAL_IS_ASCII_CHECK,
+ macro_call.span,
+ "manual check for common ascii range",
+ "try",
+ format!("{recv}.{sugg}()"),
+ applicability,
+ );
+ }
+ }
+ }
+ }
+
+ extract_msrv_attr!(LateContext);
+}
+
+fn check_pat(pat_kind: &PatKind<'_>) -> CharRange {
+ match pat_kind {
+ PatKind::Or(pats) => {
+ let ranges = pats.iter().map(|p| check_pat(&p.kind)).collect::<Vec<_>>();
+
+ if ranges.len() == 2 && ranges.contains(&CharRange::UpperChar) && ranges.contains(&CharRange::LowerChar) {
+ CharRange::FullChar
+ } else {
+ CharRange::Otherwise
+ }
+ },
+ PatKind::Range(Some(start), Some(end), kind) if *kind == RangeEnd::Included => check_range(start, end),
+ _ => CharRange::Otherwise,
+ }
+}
+
+fn check_range(start: &Expr<'_>, end: &Expr<'_>) -> CharRange {
+ if let ExprKind::Lit(start_lit) = &start.kind
+ && let ExprKind::Lit(end_lit) = &end.kind {
+ match (&start_lit.node, &end_lit.node) {
+ (Char('a'), Char('z')) | (Byte(b'a'), Byte(b'z')) => CharRange::LowerChar,
+ (Char('A'), Char('Z')) | (Byte(b'A'), Byte(b'Z')) => CharRange::UpperChar,
+ (Char('0'), Char('9')) | (Byte(b'0'), Byte(b'9')) => CharRange::Digit,
+ _ => CharRange::Otherwise,
+ }
+ } else {
+ CharRange::Otherwise
+ }
+}
+
+fn is_matches_macro(cx: &LateContext<'_>, macro_def_id: DefId) -> bool {
+ if let Some(name) = cx.tcx.get_diagnostic_name(macro_def_id) {
+ return sym::matches_macro == name;
+ }
+
+ false
+}
diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
new file mode 100644
index 000000000..874d36ca9
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
@@ -0,0 +1,295 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::higher::IfLetOrMatch;
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::peel_blocks;
+use clippy_utils::source::snippet_with_context;
+use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::visitors::{for_each_expr, Descend};
+use if_chain::if_chain;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind, MatchSource, Pat, 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::symbol::sym;
+use rustc_span::Span;
+use serde::Deserialize;
+use std::ops::ControlFlow;
+
+declare_clippy_lint! {
+ /// ### What it does
+ ///
+ /// Warn of cases where `let...else` could be used
+ ///
+ /// ### Why is this bad?
+ ///
+ /// `let...else` provides a standard construct for this pattern
+ /// that people can easily recognize. It's also more compact.
+ ///
+ /// ### Example
+ ///
+ /// ```rust
+ /// # let w = Some(0);
+ /// let v = if let Some(v) = w { v } else { return };
+ /// ```
+ ///
+ /// Could be written:
+ ///
+ /// ```rust
+ /// # #![feature(let_else)]
+ /// # fn main () {
+ /// # let w = Some(0);
+ /// let Some(v) = w else { return };
+ /// # }
+ /// ```
+ #[clippy::version = "1.67.0"]
+ pub MANUAL_LET_ELSE,
+ pedantic,
+ "manual implementation of a let...else statement"
+}
+
+pub struct ManualLetElse {
+ msrv: Msrv,
+ matches_behaviour: MatchLintBehaviour,
+}
+
+impl ManualLetElse {
+ #[must_use]
+ pub fn new(msrv: Msrv, matches_behaviour: MatchLintBehaviour) -> Self {
+ Self {
+ msrv,
+ matches_behaviour,
+ }
+ }
+}
+
+impl_lint_pass!(ManualLetElse => [MANUAL_LET_ELSE]);
+
+impl<'tcx> LateLintPass<'tcx> for ManualLetElse {
+ fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) {
+ let if_let_or_match = if_chain! {
+ if self.msrv.meets(msrvs::LET_ELSE);
+ if !in_external_macro(cx.sess(), stmt.span);
+ if let StmtKind::Local(local) = stmt.kind;
+ if let Some(init) = local.init;
+ if local.els.is_none();
+ if local.ty.is_none();
+ if init.span.ctxt() == stmt.span.ctxt();
+ if let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init);
+ then {
+ if_let_or_match
+ } else {
+ return;
+ }
+ };
+
+ match if_let_or_match {
+ IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else) => if_chain! {
+ if expr_is_simple_identity(let_pat, if_then);
+ if let Some(if_else) = if_else;
+ if expr_diverges(cx, if_else);
+ then {
+ emit_manual_let_else(cx, stmt.span, if_let_expr, let_pat, if_else);
+ }
+ },
+ IfLetOrMatch::Match(match_expr, arms, source) => {
+ if self.matches_behaviour == MatchLintBehaviour::Never {
+ return;
+ }
+ if source != MatchSource::Normal {
+ return;
+ }
+ // Any other number than two arms doesn't (neccessarily)
+ // have a trivial mapping to let else.
+ if arms.len() != 2 {
+ return;
+ }
+ // Guards don't give us an easy mapping either
+ if arms.iter().any(|arm| arm.guard.is_some()) {
+ return;
+ }
+ let check_types = self.matches_behaviour == MatchLintBehaviour::WellKnownTypes;
+ let diverging_arm_opt = arms
+ .iter()
+ .enumerate()
+ .find(|(_, arm)| expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat, check_types));
+ let Some((idx, diverging_arm)) = diverging_arm_opt else { return; };
+ let pat_arm = &arms[1 - idx];
+ if !expr_is_simple_identity(pat_arm.pat, pat_arm.body) {
+ return;
+ }
+
+ emit_manual_let_else(cx, stmt.span, match_expr, pat_arm.pat, diverging_arm.body);
+ },
+ }
+ }
+
+ extract_msrv_attr!(LateContext);
+}
+
+fn emit_manual_let_else(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, pat: &Pat<'_>, else_body: &Expr<'_>) {
+ span_lint_and_then(
+ cx,
+ MANUAL_LET_ELSE,
+ span,
+ "this could be rewritten as `let...else`",
+ |diag| {
+ // This is far from perfect, for example there needs to be:
+ // * mut additions for the bindings
+ // * renamings of the bindings
+ // * unused binding collision detection with existing ones
+ // * putting patterns with at the top level | inside ()
+ // for this to be machine applicable.
+ let mut app = Applicability::HasPlaceholders;
+ let (sn_pat, _) = snippet_with_context(cx, pat.span, span.ctxt(), "", &mut app);
+ let (sn_expr, _) = snippet_with_context(cx, expr.span, span.ctxt(), "", &mut app);
+ let (sn_else, _) = snippet_with_context(cx, else_body.span, span.ctxt(), "", &mut app);
+
+ let else_bl = if matches!(else_body.kind, ExprKind::Block(..)) {
+ sn_else.into_owned()
+ } else {
+ format!("{{ {sn_else} }}")
+ };
+ let sugg = format!("let {sn_pat} = {sn_expr} else {else_bl};");
+ diag.span_suggestion(span, "consider writing", sugg, app);
+ },
+ );
+}
+
+fn expr_diverges(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool {
+ fn is_never(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool {
+ if let Some(ty) = cx.typeck_results().expr_ty_opt(expr) {
+ return ty.is_never();
+ }
+ false
+ }
+ // We can't just call is_never on expr and be done, because the type system
+ // sometimes coerces the ! type to something different before we can get
+ // our hands on it. So instead, we do a manual search. We do fall back to
+ // is_never in some places when there is no better alternative.
+ for_each_expr(expr, |ex| {
+ match ex.kind {
+ ExprKind::Continue(_) | ExprKind::Break(_, _) | ExprKind::Ret(_) => ControlFlow::Break(()),
+ ExprKind::Call(call, _) => {
+ if is_never(cx, ex) || is_never(cx, call) {
+ return ControlFlow::Break(());
+ }
+ ControlFlow::Continue(Descend::Yes)
+ },
+ ExprKind::MethodCall(..) => {
+ if is_never(cx, ex) {
+ return ControlFlow::Break(());
+ }
+ ControlFlow::Continue(Descend::Yes)
+ },
+ ExprKind::If(if_expr, if_then, if_else) => {
+ let else_diverges = if_else.map_or(false, |ex| expr_diverges(cx, ex));
+ let diverges = expr_diverges(cx, if_expr) || (else_diverges && expr_diverges(cx, if_then));
+ if diverges {
+ return ControlFlow::Break(());
+ }
+ ControlFlow::Continue(Descend::No)
+ },
+ ExprKind::Match(match_expr, match_arms, _) => {
+ let diverges = expr_diverges(cx, match_expr)
+ || match_arms.iter().all(|arm| {
+ let guard_diverges = arm.guard.as_ref().map_or(false, |g| expr_diverges(cx, g.body()));
+ guard_diverges || expr_diverges(cx, arm.body)
+ });
+ if diverges {
+ return ControlFlow::Break(());
+ }
+ ControlFlow::Continue(Descend::No)
+ },
+
+ // Don't continue into loops or labeled blocks, as they are breakable,
+ // and we'd have to start checking labels.
+ ExprKind::Block(_, Some(_)) | ExprKind::Loop(..) => ControlFlow::Continue(Descend::No),
+
+ // Default: descend
+ _ => ControlFlow::Continue(Descend::Yes),
+ }
+ })
+ .is_some()
+}
+
+fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: bool) -> bool {
+ // Check whether the pattern contains any bindings, as the
+ // binding might potentially be used in the body.
+ // TODO: only look for *used* bindings.
+ let mut has_bindings = false;
+ pat.each_binding_or_first(&mut |_, _, _, _| has_bindings = true);
+ if has_bindings {
+ return false;
+ }
+
+ // If we shouldn't check the types, exit early.
+ if !check_types {
+ return true;
+ }
+
+ // Check whether any possibly "unknown" patterns are included,
+ // because users might not know which values some enum has.
+ // Well-known enums are excepted, as we assume people know them.
+ // We do a deep check, to be able to disallow Err(En::Foo(_))
+ // for usage of the En::Foo variant, as we disallow En::Foo(_),
+ // but we allow Err(_).
+ let typeck_results = cx.typeck_results();
+ let mut has_disallowed = false;
+ pat.walk_always(|pat| {
+ // Only do the check if the type is "spelled out" in the pattern
+ if !matches!(
+ pat.kind,
+ PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..)
+ ) {
+ return;
+ };
+ let ty = typeck_results.pat_ty(pat);
+ // Option and Result are allowed, everything else isn't.
+ if !(is_type_diagnostic_item(cx, ty, sym::Option) || is_type_diagnostic_item(cx, ty, sym::Result)) {
+ has_disallowed = true;
+ }
+ });
+ !has_disallowed
+}
+
+/// Checks if the passed block is a simple identity referring to bindings created by the pattern
+fn expr_is_simple_identity(pat: &'_ Pat<'_>, expr: &'_ Expr<'_>) -> bool {
+ // We support patterns with multiple bindings and tuples, like:
+ // let ... = if let (Some(foo), bar) = g() { (foo, bar) } else { ... }
+ let peeled = peel_blocks(expr);
+ let paths = match peeled.kind {
+ ExprKind::Tup(exprs) | ExprKind::Array(exprs) => exprs,
+ ExprKind::Path(_) => std::slice::from_ref(peeled),
+ _ => return false,
+ };
+ let mut pat_bindings = FxHashSet::default();
+ pat.each_binding_or_first(&mut |_ann, _hir_id, _sp, ident| {
+ pat_bindings.insert(ident);
+ });
+ if pat_bindings.len() < paths.len() {
+ return false;
+ }
+ for path in paths {
+ if_chain! {
+ if let ExprKind::Path(QPath::Resolved(_ty, path)) = path.kind;
+ if let [path_seg] = path.segments;
+ then {
+ if !pat_bindings.remove(&path_seg.ident) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+ true
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize)]
+pub enum MatchLintBehaviour {
+ AllTypes,
+ WellKnownTypes,
+ Never,
+}
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 6806c1466..bca193be9 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -1,6 +1,7 @@
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
+use clippy_utils::is_doc_hidden;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_opt;
-use clippy_utils::{is_doc_hidden, meets_msrv, msrvs};
use rustc_ast::ast::{self, VisibilityKind};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
@@ -8,7 +9,6 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::{self as hir, Expr, ExprKind, QPath};
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
use rustc_middle::ty::DefIdTree;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::{sym, Span};
@@ -63,12 +63,12 @@ declare_clippy_lint! {
#[expect(clippy::module_name_repetitions)]
pub struct ManualNonExhaustiveStruct {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl ManualNonExhaustiveStruct {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -77,14 +77,14 @@ impl_lint_pass!(ManualNonExhaustiveStruct => [MANUAL_NON_EXHAUSTIVE]);
#[expect(clippy::module_name_repetitions)]
pub struct ManualNonExhaustiveEnum {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
constructed_enum_variants: FxHashSet<(DefId, DefId)>,
potential_enums: Vec<(LocalDefId, LocalDefId, Span, Span)>,
}
impl ManualNonExhaustiveEnum {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self {
msrv,
constructed_enum_variants: FxHashSet::default(),
@@ -97,7 +97,7 @@ impl_lint_pass!(ManualNonExhaustiveEnum => [MANUAL_NON_EXHAUSTIVE]);
impl EarlyLintPass for ManualNonExhaustiveStruct {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
- if !meets_msrv(self.msrv, msrvs::NON_EXHAUSTIVE) {
+ if !self.msrv.meets(msrvs::NON_EXHAUSTIVE) {
return;
}
@@ -149,7 +149,7 @@ impl EarlyLintPass for ManualNonExhaustiveStruct {
impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
- if !meets_msrv(self.msrv, msrvs::NON_EXHAUSTIVE) {
+ if !self.msrv.meets(msrvs::NON_EXHAUSTIVE) {
return;
}
@@ -157,10 +157,10 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
&& def.variants.len() > 1
{
let mut iter = def.variants.iter().filter_map(|v| {
- let id = cx.tcx.hir().local_def_id(v.id);
- (matches!(v.data, hir::VariantData::Unit(_))
+ let id = cx.tcx.hir().local_def_id(v.hir_id);
+ (matches!(v.data, hir::VariantData::Unit(..))
&& v.ident.as_str().starts_with('_')
- && is_doc_hidden(cx.tcx.hir().attrs(v.id)))
+ && is_doc_hidden(cx.tcx.hir().attrs(v.hir_id)))
.then_some((id, v.span))
});
if let Some((id, span)) = iter.next()
diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
index 6f25a2ed8..8d447c371 100644
--- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
@@ -1,12 +1,12 @@
use clippy_utils::consts::{constant_full_int, FullInt};
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{in_constant, meets_msrv, msrvs, path_to_local};
+use clippy_utils::{in_constant, path_to_local};
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! {
@@ -34,12 +34,12 @@ declare_clippy_lint! {
}
pub struct ManualRemEuclid {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl ManualRemEuclid {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -48,11 +48,11 @@ impl_lint_pass!(ManualRemEuclid => [MANUAL_REM_EUCLID]);
impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if !meets_msrv(self.msrv, msrvs::REM_EUCLID) {
+ if !self.msrv.meets(msrvs::REM_EUCLID) {
return;
}
- if in_constant(cx, expr.hir_id) && !meets_msrv(self.msrv, msrvs::REM_EUCLID_CONST) {
+ if in_constant(cx, expr.hir_id) && !self.msrv.meets(msrvs::REM_EUCLID_CONST) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs
index 3181bc86d..c1e6c8248 100644
--- a/src/tools/clippy/clippy_lints/src/manual_retain.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs
@@ -1,8 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use clippy_utils::{get_parent_expr, match_def_path, paths, SpanlessEq};
-use clippy_utils::{meets_msrv, msrvs};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
@@ -50,12 +50,12 @@ declare_clippy_lint! {
}
pub struct ManualRetain {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl ManualRetain {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -71,9 +71,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRetain {
&& let hir::ExprKind::MethodCall(_, target_expr, [], _) = &collect_expr.kind
&& let Some(collect_def_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id)
&& match_def_path(cx, collect_def_id, &paths::CORE_ITER_COLLECT) {
- check_into_iter(cx, parent_expr, left_expr, target_expr, self.msrv);
- check_iter(cx, parent_expr, left_expr, target_expr, self.msrv);
- check_to_owned(cx, parent_expr, left_expr, target_expr, self.msrv);
+ check_into_iter(cx, parent_expr, left_expr, target_expr, &self.msrv);
+ check_iter(cx, parent_expr, left_expr, target_expr, &self.msrv);
+ check_to_owned(cx, parent_expr, left_expr, target_expr, &self.msrv);
}
}
@@ -85,14 +85,14 @@ fn check_into_iter(
parent_expr: &hir::Expr<'_>,
left_expr: &hir::Expr<'_>,
target_expr: &hir::Expr<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) {
if let hir::ExprKind::MethodCall(_, into_iter_expr, [_], _) = &target_expr.kind
&& let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
&& match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
&& let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &into_iter_expr.kind
&& let Some(into_iter_def_id) = cx.typeck_results().type_dependent_def_id(into_iter_expr.hir_id)
- && cx.tcx.lang_items().require(hir::LangItem::IntoIterIntoIter).ok() == Some(into_iter_def_id)
+ && Some(into_iter_def_id) == cx.tcx.lang_items().into_iter_fn()
&& match_acceptable_type(cx, left_expr, msrv)
&& SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) {
suggest(cx, parent_expr, left_expr, target_expr);
@@ -104,7 +104,7 @@ fn check_iter(
parent_expr: &hir::Expr<'_>,
left_expr: &hir::Expr<'_>,
target_expr: &hir::Expr<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) {
if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
&& let Some(copied_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
@@ -127,9 +127,9 @@ fn check_to_owned(
parent_expr: &hir::Expr<'_>,
left_expr: &hir::Expr<'_>,
target_expr: &hir::Expr<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) {
- if meets_msrv(msrv, msrvs::STRING_RETAIN)
+ if msrv.meets(msrvs::STRING_RETAIN)
&& let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
&& let Some(to_owned_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
&& match_def_path(cx, to_owned_def_id, &paths::TO_OWNED_METHOD)
@@ -140,7 +140,7 @@ fn check_to_owned(
&& let Some(chars_expr_def_id) = cx.typeck_results().type_dependent_def_id(chars_expr.hir_id)
&& match_def_path(cx, chars_expr_def_id, &paths::STR_CHARS)
&& let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
- && is_type_diagnostic_item(cx, ty, sym::String)
+ && is_type_lang_item(cx, ty, hir::LangItem::String)
&& SpanlessEq::new(cx).eq_expr(left_expr, str_expr) {
suggest(cx, parent_expr, left_expr, filter_expr);
}
@@ -215,10 +215,10 @@ fn match_acceptable_def_path(cx: &LateContext<'_>, collect_def_id: DefId) -> boo
.any(|&method| match_def_path(cx, collect_def_id, method))
}
-fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: Option<RustcVersion>) -> bool {
+fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv) -> bool {
let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();
ACCEPTABLE_TYPES.iter().any(|(ty, acceptable_msrv)| {
is_type_diagnostic_item(cx, expr_ty, *ty)
- && acceptable_msrv.map_or(true, |acceptable_msrv| meets_msrv(msrv, acceptable_msrv))
+ && acceptable_msrv.map_or(true, |acceptable_msrv| msrv.meets(acceptable_msrv))
})
}
diff --git a/src/tools/clippy/clippy_lints/src/manual_string_new.rs b/src/tools/clippy/clippy_lints/src/manual_string_new.rs
index 6acfb2ae3..c20d7959f 100644
--- a/src/tools/clippy/clippy_lints/src/manual_string_new.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_string_new.rs
@@ -44,7 +44,7 @@ impl LateLintPass<'_> for ManualStringNew {
let ty = cx.typeck_results().expr_ty(expr);
match ty.kind() {
ty::Adt(adt_def, _) if adt_def.is_struct() => {
- if !cx.tcx.is_diagnostic_item(sym::String, adt_def.did()) {
+ if cx.tcx.lang_items().string() != Some(adt_def.did()) {
return;
}
},
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index 0976940af..de166b976 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -1,8 +1,9 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
use clippy_utils::usage::mutated_variables;
-use clippy_utils::{eq_expr_value, higher, match_def_path, meets_msrv, msrvs, paths};
+use clippy_utils::{eq_expr_value, higher, match_def_path, paths};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
use rustc_hir::def::Res;
@@ -11,7 +12,6 @@ use rustc_hir::BinOpKind;
use rustc_hir::{BorrowKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Spanned;
use rustc_span::Span;
@@ -48,12 +48,12 @@ declare_clippy_lint! {
}
pub struct ManualStrip {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl ManualStrip {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -68,7 +68,7 @@ enum StripKind {
impl<'tcx> LateLintPass<'tcx> for ManualStrip {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if !meets_msrv(self.msrv, msrvs::STR_STRIP_PREFIX) {
+ if !self.msrv.meets(msrvs::STR_STRIP_PREFIX) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
index 32da37a86..59195d1ae 100644
--- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
@@ -119,7 +119,7 @@ fn is_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
/// semicolons, which causes problems when generating a suggestion. Given an
/// expression that evaluates to '()' or '!', recursively remove useless braces
/// and semi-colons until is suitable for including in the suggestion template
-fn reduce_unit_expression<'a>(cx: &LateContext<'_>, expr: &'a hir::Expr<'_>) -> Option<Span> {
+fn reduce_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Span> {
if !is_unit_expression(cx, expr) {
return None;
}
diff --git a/src/tools/clippy/clippy_lints/src/matches/infallible_destructuring_match.rs b/src/tools/clippy/clippy_lints/src/matches/infallible_destructuring_match.rs
index 2472acb6f..d18c92cab 100644
--- a/src/tools/clippy/clippy_lints/src/matches/infallible_destructuring_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/infallible_destructuring_match.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{path_to_local_id, peel_blocks, strip_pat_refs};
use rustc_errors::Applicability;
-use rustc_hir::{ExprKind, Local, MatchSource, PatKind, QPath};
+use rustc_hir::{ByRef, ExprKind, Local, MatchSource, PatKind, QPath};
use rustc_lint::LateContext;
use super::INFALLIBLE_DESTRUCTURING_MATCH;
@@ -16,7 +16,7 @@ pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool {
if let PatKind::TupleStruct(
QPath::Resolved(None, variant_name), args, _) = arms[0].pat.kind;
if args.len() == 1;
- if let PatKind::Binding(_, arg, ..) = strip_pat_refs(&args[0]).kind;
+ if let PatKind::Binding(binding, arg, ..) = strip_pat_refs(&args[0]).kind;
let body = peel_blocks(arms[0].body);
if path_to_local_id(body, arg);
@@ -30,8 +30,9 @@ pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool {
Consider using `let`",
"try this",
format!(
- "let {}({}) = {};",
+ "let {}({}{}) = {};",
snippet_with_applicability(cx, variant_name.span, "..", &mut applicability),
+ if binding.0 == ByRef::Yes { "ref " } else { "" },
snippet_with_applicability(cx, local.pat.span, "..", &mut applicability),
snippet_with_applicability(cx, target.span, "..", &mut applicability),
),
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_filter.rs b/src/tools/clippy/clippy_lints/src/matches/manual_filter.rs
index 66ba1f6f9..d521a529e 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_filter.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_filter.rs
@@ -62,7 +62,7 @@ fn peels_blocks_incl_unsafe<'a>(expr: &'a Expr<'a>) -> &'a Expr<'a> {
// <expr>
// }
// Returns true if <expr> resolves to `Some(x)`, `false` otherwise
-fn is_some_expr<'tcx>(cx: &LateContext<'_>, target: HirId, ctxt: SyntaxContext, expr: &'tcx Expr<'_>) -> bool {
+fn is_some_expr(cx: &LateContext<'_>, target: HirId, ctxt: SyntaxContext, expr: &Expr<'_>) -> bool {
if let Some(inner_expr) = peels_blocks_incl_unsafe_opt(expr) {
// there can be not statements in the block as they would be removed when switching to `.filter`
if let ExprKind::Call(callee, [arg]) = inner_expr.kind {
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
index 6647322ca..675a85ae5 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
@@ -1,13 +1,13 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::{Arm, Expr, ExprKind, PatKind};
+use rustc_hir::{Arm, Expr, ExprKind, LangItem, PatKind};
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_span::symbol::Symbol;
-use rustc_span::{sym, Span};
+use rustc_span::Span;
use super::MATCH_STR_CASE_MISMATCH;
@@ -59,7 +59,7 @@ impl<'a, 'tcx> MatchExprVisitor<'a, 'tcx> {
if let Some(case_method) = get_case_method(segment_ident) {
let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs();
- if is_type_diagnostic_item(self.cx, ty, sym::String) || ty.kind() == &ty::Str {
+ if is_type_lang_item(self.cx, ty, LangItem::String) || ty.kind() == &ty::Str {
self.case_method = Some(case_method);
return true;
}
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs
index 6f8d766ae..7f8d12483 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs
@@ -65,14 +65,14 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
_ => return,
};
if arm.guard.is_none() {
- missing_variants.retain(|e| e.ctor_def_id != Some(id));
+ missing_variants.retain(|e| e.ctor_def_id() != Some(id));
}
path
},
PatKind::TupleStruct(path, patterns, ..) => {
if let Some(id) = cx.qpath_res(path, pat.hir_id).opt_def_id() {
if arm.guard.is_none() && patterns.iter().all(|p| !is_refutable(cx, p)) {
- missing_variants.retain(|e| e.ctor_def_id != Some(id));
+ missing_variants.retain(|e| e.ctor_def_id() != Some(id));
}
}
path
@@ -122,11 +122,11 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
s
},
variant.name,
- match variant.ctor_kind {
- CtorKind::Fn if variant.fields.len() == 1 => "(_)",
- CtorKind::Fn => "(..)",
- CtorKind::Const => "",
- CtorKind::Fictive => "{ .. }",
+ match variant.ctor_kind() {
+ Some(CtorKind::Fn) if variant.fields.len() == 1 => "(_)",
+ Some(CtorKind::Fn) => "(..)",
+ Some(CtorKind::Const) => "",
+ None => "{ .. }",
}
)
};
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index 7d8171ead..7b15a307f 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -23,13 +23,13 @@ mod single_match;
mod try_err;
mod wild_in_or_pats;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{snippet_opt, walk_span_to_context};
-use clippy_utils::{higher, in_constant, is_span_match, meets_msrv, msrvs};
+use clippy_utils::{higher, in_constant, is_span_match};
use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat};
use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{Span, SpanData, SyntaxContext};
@@ -930,13 +930,13 @@ declare_clippy_lint! {
#[derive(Default)]
pub struct Matches {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
infallible_destructuring_match_linted: bool,
}
impl Matches {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self {
msrv,
..Matches::default()
@@ -1000,9 +1000,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
if !from_expansion && !contains_cfg_arm(cx, expr, ex, arms) {
if source == MatchSource::Normal {
- if !(meets_msrv(self.msrv, msrvs::MATCHES_MACRO)
- && match_like_matches::check_match(cx, expr, ex, arms))
- {
+ if !(self.msrv.meets(msrvs::MATCHES_MACRO) && match_like_matches::check_match(cx, expr, ex, arms)) {
match_same_arms::check(cx, arms);
}
@@ -1034,7 +1032,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
collapsible_match::check_if_let(cx, if_let.let_pat, if_let.if_then, if_let.if_else);
if !from_expansion {
if let Some(else_expr) = if_let.if_else {
- if meets_msrv(self.msrv, msrvs::MATCHES_MACRO) {
+ if self.msrv.meets(msrvs::MATCHES_MACRO) {
match_like_matches::check_if_let(
cx,
expr,
diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index 85269e533..f587c69f7 100644
--- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -83,8 +83,8 @@ fn set_diagnostic<'tcx>(diag: &mut Diagnostic, cx: &LateContext<'tcx>, expr: &'t
/// If the expression is an `ExprKind::Match`, check if the scrutinee has a significant drop that
/// may have a surprising lifetime.
-fn has_significant_drop_in_scrutinee<'tcx, 'a>(
- cx: &'a LateContext<'tcx>,
+fn has_significant_drop_in_scrutinee<'tcx>(
+ cx: &LateContext<'tcx>,
scrutinee: &'tcx Expr<'tcx>,
source: MatchSource,
) -> Option<(Vec<FoundSigDrop>, &'static str)> {
@@ -226,7 +226,7 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> {
/// This will try to set the current suggestion (so it can be moved into the suggestions vec
/// later). If `allow_move_and_clone` is false, the suggestion *won't* be set -- this gives us
/// an opportunity to look for another type in the chain that will be trivially copyable.
- /// However, if we are at the the end of the chain, we want to accept whatever is there. (The
+ /// However, if we are at the end of the chain, we want to accept whatever is there. (The
/// suggestion won't actually be output, but the diagnostic message will be output, so the user
/// can determine the best way to handle the lint.)
fn try_setting_current_suggestion(&mut self, expr: &'tcx Expr<'_>, allow_move_and_clone: bool) {
@@ -377,7 +377,7 @@ impl<'a, 'tcx> ArmSigDropHelper<'a, 'tcx> {
}
}
-fn has_significant_drop_in_arms<'tcx, 'a>(cx: &'a LateContext<'tcx>, arms: &'tcx [Arm<'_>]) -> FxHashSet<Span> {
+fn has_significant_drop_in_arms<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) -> FxHashSet<Span> {
let mut helper = ArmSigDropHelper::new(cx);
for arm in arms {
helper.visit_expr(arm.body);
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index e5a15b2e1..19b49c44d 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -153,7 +153,7 @@ fn pat_in_candidate_enum<'a>(cx: &LateContext<'a>, ty: Ty<'a>, pat: &Pat<'_>) ->
}
/// Returns `true` if the given type is an enum we know won't be expanded in the future
-fn in_candidate_enum<'a>(cx: &LateContext<'a>, ty: Ty<'_>) -> bool {
+fn in_candidate_enum(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
// list of candidate `Enum`s we know will never get any more members
let candidates = [sym::Cow, sym::Option, sym::Result];
diff --git a/src/tools/clippy/clippy_lints/src/matches/try_err.rs b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
index c6cba81d8..704c34c32 100644
--- a/src/tools/clippy/clippy_lints/src/matches/try_err.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{get_parent_expr, is_res_lang_ctor, match_def_path, path_res, paths};
+use clippy_utils::{get_parent_expr, is_res_lang_ctor, path_res};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::LangItem::ResultErr;
@@ -107,7 +107,7 @@ fn result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
fn poll_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
if_chain! {
if let ty::Adt(def, subst) = ty.kind();
- if match_def_path(cx, def.did(), &paths::POLL);
+ if cx.tcx.lang_items().get(LangItem::Poll) == Some(def.did());
let ready_ty = subst.type_at(0);
if let ty::Adt(ready_def, ready_subst) = ready_ty.kind();
@@ -124,7 +124,7 @@ fn poll_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<
fn poll_option_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
if_chain! {
if let ty::Adt(def, subst) = ty.kind();
- if match_def_path(cx, def.did(), &paths::POLL);
+ if cx.tcx.lang_items().get(LangItem::Poll) == Some(def.did());
let ready_ty = subst.type_at(0);
if let ty::Adt(ready_def, ready_subst) = ready_ty.kind();
diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs
index 0c4d9f100..35024ec12 100644
--- a/src/tools/clippy/clippy_lints/src/mem_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs
@@ -1,14 +1,14 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::ty::is_non_aggregate_primitive_type;
-use clippy_utils::{is_default_equivalent, is_res_lang_ctor, meets_msrv, msrvs, path_res};
+use clippy_utils::{is_default_equivalent, is_res_lang_ctor, path_res};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::LangItem::OptionNone;
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
use rustc_span::symbol::sym;
@@ -227,12 +227,12 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<
}
pub struct MemReplace {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl MemReplace {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -248,7 +248,7 @@ impl<'tcx> LateLintPass<'tcx> for MemReplace {
then {
check_replace_option_with_none(cx, src, dest, expr.span);
check_replace_with_uninit(cx, src, dest, expr.span);
- if meets_msrv(self.msrv, msrvs::MEM_TAKE) {
+ if self.msrv.meets(msrvs::MEM_TAKE) {
check_replace_with_default(cx, src, dest, expr.span);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
index cc26b0f7f..4720a6e68 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
@@ -41,7 +41,7 @@ pub(crate) trait BindInsteadOfMap {
const GOOD_METHOD_NAME: &'static str;
fn no_op_msg(cx: &LateContext<'_>) -> Option<String> {
- let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
+ let variant_id = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM)?;
let item_id = cx.tcx.parent(variant_id);
Some(format!(
"using `{}.{}({})`, which is a no-op",
@@ -52,7 +52,7 @@ pub(crate) trait BindInsteadOfMap {
}
fn lint_msg(cx: &LateContext<'_>) -> Option<String> {
- let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
+ let variant_id = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM)?;
let item_id = cx.tcx.parent(variant_id);
Some(format!(
"using `{}.{}(|x| {}(y))`, which is more succinctly expressed as `{}(|x| y)`",
@@ -144,7 +144,7 @@ pub(crate) trait BindInsteadOfMap {
fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) -> bool {
if_chain! {
if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def();
- if let Ok(vid) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM);
+ if let Some(vid) = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM);
if adt.did() == cx.tcx.parent(vid);
then {} else { return false; }
}
@@ -181,7 +181,7 @@ pub(crate) trait BindInsteadOfMap {
fn is_variant(cx: &LateContext<'_>, res: Res) -> bool {
if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res {
- if let Ok(variant_id) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM) {
+ if let Some(variant_id) = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM) {
return cx.tcx.parent(id) == variant_id;
}
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs
index fcfc25b52..89aaad359 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs
@@ -1,11 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
-use rustc_span::sym;
use super::BYTES_COUNT_TO_LEN;
@@ -20,7 +19,7 @@ pub(super) fn check<'tcx>(
if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id);
if cx.tcx.type_of(impl_id).is_str();
let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs();
- if ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String);
+ if ty.is_str() || is_type_lang_item(cx, ty, hir::LangItem::String);
then {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs b/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
index 2e96346be..d512cc4ee 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
@@ -1,10 +1,9 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use rustc_errors::Applicability;
-use rustc_hir::Expr;
+use rustc_hir::{Expr, LangItem};
use rustc_lint::LateContext;
-use rustc_span::sym;
use super::BYTES_NTH;
@@ -12,7 +11,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
let ty = cx.typeck_results().expr_ty(recv).peel_refs();
let caller_type = if ty.is_str() {
"str"
- } else if is_type_diagnostic_item(cx, ty, sym::String) {
+ } else if is_type_lang_item(cx, ty, LangItem::String) {
"String"
} else {
return;
diff --git a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
index b3c2c7c9a..d226c0bba 100644
--- a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
@@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::LateContext;
-use rustc_span::{source_map::Spanned, symbol::sym, Span};
+use rustc_span::{source_map::Spanned, Span};
use super::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS;
@@ -26,7 +26,7 @@ pub(super) fn check<'tcx>(
if ext_str.chars().skip(1).all(|c| c.is_uppercase() || c.is_ascii_digit())
|| ext_str.chars().skip(1).all(|c| c.is_lowercase() || c.is_ascii_digit());
let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs();
- if recv_ty.is_str() || is_type_diagnostic_item(cx, recv_ty, sym::String);
+ if recv_ty.is_str() || is_type_lang_item(cx, recv_ty, LangItem::String);
then {
span_lint_and_help(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
index 7e8087606..27a05337a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
@@ -9,8 +9,8 @@ use rustc_lint::LateContext;
use rustc_lint::Lint;
/// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints with `unwrap()`.
-pub(super) fn check<'tcx>(
- cx: &LateContext<'tcx>,
+pub(super) fn check(
+ cx: &LateContext<'_>,
info: &crate::methods::BinaryExprInfo<'_>,
chain_methods: &[&str],
lint: &'static Lint,
diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_last_cmp.rs b/src/tools/clippy/clippy_lints/src/methods/chars_last_cmp.rs
index 07bbc5ca1..2efff4c3c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/chars_last_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/chars_last_cmp.rs
@@ -4,7 +4,7 @@ use rustc_lint::LateContext;
use super::CHARS_LAST_CMP;
/// Checks for the `CHARS_LAST_CMP` lint.
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
if chars_cmp::check(cx, info, &["chars", "last"], CHARS_LAST_CMP, "ends_with") {
true
} else {
diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs
index c29ee0ec8..5b8713f7d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs
@@ -4,7 +4,7 @@ use rustc_lint::LateContext;
use super::CHARS_LAST_CMP;
/// Checks for the `CHARS_LAST_CMP` lint with `unwrap()`.
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
if chars_cmp_with_unwrap::check(cx, info, &["chars", "last", "unwrap"], CHARS_LAST_CMP, "ends_with") {
true
} else {
diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_next_cmp.rs b/src/tools/clippy/clippy_lints/src/methods/chars_next_cmp.rs
index a6701d883..b631fecab 100644
--- a/src/tools/clippy/clippy_lints/src/methods/chars_next_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/chars_next_cmp.rs
@@ -3,6 +3,6 @@ use rustc_lint::LateContext;
use super::CHARS_NEXT_CMP;
/// Checks for the `CHARS_NEXT_CMP` lint.
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
crate::methods::chars_cmp::check(cx, info, &["chars", "next"], CHARS_NEXT_CMP, "starts_with")
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs
index 28ede28e9..caf21d3ff 100644
--- a/src/tools/clippy/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs
@@ -3,6 +3,6 @@ use rustc_lint::LateContext;
use super::CHARS_NEXT_CMP;
/// Checks for the `CHARS_NEXT_CMP` lint with `unwrap()`.
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
crate::methods::chars_cmp_with_unwrap::check(cx, info, &["chars", "next", "unwrap"], CHARS_NEXT_CMP, "starts_with")
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs b/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
index e9aeab2d5..4e6ec61f6 100644
--- a/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
@@ -1,25 +1,25 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_trait_method;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::{get_iterator_item_ty, is_copy};
-use clippy_utils::{is_trait_method, meets_msrv, msrvs};
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty;
-use rustc_semver::RustcVersion;
use rustc_span::{sym, Span};
use super::CLONED_INSTEAD_OF_COPIED;
-pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: Option<RustcVersion>) {
+pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: &Msrv) {
let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
let inner_ty = match recv_ty.kind() {
// `Option<T>` -> `T`
ty::Adt(adt, subst)
- if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && meets_msrv(msrv, msrvs::OPTION_COPIED) =>
+ if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && msrv.meets(msrvs::OPTION_COPIED) =>
{
subst.type_at(0)
},
- _ if is_trait_method(cx, expr, sym::Iterator) && meets_msrv(msrv, msrvs::ITERATOR_COPIED) => {
+ _ if is_trait_method(cx, expr, sym::Iterator) && msrv.meets(msrvs::ITERATOR_COPIED) => {
match get_iterator_item_ty(cx, recv_ty) {
// <T as Iterator>::Item
Some(ty) => ty,
diff --git a/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs b/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs
index 501646863..ac61b4377 100644
--- a/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs
@@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(
// If the parent node's `to` argument is the same as the `to` argument
// of the last replace call in the current chain, don't lint as it was already linted
if let Some(parent) = get_parent_expr(cx, expr)
- && let Some(("replace", _, [current_from, current_to], _)) = method_call(parent)
+ && let Some(("replace", _, [current_from, current_to], _, _)) = method_call(parent)
&& eq_expr_value(cx, to, current_to)
&& from_kind == cx.typeck_results().expr_ty(current_from).peel_refs().kind()
{
@@ -48,7 +48,7 @@ fn collect_replace_calls<'tcx>(
let mut from_args = VecDeque::new();
let _: Option<()> = for_each_expr(expr, |e| {
- if let Some(("replace", _, [from, to], _)) = method_call(e) {
+ if let Some(("replace", _, [from, to], _, _)) = method_call(e) {
if eq_expr_value(cx, to_arg, to) && cx.typeck_results().expr_ty(from).peel_refs().is_char() {
methods.push_front(e);
from_args.push_front(from);
@@ -78,7 +78,7 @@ fn check_consecutive_replace_calls<'tcx>(
.collect();
let app = Applicability::MachineApplicable;
let earliest_replace_call = replace_methods.methods.front().unwrap();
- if let Some((_, _, [..], span_lo)) = method_call(earliest_replace_call) {
+ if let Some((_, _, [..], span_lo, _)) = method_call(earliest_replace_call) {
span_lint_and_sugg(
cx,
COLLAPSIBLE_STR_REPLACE,
diff --git a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
index 720d9a68c..ae03da0d3 100644
--- a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
@@ -1,27 +1,27 @@
use super::ERR_EXPECT;
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::has_debug_impl;
-use clippy_utils::{meets_msrv, msrvs, ty::is_type_diagnostic_item};
+use clippy_utils::ty::is_type_diagnostic_item;
use rustc_errors::Applicability;
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_middle::ty::Ty;
-use rustc_semver::RustcVersion;
use rustc_span::{sym, Span};
pub(super) fn check(
cx: &LateContext<'_>,
_expr: &rustc_hir::Expr<'_>,
recv: &rustc_hir::Expr<'_>,
- msrv: Option<RustcVersion>,
expect_span: Span,
err_span: Span,
+ msrv: &Msrv,
) {
if_chain! {
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
// Test the version to make sure the lint can be showed (expect_err has been
// introduced in rust 1.17.0 : https://github.com/rust-lang/rust/pull/38982)
- if meets_msrv(msrv, msrvs::EXPECT_ERR);
+ if msrv.meets(msrvs::EXPECT_ERR);
// Grabs the `Result<T, E>` type
let result_type = cx.typeck_results().expr_ty(recv);
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 d0cf411df..a9189b31c 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
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn};
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
@@ -33,7 +33,7 @@ pub(super) fn check<'tcx>(
if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && {
let arg_type = cx.typeck_results().expr_ty(receiver);
let base_type = arg_type.peel_refs();
- *base_type.kind() == ty::Str || is_type_diagnostic_item(cx, base_type, sym::String)
+ *base_type.kind() == ty::Str || is_type_lang_item(cx, base_type, hir::LangItem::String)
} {
receiver
} else {
@@ -50,7 +50,7 @@ pub(super) fn check<'tcx>(
// converted to string.
fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
let arg_ty = cx.typeck_results().expr_ty(arg);
- if is_type_diagnostic_item(cx, arg_ty, sym::String) {
+ if is_type_lang_item(cx, arg_ty, hir::LangItem::String) {
return false;
}
if let ty::Ref(_, ty, ..) = arg_ty.kind() {
diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_used.rs b/src/tools/clippy/clippy_lints/src/methods/expect_used.rs
index d59fefa1d..cce8f797e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/expect_used.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/expect_used.rs
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::is_in_test_function;
+use clippy_utils::is_in_cfg_test;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_hir as hir;
use rustc_lint::LateContext;
@@ -18,16 +18,16 @@ pub(super) fn check(
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) && !is_err {
- Some((EXPECT_USED, "an Option", "None", ""))
+ Some((EXPECT_USED, "an `Option`", "None", ""))
} else if is_type_diagnostic_item(cx, obj_ty, sym::Result) {
- Some((EXPECT_USED, "a Result", if is_err { "Ok" } else { "Err" }, "an "))
+ Some((EXPECT_USED, "a `Result`", if is_err { "Ok" } else { "Err" }, "an "))
} else {
None
};
let method = if is_err { "expect_err" } else { "expect" };
- if allow_expect_in_tests && is_in_test_function(cx.tcx, expr.hir_id) {
+ if allow_expect_in_tests && is_in_cfg_test(cx.tcx, expr.hir_id) {
return;
}
@@ -36,7 +36,7 @@ pub(super) fn check(
cx,
lint,
expr.span,
- &format!("used `{method}()` on `{kind}` value"),
+ &format!("used `{method}()` on {kind} value"),
None,
&format!("if this value is {none_prefix}`{none_value}`, it will panic"),
);
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
index 9719b2f1c..f888c58a7 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
@@ -17,7 +17,7 @@ use super::MANUAL_FILTER_MAP;
use super::MANUAL_FIND_MAP;
use super::OPTION_FILTER_MAP;
-fn is_method<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Symbol) -> bool {
+fn is_method(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol) -> bool {
match &expr.kind {
hir::ExprKind::Path(QPath::TypeRelative(_, mname)) => mname.ident.name == method_name,
hir::ExprKind::Path(QPath::Resolved(_, segments)) => {
@@ -46,7 +46,7 @@ fn is_method<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Sy
}
}
-fn is_option_filter_map<'tcx>(cx: &LateContext<'tcx>, filter_arg: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) -> bool {
+fn is_option_filter_map(cx: &LateContext<'_>, filter_arg: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) -> bool {
is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_some))
}
@@ -66,8 +66,8 @@ fn is_filter_some_map_unwrap(
/// lint use of `filter().map()` or `find().map()` for `Iterators`
#[allow(clippy::too_many_arguments)]
-pub(super) fn check<'tcx>(
- cx: &LateContext<'tcx>,
+pub(super) fn check(
+ cx: &LateContext<'_>,
expr: &hir::Expr<'_>,
filter_recv: &hir::Expr<'_>,
filter_arg: &hir::Expr<'_>,
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs
index ddf8a1f09..175e04f8a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs
@@ -1,10 +1,10 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
+use clippy_utils::is_trait_method;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
-use clippy_utils::{is_trait_method, meets_msrv, msrvs};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
-use rustc_semver::RustcVersion;
use rustc_span::sym;
use super::FILTER_MAP_NEXT;
@@ -14,10 +14,10 @@ pub(super) fn check<'tcx>(
expr: &'tcx hir::Expr<'_>,
recv: &'tcx hir::Expr<'_>,
arg: &'tcx hir::Expr<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) {
if is_trait_method(cx, expr, sym::Iterator) {
- if !meets_msrv(msrv, msrvs::ITERATOR_FIND_MAP) {
+ if !msrv.meets(msrvs::ITERATOR_FIND_MAP) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
index ede3b8bb7..d8c821bc9 100644
--- a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
@@ -1,19 +1,19 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::{is_type_diagnostic_item, walk_ptrs_ty_depth};
+use clippy_utils::ty::{is_type_lang_item, walk_ptrs_ty_depth};
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{Symbol, sym};
use super::INEFFICIENT_TO_STRING;
/// Checks for the `INEFFICIENT_TO_STRING` lint
-pub fn check<'tcx>(
- cx: &LateContext<'tcx>,
+pub fn check(
+ cx: &LateContext<'_>,
expr: &hir::Expr<'_>,
method_name: Symbol,
receiver: &hir::Expr<'_>,
@@ -60,7 +60,7 @@ fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
return true;
}
- if is_type_diagnostic_item(cx, ty, sym::String) {
+ if is_type_lang_item(cx, ty, hir::LangItem::String) {
return true;
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs b/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
index 304024e80..301aff5ae 100644
--- a/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
@@ -1,23 +1,22 @@
//! Lint for `c.is_digit(10)`
use super::IS_DIGIT_ASCII_RADIX;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::{
- consts::constant_full_int, consts::FullInt, diagnostics::span_lint_and_sugg, meets_msrv, msrvs,
- source::snippet_with_applicability,
+ consts::constant_full_int, consts::FullInt, diagnostics::span_lint_and_sugg, source::snippet_with_applicability,
};
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
-use rustc_semver::RustcVersion;
pub(super) fn check<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx Expr<'_>,
self_arg: &'tcx Expr<'_>,
radix: &'tcx Expr<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) {
- if !meets_msrv(msrv, msrvs::IS_ASCII_DIGIT) {
+ if !msrv.meets(msrvs::IS_ASCII_DIGIT) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_nth_zero.rs b/src/tools/clippy/clippy_lints/src/methods/iter_nth_zero.rs
index 68d906c3e..c830958d5 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_nth_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_nth_zero.rs
@@ -10,7 +10,7 @@ use rustc_span::sym;
use super::ITER_NTH_ZERO;
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
if_chain! {
if is_trait_method(cx, expr, sym::Iterator);
if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), arg);
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
index 4f73b3ec4..70abe4891 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
@@ -25,7 +25,7 @@ impl IterType {
}
}
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) {
let item = match recv.kind {
ExprKind::Array([]) => None,
ExprKind::Array([e]) => Some(e),
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 06a39c599..b4210d875 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,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{get_associated_type, implements_trait, is_copy};
+use clippy_utils::ty::{implements_trait, is_copy};
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
@@ -25,7 +25,7 @@ pub(super) fn check<'tcx>(
&& let Some(method_id) = typeck.type_dependent_def_id(cloned_call.hir_id)
&& cx.tcx.trait_of_item(method_id) == Some(iter_id)
&& let cloned_recv_ty = typeck.expr_ty_adjusted(cloned_recv)
- && let Some(iter_assoc_ty) = get_associated_type(cx, cloned_recv_ty, iter_id, "Item")
+ && let Some(iter_assoc_ty) = cx.get_associated_type(cloned_recv_ty, iter_id, "Item")
&& matches!(*iter_assoc_ty.kind(), ty::Ref(_, ty, _) if !is_copy(cx, ty))
{
if needs_into_iter
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs
index b80541b86..a7284c644 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs
@@ -67,7 +67,7 @@ enum MinMax {
Max,
}
-fn is_min_or_max<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) -> Option<MinMax> {
+fn is_min_or_max(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<MinMax> {
// `T::max_value()` `T::min_value()` inherent methods
if_chain! {
if let hir::ExprKind::Call(func, args) = &expr.kind;
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs b/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs
index 8b6b8f1bf..a08f72540 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs
@@ -36,14 +36,14 @@ fn parse_repeat_arg(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<RepeatKind> {
}
} else {
let ty = cx.typeck_results().expr_ty(e);
- if is_type_diagnostic_item(cx, ty, sym::String)
+ if is_type_lang_item(cx, ty, LangItem::String)
|| (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).map_or(false, Ty::is_str))
|| (is_type_diagnostic_item(cx, ty, sym::Cow) && get_ty_param(ty).map_or(false, Ty::is_str))
{
Some(RepeatKind::String)
} else {
let ty = ty.peel_refs();
- (ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String)).then_some(RepeatKind::String)
+ (ty.is_str() || is_type_lang_item(cx, ty, LangItem::String)).then_some(RepeatKind::String)
}
}
}
@@ -58,11 +58,9 @@ pub(super) fn check(
if_chain! {
if let ExprKind::Call(repeat_fn, [repeat_arg]) = take_self_arg.kind;
if is_path_diagnostic_item(cx, repeat_fn, sym::iter_repeat);
- if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(collect_expr), sym::String);
- if let Some(collect_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id);
+ if is_type_lang_item(cx, cx.typeck_results().expr_ty(collect_expr), LangItem::String);
if let Some(take_id) = cx.typeck_results().type_dependent_def_id(take_expr.hir_id);
if let Some(iter_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
- if cx.tcx.trait_of_item(collect_id) == Some(iter_trait_id);
if cx.tcx.trait_of_item(take_id) == Some(iter_trait_id);
if let Some(repeat_kind) = parse_repeat_arg(cx, repeat_arg);
let ctxt = collect_expr.span.ctxt();
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
index 7ce14ec08..52cc1e046 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
@@ -1,7 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
-use clippy_utils::{is_diag_trait_item, meets_msrv, msrvs, peel_blocks};
+use clippy_utils::{is_diag_trait_item, peel_blocks};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
@@ -9,19 +10,12 @@ use rustc_lint::LateContext;
use rustc_middle::mir::Mutability;
use rustc_middle::ty;
use rustc_middle::ty::adjustment::Adjust;
-use rustc_semver::RustcVersion;
use rustc_span::symbol::Ident;
use rustc_span::{sym, Span};
use super::MAP_CLONE;
-pub(super) fn check<'tcx>(
- cx: &LateContext<'_>,
- e: &hir::Expr<'_>,
- recv: &hir::Expr<'_>,
- arg: &'tcx hir::Expr<'_>,
- msrv: Option<RustcVersion>,
-) {
+pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>, msrv: &Msrv) {
if_chain! {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id);
if cx.tcx.impl_of_method(method_id)
@@ -97,10 +91,10 @@ fn lint_needless_cloning(cx: &LateContext<'_>, root: Span, receiver: Span) {
);
}
-fn lint_explicit_closure(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool, msrv: Option<RustcVersion>) {
+fn lint_explicit_closure(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool, msrv: &Msrv) {
let mut applicability = Applicability::MachineApplicable;
- let (message, sugg_method) = if is_copy && meets_msrv(msrv, msrvs::ITERATOR_COPIED) {
+ let (message, sugg_method) = if is_copy && msrv.meets(msrvs::ITERATOR_COPIED) {
("you are using an explicit closure for copying elements", "copied")
} else {
("you are using an explicit closure for cloning elements", "cloned")
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs b/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs
index d420f144e..a0300d278 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs
@@ -1,5 +1,4 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_trait_method;
use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item;
use if_chain::if_chain;
@@ -11,18 +10,10 @@ use rustc_span::symbol::sym;
use super::MAP_COLLECT_RESULT_UNIT;
-pub(super) fn check(
- cx: &LateContext<'_>,
- expr: &hir::Expr<'_>,
- iter: &hir::Expr<'_>,
- map_fn: &hir::Expr<'_>,
- collect_recv: &hir::Expr<'_>,
-) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, iter: &hir::Expr<'_>, map_fn: &hir::Expr<'_>) {
+ // return of collect `Result<(),_>`
+ let collect_ret_ty = cx.typeck_results().expr_ty(expr);
if_chain! {
- // called on Iterator
- if is_trait_method(cx, collect_recv, sym::Iterator);
- // return of collect `Result<(),_>`
- let collect_ret_ty = cx.typeck_results().expr_ty(expr);
if is_type_diagnostic_item(cx, collect_ret_ty, sym::Result);
if let ty::Adt(_, substs) = collect_ret_ty.kind();
if let Some(result_t) = substs.types().next();
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs
index 1fb661714..b773b3e42 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs
@@ -6,7 +6,7 @@ use rustc_span::sym;
use super::MAP_ERR_IGNORE;
-pub(super) fn check<'tcx>(cx: &LateContext<'_>, e: &Expr<'_>, arg: &'tcx Expr<'_>) {
+pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, arg: &Expr<'_>) {
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
&& let Some(impl_id) = cx.tcx.impl_of_method(method_id)
&& is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Result)
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs
index 74fdead21..3122f72ee 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs
@@ -1,12 +1,11 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::usage::mutated_variables;
-use clippy_utils::{meets_msrv, msrvs};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
-use rustc_semver::RustcVersion;
use rustc_span::symbol::sym;
use super::MAP_UNWRAP_OR;
@@ -19,13 +18,13 @@ pub(super) fn check<'tcx>(
recv: &'tcx hir::Expr<'_>,
map_arg: &'tcx hir::Expr<'_>,
unwrap_arg: &'tcx hir::Expr<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) -> bool {
// lint if the caller of `map()` is an `Option`
let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option);
let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
- if is_result && !meets_msrv(msrv, msrvs::RESULT_MAP_OR_ELSE) {
+ if is_result && !msrv.meets(msrvs::RESULT_MAP_OR_ELSE) {
return false;
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 8a76ba0b0..d2913680c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -54,6 +54,7 @@ mod map_flatten;
mod map_identity;
mod map_unwrap_or;
mod mut_mutex_lock;
+mod needless_collect;
mod needless_option_as_deref;
mod needless_option_take;
mod no_effect_replace;
@@ -69,6 +70,8 @@ mod path_buf_push_overwrite;
mod range_zip_with_len;
mod repeat_once;
mod search_is_some;
+mod seek_from_current;
+mod seek_to_start_instead_of_rewind;
mod single_char_add_str;
mod single_char_insert_string;
mod single_char_pattern;
@@ -101,17 +104,16 @@ mod zst_offset;
use bind_instead_of_map::BindInsteadOfMap;
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
-use clippy_utils::ty::{contains_adt_constructor, implements_trait, is_copy, is_type_diagnostic_item};
-use clippy_utils::{contains_return, is_trait_method, iter_input_pats, meets_msrv, msrvs, return_ty};
+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, return_ty};
use if_chain::if_chain;
use rustc_hir as hir;
-use rustc_hir::def::Res;
-use rustc_hir::{Expr, ExprKind, PrimTy, QPath, TraitItem, TraitItemKind};
+use rustc_hir::{Expr, ExprKind, 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};
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{sym, Span};
@@ -156,9 +158,9 @@ declare_clippy_lint! {
/// ```
/// Use instead:
/// ```rust
- /// let hello = "hesuo worpd".replace(&['s', 'u', 'p'], "l");
+ /// let hello = "hesuo worpd".replace(['s', 'u', 'p'], "l");
/// ```
- #[clippy::version = "1.64.0"]
+ #[clippy::version = "1.65.0"]
pub COLLAPSIBLE_STR_REPLACE,
perf,
"collapse consecutive calls to str::replace (2 or more) into a single call"
@@ -829,32 +831,30 @@ declare_clippy_lint! {
/// etc. instead.
///
/// ### Why is this bad?
- /// The function will always be called and potentially
- /// allocate an object acting as the default.
+ /// The function will always be called. This is only bad if it allocates or
+ /// does some non-trivial amount of work.
///
/// ### Known problems
- /// If the function has side-effects, not calling it will
- /// change the semantic of the program, but you shouldn't rely on that anyway.
+ /// If the function has side-effects, not calling it will change the
+ /// semantic of the program, but you shouldn't rely on that.
+ ///
+ /// The lint also cannot figure out whether the function you call is
+ /// actually expensive to call or not.
///
/// ### Example
/// ```rust
/// # let foo = Some(String::new());
- /// foo.unwrap_or(String::new());
+ /// foo.unwrap_or(String::from("empty"));
/// ```
///
/// Use instead:
/// ```rust
/// # let foo = Some(String::new());
- /// foo.unwrap_or_else(String::new);
- ///
- /// // or
- ///
- /// # let foo = Some(String::new());
- /// foo.unwrap_or_default();
+ /// foo.unwrap_or_else(|| String::from("empty"));
/// ```
#[clippy::version = "pre 1.29.0"]
pub OR_FUN_CALL,
- perf,
+ nursery,
"using any `*or` method with a function call, which suggests `*or_else`"
}
@@ -1728,7 +1728,7 @@ declare_clippy_lint! {
declare_clippy_lint! {
/// ### What it does
- /// Checks for usage of `_.as_ref().map(Deref::deref)` or it's aliases (such as String::as_str).
+ /// Checks for usage of `_.as_ref().map(Deref::deref)` or its aliases (such as String::as_str).
///
/// ### Why is this bad?
/// Readability, this can be written more concisely as
@@ -2094,8 +2094,7 @@ declare_clippy_lint! {
/// let s = "Hello world!";
/// let cow = Cow::Borrowed(s);
///
- /// let data = cow.into_owned();
- /// assert!(matches!(data, String))
+ /// let _data: String = cow.into_owned();
/// ```
#[clippy::version = "1.65.0"]
pub SUSPICIOUS_TO_OWNED,
@@ -2426,7 +2425,7 @@ declare_clippy_lint! {
/// ### Known problems
///
/// The type of the resulting iterator might become incompatible with its usage
- #[clippy::version = "1.64.0"]
+ #[clippy::version = "1.65.0"]
pub ITER_ON_SINGLE_ITEMS,
nursery,
"Iterator for array of length 1"
@@ -2458,7 +2457,7 @@ declare_clippy_lint! {
/// ### Known problems
///
/// The type of the resulting iterator might become incompatible with its usage
- #[clippy::version = "1.64.0"]
+ #[clippy::version = "1.65.0"]
pub ITER_ON_EMPTY_COLLECTIONS,
nursery,
"Iterator for empty array"
@@ -3066,9 +3065,105 @@ declare_clippy_lint! {
"iterating on map using `iter` when `keys` or `values` would do"
}
+declare_clippy_lint! {
+ /// ### What it does
+ ///
+ /// Checks an argument of `seek` method of `Seek` trait
+ /// and if it start seek from `SeekFrom::Current(0)`, suggests `stream_position` instead.
+ ///
+ /// ### Why is this bad?
+ ///
+ /// Readability. Use dedicated method.
+ ///
+ /// ### Example
+ ///
+ /// ```rust,no_run
+ /// use std::fs::File;
+ /// use std::io::{self, Write, Seek, SeekFrom};
+ ///
+ /// fn main() -> io::Result<()> {
+ /// let mut f = File::create("foo.txt")?;
+ /// f.write_all(b"Hello")?;
+ /// eprintln!("Written {} bytes", f.seek(SeekFrom::Current(0))?);
+ ///
+ /// Ok(())
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust,no_run
+ /// use std::fs::File;
+ /// use std::io::{self, Write, Seek, SeekFrom};
+ ///
+ /// fn main() -> io::Result<()> {
+ /// let mut f = File::create("foo.txt")?;
+ /// f.write_all(b"Hello")?;
+ /// eprintln!("Written {} bytes", f.stream_position()?);
+ ///
+ /// Ok(())
+ /// }
+ /// ```
+ #[clippy::version = "1.66.0"]
+ pub SEEK_FROM_CURRENT,
+ complexity,
+ "use dedicated method for seek from current position"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ ///
+ /// Checks for jumps to the start of a stream that implements `Seek`
+ /// and uses the `seek` method providing `Start` as parameter.
+ ///
+ /// ### Why is this bad?
+ ///
+ /// Readability. There is a specific method that was implemented for
+ /// this exact scenario.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # use std::io;
+ /// fn foo<T: io::Seek>(t: &mut T) {
+ /// t.seek(io::SeekFrom::Start(0));
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// # use std::io;
+ /// fn foo<T: io::Seek>(t: &mut T) {
+ /// t.rewind();
+ /// }
+ /// ```
+ #[clippy::version = "1.66.0"]
+ pub SEEK_TO_START_INSTEAD_OF_REWIND,
+ complexity,
+ "jumping to the start of stream using `seek` method"
+}
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for functions collecting an iterator when collect
+ /// is not needed.
+ ///
+ /// ### Why is this bad?
+ /// `collect` causes the allocation of a new data structure,
+ /// when this allocation may not be needed.
+ ///
+ /// ### Example
+ /// ```rust
+ /// # let iterator = vec![1].into_iter();
+ /// let len = iterator.clone().collect::<Vec<_>>().len();
+ /// // should be
+ /// let len = iterator.count();
+ /// ```
+ #[clippy::version = "1.30.0"]
+ pub NEEDLESS_COLLECT,
+ nursery,
+ "collecting an iterator when collect is not needed"
+}
+
pub struct Methods {
avoid_breaking_exported_api: bool,
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
allow_expect_in_tests: bool,
allow_unwrap_in_tests: bool,
}
@@ -3077,7 +3172,7 @@ impl Methods {
#[must_use]
pub fn new(
avoid_breaking_exported_api: bool,
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
allow_expect_in_tests: bool,
allow_unwrap_in_tests: bool,
) -> Self {
@@ -3190,16 +3285,19 @@ impl_lint_pass!(Methods => [
VEC_RESIZE_TO_ZERO,
VERBOSE_FILE_READS,
ITER_KV_MAP,
+ SEEK_FROM_CURRENT,
+ SEEK_TO_START_INSTEAD_OF_REWIND,
+ NEEDLESS_COLLECT,
]);
/// Extracts a method call name, args, and `Span` of the method name.
fn method_call<'tcx>(
recv: &'tcx hir::Expr<'tcx>,
-) -> Option<(&'tcx str, &'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], Span)> {
- if let ExprKind::MethodCall(path, receiver, args, _) = recv.kind {
+) -> Option<(&'tcx str, &'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], Span, Span)> {
+ if let ExprKind::MethodCall(path, receiver, args, call_span) = recv.kind {
if !args.iter().any(|e| e.span.from_expansion()) && !receiver.span.from_expansion() {
let name = path.ident.name.as_str();
- return Some((name, receiver, args, path.ident.span));
+ return Some((name, receiver, args, path.ident.span, call_span));
}
}
None
@@ -3227,7 +3325,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
single_char_add_str::check(cx, expr, receiver, args);
into_iter_on_ref::check(cx, expr, method_span, method_call.ident.name, receiver);
single_char_pattern::check(cx, expr, method_call.ident.name, receiver, args);
- unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, self.msrv);
+ unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, &self.msrv);
},
hir::ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => {
let mut info = BinaryExprInfo {
@@ -3316,36 +3414,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
if let hir::ImplItemKind::Fn(_, _) = impl_item.kind {
let ret_ty = return_ty(cx, impl_item.hir_id());
- // walk the return type and check for Self (this does not check associated types)
- if let Some(self_adt) = self_ty.ty_adt_def() {
- if contains_adt_constructor(ret_ty, self_adt) {
- return;
- }
- } else if ret_ty.contains(self_ty) {
+ if contains_ty_adt_constructor_opaque(cx, ret_ty, self_ty) {
return;
}
- // if return type is impl trait, check the associated types
- if let ty::Opaque(def_id, _) = *ret_ty.kind() {
- // one of the associated types must be Self
- for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) {
- if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
- let assoc_ty = match projection_predicate.term.unpack() {
- ty::TermKind::Ty(ty) => ty,
- ty::TermKind::Const(_c) => continue,
- };
- // walk the associated type and check for Self
- if let Some(self_adt) = self_ty.ty_adt_def() {
- if contains_adt_constructor(assoc_ty, self_adt) {
- return;
- }
- } else if assoc_ty.contains(self_ty) {
- return;
- }
- }
- }
- }
-
if name == "new" && ret_ty != self_ty {
span_lint(
cx,
@@ -3411,7 +3483,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
impl Methods {
#[allow(clippy::too_many_lines)]
fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- if let Some((name, recv, args, span)) = method_call(expr) {
+ if let Some((name, recv, args, span, call_span)) = method_call(expr) {
match (name, args) {
("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => {
zst_offset::check(cx, expr, recv);
@@ -3429,29 +3501,32 @@ impl Methods {
("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),
- ("cloned", []) => cloned_instead_of_copied::check(cx, expr, recv, span, self.msrv),
- ("collect", []) => match method_call(recv) {
- Some((name @ ("cloned" | "copied"), recv2, [], _)) => {
- iter_cloned_collect::check(cx, name, expr, recv2);
- },
- Some(("map", m_recv, [m_arg], _)) => {
- map_collect_result_unit::check(cx, expr, m_recv, m_arg, recv);
- },
- Some(("take", take_self_arg, [take_arg], _)) => {
- if meets_msrv(self.msrv, msrvs::STR_REPEAT) {
- manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg);
- }
- },
- _ => {},
+ ("cloned", []) => cloned_instead_of_copied::check(cx, expr, recv, span, &self.msrv),
+ ("collect", []) if is_trait_method(cx, expr, sym::Iterator) => {
+ needless_collect::check(cx, span, expr, recv, call_span);
+ match method_call(recv) {
+ Some((name @ ("cloned" | "copied"), recv2, [], _, _)) => {
+ iter_cloned_collect::check(cx, name, expr, recv2);
+ },
+ Some(("map", m_recv, [m_arg], _, _)) => {
+ map_collect_result_unit::check(cx, expr, m_recv, m_arg);
+ },
+ Some(("take", take_self_arg, [take_arg], _, _)) => {
+ if self.msrv.meets(msrvs::STR_REPEAT) {
+ manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg);
+ }
+ },
+ _ => {},
+ }
},
("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((name2 @ ("into_iter" | "iter" | "iter_mut"), recv2, [], _)) => {
+ Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, true, false),
+ Some((name2 @ ("into_iter" | "iter" | "iter_mut"), recv2, [], _, _)) => {
iter_count::check(cx, expr, recv2, name2);
},
- Some(("map", _, [arg], _)) => suspicious_map::check(cx, expr, recv, arg),
- Some(("filter", recv2, [arg], _)) => bytecount::check(cx, expr, recv2, arg),
- Some(("bytes", recv2, [], _)) => bytes_count_to_len::check(cx, expr, recv, recv2),
+ Some(("map", _, [arg], _, _)) => suspicious_map::check(cx, expr, recv, arg),
+ Some(("filter", recv2, [arg], _, _)) => bytecount::check(cx, expr, recv2, arg),
+ Some(("bytes", recv2, [], _, _)) => bytes_count_to_len::check(cx, expr, recv, recv2),
_ => {},
},
("drain", [arg]) => {
@@ -3463,8 +3538,8 @@ impl Methods {
}
},
("expect", [_]) => match method_call(recv) {
- Some(("ok", recv, [], _)) => ok_expect::check(cx, expr, recv),
- Some(("err", recv, [], err_span)) => err_expect::check(cx, expr, recv, self.msrv, span, err_span),
+ Some(("ok", recv, [], _, _)) => ok_expect::check(cx, expr, recv),
+ Some(("err", recv, [], err_span, _)) => err_expect::check(cx, expr, recv, span, err_span, &self.msrv),
_ => expect_used::check(cx, expr, recv, false, self.allow_expect_in_tests),
},
("expect_err", [_]) => expect_used::check(cx, expr, recv, true, self.allow_expect_in_tests),
@@ -3484,13 +3559,13 @@ impl Methods {
flat_map_option::check(cx, expr, arg, span);
},
("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(("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),
_ => {},
},
("fold", [init, acc]) => unnecessary_fold::check(cx, expr, init, acc, span),
("for_each", [_]) => {
- if let Some(("inspect", _, [_], span2)) = method_call(recv) {
+ if let Some(("inspect", _, [_], span2, _)) = method_call(recv) {
inspect_for_each::check(cx, expr, span2);
}
},
@@ -3503,19 +3578,19 @@ impl Methods {
unit_hash::check(cx, expr, recv, arg);
},
("is_file", []) => filetype_is_file::check(cx, expr, recv),
- ("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, self.msrv),
+ ("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, &self.msrv),
("is_none", []) => check_is_some_is_none(cx, expr, recv, false),
("is_some", []) => check_is_some_is_none(cx, expr, recv, true),
("iter" | "iter_mut" | "into_iter", []) => {
iter_on_single_or_empty_collections::check(cx, expr, name, recv);
},
("join", [join_arg]) => {
- if let Some(("collect", _, _, span)) = method_call(recv) {
+ if let Some(("collect", _, _, span, _)) = method_call(recv) {
unnecessary_join::check(cx, expr, recv, join_arg, span);
}
},
("last", []) | ("skip", [_]) => {
- if let Some((name2, recv2, args2, _span2)) = method_call(recv) {
+ if let Some((name2, recv2, args2, _span2, _)) = method_call(recv) {
if let ("cloned", []) = (name2, args2) {
iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
}
@@ -3526,17 +3601,17 @@ 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) {
+ 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);
}
} else {
map_err_ignore::check(cx, expr, m_arg);
}
- if let Some((name, recv2, args, span2)) = method_call(recv) {
+ if let Some((name, recv2, args, span2,_)) = method_call(recv) {
match (name, args) {
- ("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, self.msrv),
- ("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, self.msrv),
+ ("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, &self.msrv),
+ ("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, &self.msrv),
("filter", [f_arg]) => {
filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, false);
},
@@ -3553,11 +3628,11 @@ impl Methods {
manual_ok_or::check(cx, expr, recv, def, map);
},
("next", []) => {
- if let Some((name2, recv2, args2, _)) = method_call(recv) {
+ if let Some((name2, recv2, args2, _, _)) = method_call(recv) {
match (name2, args2) {
("cloned", []) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
("filter", [arg]) => filter_next::check(cx, expr, recv2, arg),
- ("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, self.msrv),
+ ("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, &self.msrv),
("iter", []) => iter_next_slice::check(cx, expr, recv2),
("skip", [arg]) => iter_skip_next::check(cx, expr, recv2, arg),
("skip_while", [_]) => skip_while_next::check(cx, expr),
@@ -3566,10 +3641,10 @@ 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(("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),
+ 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(("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),
},
("ok_or_else", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or"),
@@ -3604,6 +3679,14 @@ impl Methods {
("resize", [count_arg, default_arg]) => {
vec_resize_to_zero::check(cx, expr, count_arg, default_arg, span);
},
+ ("seek", [arg]) => {
+ if self.msrv.meets(msrvs::SEEK_FROM_CURRENT) {
+ seek_from_current::check(cx, expr, recv, arg);
+ }
+ if self.msrv.meets(msrvs::SEEK_REWIND) {
+ seek_to_start_instead_of_rewind::check(cx, expr, recv, arg, span);
+ }
+ },
("sort", []) => {
stable_sort_primitive::check(cx, expr, recv);
},
@@ -3616,7 +3699,7 @@ impl Methods {
("splitn" | "rsplitn", [count_arg, pat_arg]) => {
if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) {
suspicious_splitn::check(cx, name, expr, recv, count);
- str_splitn::check(cx, name, expr, recv, pat_arg, count, self.msrv);
+ str_splitn::check(cx, name, expr, recv, pat_arg, count, &self.msrv);
}
},
("splitn_mut" | "rsplitn_mut", [count_arg, _]) => {
@@ -3626,7 +3709,7 @@ impl Methods {
},
("step_by", [arg]) => iterator_step_by_zero::check(cx, expr, arg),
("take", [_arg]) => {
- if let Some((name2, recv2, args2, _span2)) = method_call(recv) {
+ if let Some((name2, recv2, args2, _span2, _)) = method_call(recv) {
if let ("cloned", []) = (name2, args2) {
iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
}
@@ -3634,7 +3717,7 @@ impl Methods {
},
("take", []) => needless_option_take::check(cx, expr, recv),
("then", [arg]) => {
- if !meets_msrv(self.msrv, msrvs::BOOL_THEN_SOME) {
+ if !self.msrv.meets(msrvs::BOOL_THEN_SOME) {
return;
}
unnecessary_lazy_eval::check(cx, expr, recv, arg, "then_some");
@@ -3649,13 +3732,13 @@ impl Methods {
},
("unwrap", []) => {
match method_call(recv) {
- Some(("get", recv, [get_arg], _)) => {
+ Some(("get", recv, [get_arg], _, _)) => {
get_unwrap::check(cx, expr, recv, get_arg, false);
},
- Some(("get_mut", recv, [get_arg], _)) => {
+ Some(("get_mut", recv, [get_arg], _, _)) => {
get_unwrap::check(cx, expr, recv, get_arg, true);
},
- Some(("or", recv, [or_arg], or_span)) => {
+ Some(("or", recv, [or_arg], or_span, _)) => {
or_then_unwrap::check(cx, expr, recv, or_arg, or_span);
},
_ => {},
@@ -3664,20 +3747,20 @@ impl Methods {
},
("unwrap_err", []) => unwrap_used::check(cx, expr, recv, true, self.allow_unwrap_in_tests),
("unwrap_or", [u_arg]) => match method_call(recv) {
- Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), lhs, [rhs], _)) => {
+ Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), lhs, [rhs], _, _)) => {
manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, &arith["checked_".len()..]);
},
- Some(("map", m_recv, [m_arg], span)) => {
+ Some(("map", m_recv, [m_arg], span, _)) => {
option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span);
},
- Some(("then_some", t_recv, [t_arg], _)) => {
+ Some(("then_some", t_recv, [t_arg], _, _)) => {
obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg);
},
_ => {},
},
("unwrap_or_else", [u_arg]) => match method_call(recv) {
- Some(("map", recv, [map_arg], _))
- if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, self.msrv) => {},
+ Some(("map", recv, [map_arg], _, _))
+ if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, &self.msrv) => {},
_ => {
unwrap_or_else_default::check(cx, expr, recv, u_arg);
unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or");
@@ -3697,7 +3780,7 @@ impl Methods {
}
fn check_is_some_is_none(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, is_some: bool) {
- if let Some((name @ ("find" | "position" | "rposition"), f_recv, [arg], span)) = method_call(recv) {
+ if let Some((name @ ("find" | "position" | "rposition"), f_recv, [arg], span, _)) = method_call(recv) {
search_is_some::check(cx, expr, name, is_some, f_recv, arg, recv, span);
}
}
@@ -3906,14 +3989,6 @@ impl OutType {
}
}
-fn is_bool(ty: &hir::Ty<'_>) -> bool {
- if let hir::TyKind::Path(QPath::Resolved(_, path)) = ty.kind {
- matches!(path.res, Res::PrimTy(PrimTy::Bool))
- } else {
- false
- }
-}
-
fn fn_header_equals(expected: hir::FnHeader, actual: hir::FnHeader) -> bool {
expected.constness == actual.constness
&& expected.unsafety == actual.unsafety
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index 66f9e2859..b088e642e 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -3,94 +3,99 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
use clippy_utils::higher;
use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{can_move_expr_to_closure, is_trait_method, path_to_local, path_to_local_id, CaptureKind};
-use if_chain::if_chain;
+use clippy_utils::ty::{is_type_diagnostic_item, make_normalized_projection, make_projection};
+use clippy_utils::{
+ can_move_expr_to_closure, get_enclosing_block, get_parent_node, is_trait_method, path_to_local, path_to_local_id,
+ CaptureKind,
+};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, MultiSpan};
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
-use rustc_hir::{Block, Expr, ExprKind, HirId, HirIdSet, Local, Mutability, Node, PatKind, Stmt, StmtKind};
+use rustc_hir::{
+ BindingAnnotation, Block, Expr, ExprKind, HirId, HirIdSet, Local, Mutability, Node, PatKind, Stmt, StmtKind,
+};
use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::{self, Ty};
-use rustc_span::sym;
-use rustc_span::Span;
+use rustc_middle::ty::{self, AssocKind, EarlyBinder, GenericArg, GenericArgKind, Ty};
+use rustc_span::symbol::Ident;
+use rustc_span::{sym, Span, Symbol};
const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed";
-pub(super) fn check<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
- check_needless_collect_direct_usage(expr, cx);
- check_needless_collect_indirect_usage(expr, cx);
-}
-fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
- if_chain! {
- if let ExprKind::MethodCall(method, receiver, args, _) = expr.kind;
- if let ExprKind::MethodCall(chain_method, ..) = receiver.kind;
- if chain_method.ident.name == sym!(collect) && is_trait_method(cx, receiver, sym::Iterator);
- then {
- let ty = cx.typeck_results().expr_ty(receiver);
- let mut applicability = Applicability::MaybeIncorrect;
- let is_empty_sugg = "next().is_none()".to_string();
- let method_name = method.ident.name.as_str();
- let sugg = if is_type_diagnostic_item(cx, ty, sym::Vec) ||
- is_type_diagnostic_item(cx, ty, sym::VecDeque) ||
- is_type_diagnostic_item(cx, ty, sym::LinkedList) ||
- is_type_diagnostic_item(cx, ty, sym::BinaryHeap) {
- match method_name {
- "len" => "count()".to_string(),
- "is_empty" => is_empty_sugg,
- "contains" => {
- let contains_arg = snippet_with_applicability(cx, args[0].span, "??", &mut applicability);
- let (arg, pred) = contains_arg
- .strip_prefix('&')
- .map_or(("&x", &*contains_arg), |s| ("x", s));
- format!("any(|{arg}| x == {pred})")
- }
- _ => return,
- }
- }
- else if is_type_diagnostic_item(cx, ty, sym::BTreeMap) ||
- is_type_diagnostic_item(cx, ty, sym::HashMap) {
- match method_name {
- "is_empty" => is_empty_sugg,
- _ => return,
- }
- }
- else {
- return;
- };
- span_lint_and_sugg(
- cx,
- NEEDLESS_COLLECT,
- chain_method.ident.span.with_hi(expr.span.hi()),
- NEEDLESS_COLLECT_MSG,
- "replace with",
- sugg,
- applicability,
- );
- }
- }
-}
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ name_span: Span,
+ collect_expr: &'tcx Expr<'_>,
+ iter_expr: &'tcx Expr<'tcx>,
+ call_span: Span,
+) {
+ if let Some(parent) = get_parent_node(cx.tcx, collect_expr.hir_id) {
+ match parent {
+ Node::Expr(parent) => {
+ if let ExprKind::MethodCall(name, _, args @ ([] | [_]), _) = parent.kind {
+ let mut app = Applicability::MachineApplicable;
+ let name = name.ident.as_str();
+ let collect_ty = cx.typeck_results().expr_ty(collect_expr);
-fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
- if let ExprKind::Block(block, _) = expr.kind {
- for stmt in block.stmts {
- if_chain! {
- if let StmtKind::Local(local) = stmt.kind;
- if let PatKind::Binding(_, id, ..) = local.pat.kind;
- if let Some(init_expr) = local.init;
- if let ExprKind::MethodCall(method_name, iter_source, [], ..) = init_expr.kind;
- if method_name.ident.name == sym!(collect) && is_trait_method(cx, init_expr, sym::Iterator);
- let ty = cx.typeck_results().expr_ty(init_expr);
- if is_type_diagnostic_item(cx, ty, sym::Vec) ||
- is_type_diagnostic_item(cx, ty, sym::VecDeque) ||
- is_type_diagnostic_item(cx, ty, sym::BinaryHeap) ||
- is_type_diagnostic_item(cx, ty, sym::LinkedList);
- let iter_ty = cx.typeck_results().expr_ty(iter_source);
- if let Some(iter_calls) = detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty));
- if let [iter_call] = &*iter_calls;
- then {
+ let sugg: String = match name {
+ "len" => {
+ if let Some(adt) = collect_ty.ty_adt_def()
+ && matches!(
+ cx.tcx.get_diagnostic_name(adt.did()),
+ Some(sym::Vec | sym::VecDeque | sym::LinkedList | sym::BinaryHeap)
+ )
+ {
+ "count()".into()
+ } else {
+ return;
+ }
+ },
+ "is_empty"
+ if is_is_empty_sig(cx, parent.hir_id)
+ && iterates_same_ty(cx, cx.typeck_results().expr_ty(iter_expr), collect_ty) =>
+ {
+ "next().is_none()".into()
+ },
+ "contains" => {
+ if is_contains_sig(cx, parent.hir_id, iter_expr)
+ && let Some(arg) = args.first()
+ {
+ let (span, prefix) = if let ExprKind::AddrOf(_, _, arg) = arg.kind {
+ (arg.span, "")
+ } else {
+ (arg.span, "*")
+ };
+ let snip = snippet_with_applicability(cx, span, "??", &mut app);
+ format!("any(|x| x == {prefix}{snip})")
+ } else {
+ return;
+ }
+ },
+ _ => return,
+ };
+
+ span_lint_and_sugg(
+ cx,
+ NEEDLESS_COLLECT,
+ call_span.with_hi(parent.span.hi()),
+ NEEDLESS_COLLECT_MSG,
+ "replace with",
+ sugg,
+ app,
+ );
+ }
+ },
+ Node::Local(l) => {
+ if let PatKind::Binding(BindingAnnotation::NONE | BindingAnnotation::MUT, id, _, None)
+ = l.pat.kind
+ && let ty = cx.typeck_results().expr_ty(collect_expr)
+ && [sym::Vec, sym::VecDeque, sym::BinaryHeap, sym::LinkedList].into_iter()
+ .any(|item| is_type_diagnostic_item(cx, ty, item))
+ && let iter_ty = cx.typeck_results().expr_ty(iter_expr)
+ && let Some(block) = get_enclosing_block(cx, l.hir_id)
+ && let Some(iter_calls) = detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty))
+ && let [iter_call] = &*iter_calls
+ {
let mut used_count_visitor = UsedCountVisitor {
cx,
id,
@@ -102,20 +107,20 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo
}
// Suggest replacing iter_call with iter_replacement, and removing stmt
- let mut span = MultiSpan::from_span(method_name.ident.span);
+ let mut span = MultiSpan::from_span(name_span);
span.push_span_label(iter_call.span, "the iterator could be used here instead");
span_lint_hir_and_then(
cx,
super::NEEDLESS_COLLECT,
- init_expr.hir_id,
+ collect_expr.hir_id,
span,
NEEDLESS_COLLECT_MSG,
|diag| {
- let iter_replacement = format!("{}{}", Sugg::hir(cx, iter_source, ".."), iter_call.get_iter_method(cx));
+ let iter_replacement = format!("{}{}", Sugg::hir(cx, iter_expr, ".."), iter_call.get_iter_method(cx));
diag.multipart_suggestion(
iter_call.get_suggestion_text(),
vec![
- (stmt.span, String::new()),
+ (l.span, String::new()),
(iter_call.span, iter_replacement)
],
Applicability::MaybeIncorrect,
@@ -123,11 +128,61 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo
},
);
}
- }
+ },
+ _ => (),
}
}
}
+/// Checks if the given method call matches the expected signature of `([&[mut]] self) -> bool`
+fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool {
+ cx.typeck_results().type_dependent_def_id(call_id).map_or(false, |id| {
+ let sig = cx.tcx.fn_sig(id).skip_binder();
+ sig.inputs().len() == 1 && sig.output().is_bool()
+ })
+}
+
+/// Checks if `<iter_ty as Iterator>::Item` is the same as `<collect_ty as IntoIter>::Item`
+fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: Ty<'tcx>) -> bool {
+ let item = Symbol::intern("Item");
+ if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)
+ && let Some(into_iter_trait) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
+ && let Some(iter_item_ty) = make_normalized_projection(cx.tcx, cx.param_env, iter_trait, item, [iter_ty])
+ && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, item, [collect_ty])
+ && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions(
+ cx.param_env,
+ cx.tcx.mk_projection(into_iter_item_proj.item_def_id, into_iter_item_proj.substs)
+ )
+ {
+ iter_item_ty == into_iter_item_ty
+ } else {
+ false
+ }
+}
+
+/// Checks if the given method call matches the expected signature of
+/// `([&[mut]] self, &<iter_ty as Iterator>::Item) -> bool`
+fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -> bool {
+ let typeck = cx.typeck_results();
+ if let Some(id) = typeck.type_dependent_def_id(call_id)
+ && let sig = cx.tcx.fn_sig(id)
+ && sig.skip_binder().output().is_bool()
+ && let [_, search_ty] = *sig.skip_binder().inputs()
+ && let ty::Ref(_, search_ty, Mutability::Not) = *cx.tcx.erase_late_bound_regions(sig.rebind(search_ty)).kind()
+ && let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)
+ && let Some(iter_item) = cx.tcx
+ .associated_items(iter_trait)
+ .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait)
+ && let substs = cx.tcx.mk_substs([GenericArg::from(typeck.expr_ty_adjusted(iter_expr))].into_iter())
+ && let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs)
+ && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty)
+ {
+ item_ty == EarlyBinder(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id))
+ } else {
+ false
+ }
+}
+
struct IterFunction {
func: IterFunctionKind,
span: Span,
diff --git a/src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs b/src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs
index a76341855..01655e860 100644
--- a/src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs
@@ -1,11 +1,10 @@
use clippy_utils::diagnostics::span_lint;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use clippy_utils::SpanlessEq;
use if_chain::if_chain;
use rustc_ast::LitKind;
-use rustc_hir::ExprKind;
+use rustc_hir::{ExprKind, LangItem};
use rustc_lint::LateContext;
-use rustc_span::sym;
use super::NO_EFFECT_REPLACE;
@@ -16,7 +15,7 @@ pub(super) fn check<'tcx>(
arg2: &'tcx rustc_hir::Expr<'_>,
) {
let ty = cx.typeck_results().expr_ty(expr).peel_refs();
- if !(ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String)) {
+ if !(ty.is_str() || is_type_lang_item(cx, ty, LangItem::String)) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
index 742483e6b..3e33f9193 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -1,27 +1,27 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{match_def_path, meets_msrv, msrvs, path_to_local_id, paths, peel_blocks};
+use clippy_utils::{match_def_path, path_to_local_id, paths, peel_blocks};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_middle::ty;
-use rustc_semver::RustcVersion;
use rustc_span::sym;
use super::OPTION_AS_REF_DEREF;
/// lint use of `_.as_ref().map(Deref::deref)` for `Option`s
-pub(super) fn check<'tcx>(
- cx: &LateContext<'tcx>,
+pub(super) fn check(
+ cx: &LateContext<'_>,
expr: &hir::Expr<'_>,
as_ref_recv: &hir::Expr<'_>,
map_arg: &hir::Expr<'_>,
is_mut: bool,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) {
- if !meets_msrv(msrv, msrvs::OPTION_AS_DEREF) {
+ if !msrv.meets(msrvs::OPTION_AS_DEREF) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
index 30421a6dd..910ee1485 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
@@ -97,7 +97,7 @@ struct UnwrapVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> {
type NestedFilter = nested_filter::All;
- fn visit_path(&mut self, path: &'tcx Path<'_>, _id: HirId) {
+ fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
self.identifiers.insert(ident(path));
walk_path(self, path);
}
@@ -116,7 +116,7 @@ struct MapExprVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for MapExprVisitor<'a, 'tcx> {
type NestedFilter = nested_filter::All;
- fn visit_path(&mut self, path: &'tcx Path<'_>, _id: HirId) {
+ fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
if self.identifiers.contains(&ident(path)) {
self.found_identifier = true;
return;
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 991d3dd53..4460f38fc 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
@@ -83,6 +83,8 @@ pub(super) fn check<'tcx>(
method_span: Span,
self_expr: &hir::Expr<'_>,
arg: &'tcx hir::Expr<'_>,
+ // `Some` if fn has second argument
+ second_arg: Option<&hir::Expr<'_>>,
span: Span,
// None if lambda is required
fun_span: Option<Span>,
@@ -109,30 +111,40 @@ pub(super) fn check<'tcx>(
if poss.contains(&name);
then {
- let macro_expanded_snipped;
- let sugg: Cow<'_, str> = {
+ let sugg = {
let (snippet_span, use_lambda) = match (fn_has_arguments, fun_span) {
(false, Some(fun_span)) => (fun_span, false),
_ => (arg.span, true),
};
- let snippet = {
- let not_macro_argument_snippet = snippet_with_macro_callsite(cx, snippet_span, "..");
- if not_macro_argument_snippet == "vec![]" {
- macro_expanded_snipped = snippet(cx, snippet_span, "..");
+
+ let format_span = |span: Span| {
+ let not_macro_argument_snippet = snippet_with_macro_callsite(cx, span, "..");
+ let snip = if not_macro_argument_snippet == "vec![]" {
+ let macro_expanded_snipped = snippet(cx, snippet_span, "..");
match macro_expanded_snipped.strip_prefix("$crate::vec::") {
- Some(stripped) => Cow::from(stripped),
+ Some(stripped) => Cow::Owned(stripped.to_owned()),
None => macro_expanded_snipped,
}
} else {
not_macro_argument_snippet
- }
+ };
+
+ snip.to_string()
};
- if use_lambda {
+ let snip = format_span(snippet_span);
+ let snip = if use_lambda {
let l_arg = if fn_has_arguments { "_" } else { "" };
- format!("|{l_arg}| {snippet}").into()
+ format!("|{l_arg}| {snip}")
} else {
- snippet
+ snip
+ };
+
+ if let Some(f) = second_arg {
+ let f = format_span(f.span);
+ format!("{snip}, {f}")
+ } else {
+ snip
}
};
let span_replace_word = method_span.with_hi(span.hi());
@@ -149,8 +161,8 @@ pub(super) fn check<'tcx>(
}
}
- if let [arg] = args {
- let inner_arg = if let hir::ExprKind::Block(
+ let extract_inner_arg = |arg: &'tcx hir::Expr<'_>| {
+ if let hir::ExprKind::Block(
hir::Block {
stmts: [],
expr: Some(expr),
@@ -162,19 +174,32 @@ pub(super) fn check<'tcx>(
expr
} else {
arg
- };
+ }
+ };
+
+ if let [arg] = args {
+ let inner_arg = extract_inner_arg(arg);
match inner_arg.kind {
hir::ExprKind::Call(fun, or_args) => {
let or_has_args = !or_args.is_empty();
if !check_unwrap_or_default(cx, name, fun, arg, or_has_args, expr.span, method_span) {
let fun_span = if or_has_args { None } else { Some(fun.span) };
- check_general_case(cx, name, method_span, receiver, arg, expr.span, fun_span);
+ check_general_case(cx, name, method_span, receiver, arg, None, expr.span, fun_span);
}
},
hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => {
- check_general_case(cx, name, method_span, receiver, arg, expr.span, None);
+ check_general_case(cx, name, method_span, receiver, arg, None, expr.span, None);
},
_ => (),
}
}
+
+ // `map_or` takes two arguments
+ if let [arg, lambda] = args {
+ let inner_arg = extract_inner_arg(arg);
+ if let hir::ExprKind::Call(fun, or_args) = inner_arg.kind {
+ let fun_span = if or_args.is_empty() { Some(fun.span) } else { None };
+ check_general_case(cx, name, method_span, receiver, arg, Some(lambda), expr.span, fun_span);
+ }
+ }
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/repeat_once.rs b/src/tools/clippy/clippy_lints/src/methods/repeat_once.rs
index 0a14f9216..a345ec813 100644
--- a/src/tools/clippy/clippy_lints/src/methods/repeat_once.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/repeat_once.rs
@@ -1,11 +1,10 @@
use clippy_utils::consts::{constant_context, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use rustc_errors::Applicability;
-use rustc_hir::Expr;
+use rustc_hir::{Expr, LangItem};
use rustc_lint::LateContext;
-use rustc_span::sym;
use super::REPEAT_ONCE;
@@ -37,7 +36,7 @@ pub(super) fn check<'tcx>(
format!("{}.to_vec()", snippet(cx, recv.span, r#""...""#)),
Applicability::MachineApplicable,
);
- } else if is_type_diagnostic_item(cx, ty, sym::String) {
+ } else if is_type_lang_item(cx, ty, LangItem::String) {
span_lint_and_sugg(
cx,
REPEAT_ONCE,
diff --git a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
index 324c9c17b..1c031ad6a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::sugg::deref_closure_args;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{is_trait_method, strip_pat_refs};
use if_chain::if_chain;
use rustc_errors::Applicability;
@@ -105,7 +105,7 @@ pub(super) fn check<'tcx>(
else if search_method == "find" {
let is_string_or_str_slice = |e| {
let self_ty = cx.typeck_results().expr_ty(e).peel_refs();
- if is_type_diagnostic_item(cx, self_ty, sym::String) {
+ if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
true
} else {
*self_ty.kind() == ty::Str
diff --git a/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs b/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs
new file mode 100644
index 000000000..361a3082f
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs
@@ -0,0 +1,48 @@
+use rustc_ast::ast::{LitIntType, LitKind};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+
+use clippy_utils::{
+ diagnostics::span_lint_and_sugg, get_trait_def_id, match_def_path, paths, source::snippet_with_applicability,
+ ty::implements_trait,
+};
+
+use super::SEEK_FROM_CURRENT;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) {
+ let ty = cx.typeck_results().expr_ty(recv);
+
+ if let Some(def_id) = get_trait_def_id(cx, &paths::STD_IO_SEEK) {
+ if implements_trait(cx, ty, def_id, &[]) && arg_is_seek_from_current(cx, arg) {
+ let mut applicability = Applicability::MachineApplicable;
+ let snip = snippet_with_applicability(cx, recv.span, "..", &mut applicability);
+
+ span_lint_and_sugg(
+ cx,
+ SEEK_FROM_CURRENT,
+ expr.span,
+ "using `SeekFrom::Current` to start from current position",
+ "replace with",
+ format!("{snip}.stream_position()"),
+ applicability,
+ );
+ }
+ }
+}
+
+fn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {
+ if let ExprKind::Call(f, args) = expr.kind &&
+ let ExprKind::Path(ref path) = f.kind &&
+ let Some(def_id) = cx.qpath_res(path, f.hir_id).opt_def_id() &&
+ match_def_path(cx, def_id, &paths::STD_IO_SEEK_FROM_CURRENT) {
+ // check if argument of `SeekFrom::Current` is `0`
+ if args.len() == 1 &&
+ let ExprKind::Lit(ref lit) = args[0].kind &&
+ let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node {
+ return true
+ }
+ }
+
+ false
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs b/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
new file mode 100644
index 000000000..7e3bed1e4
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
@@ -0,0 +1,45 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::ty::implements_trait;
+use clippy_utils::{get_trait_def_id, match_def_path, paths};
+use rustc_ast::ast::{LitIntType, LitKind};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::Span;
+
+use super::SEEK_TO_START_INSTEAD_OF_REWIND;
+
+pub(super) fn check<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'_>,
+ recv: &'tcx Expr<'_>,
+ arg: &'tcx Expr<'_>,
+ name_span: Span,
+) {
+ // Get receiver type
+ let ty = cx.typeck_results().expr_ty(recv).peel_refs();
+
+ if let Some(seek_trait_id) = get_trait_def_id(cx, &paths::STD_IO_SEEK) &&
+ implements_trait(cx, ty, seek_trait_id, &[]) &&
+ let ExprKind::Call(func, args1) = arg.kind &&
+ let ExprKind::Path(ref path) = func.kind &&
+ let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id() &&
+ match_def_path(cx, def_id, &paths::STD_IO_SEEKFROM_START) &&
+ args1.len() == 1 &&
+ let ExprKind::Lit(ref lit) = args1[0].kind &&
+ let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node
+ {
+ let method_call_span = expr.span.with_lo(name_span.lo());
+ span_lint_and_then(
+ cx,
+ SEEK_TO_START_INSTEAD_OF_REWIND,
+ method_call_span,
+ "used `seek` to go to the start of the stream",
+ |diag| {
+ let app = Applicability::MachineApplicable;
+
+ diag.span_suggestion(method_call_span, "replace with", "rewind()", app);
+ },
+ );
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
index 1acac5914..3c01ce1fe 100644
--- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
@@ -1,9 +1,10 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_context;
use clippy_utils::usage::local_used_after_expr;
use clippy_utils::visitors::{for_each_expr_with_closures, Descend};
-use clippy_utils::{is_diag_item_method, match_def_path, meets_msrv, msrvs, path_to_local_id, paths};
+use clippy_utils::{is_diag_item_method, match_def_path, path_to_local_id, paths};
use core::ops::ControlFlow;
use if_chain::if_chain;
use rustc_errors::Applicability;
@@ -12,7 +13,6 @@ use rustc_hir::{
};
use rustc_lint::LateContext;
use rustc_middle::ty;
-use rustc_semver::RustcVersion;
use rustc_span::{sym, Span, Symbol, SyntaxContext};
use super::{MANUAL_SPLIT_ONCE, NEEDLESS_SPLITN};
@@ -24,7 +24,7 @@ pub(super) fn check(
self_arg: &Expr<'_>,
pat_arg: &Expr<'_>,
count: u128,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) {
if count < 2 || !cx.typeck_results().expr_ty_adjusted(self_arg).peel_refs().is_str() {
return;
@@ -34,7 +34,7 @@ pub(super) fn check(
IterUsageKind::Nth(n) => count > n + 1,
IterUsageKind::NextTuple => count > 2,
};
- let manual = count == 2 && meets_msrv(msrv, msrvs::STR_SPLIT_ONCE);
+ let manual = count == 2 && msrv.meets(msrvs::STR_SPLIT_ONCE);
match parse_iter_usage(cx, expr.span.ctxt(), cx.tcx.hir().parent_iter(expr.hir_id)) {
Some(usage) if needless(usage.kind) => lint_needless(cx, method_name, expr, self_arg, pat_arg),
diff --git a/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs b/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs
index 6974260f7..f35d81cee 100644
--- a/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs
@@ -1,26 +1,29 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::method_chain_args;
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_middle::ty;
-use rustc_span::symbol::sym;
use super::STRING_EXTEND_CHARS;
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
- if !is_type_diagnostic_item(cx, obj_ty, sym::String) {
+ if !is_type_lang_item(cx, obj_ty, hir::LangItem::String) {
return;
}
if let Some(arglists) = method_chain_args(arg, &["chars"]) {
let target = &arglists[0].0;
let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
let ref_str = if *self_ty.kind() == ty::Str {
- ""
- } else if is_type_diagnostic_item(cx, self_ty, sym::String) {
+ if matches!(target.kind, hir::ExprKind::Index(..)) {
+ "&"
+ } else {
+ ""
+ }
+ } else if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
"&"
} else {
return;
diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs
index 851cdf544..2ac0786b3 100644
--- a/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_map.rs
@@ -8,7 +8,7 @@ use rustc_span::sym;
use super::SUSPICIOUS_MAP;
-pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, count_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) {
+pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, count_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) {
if_chain! {
if is_trait_method(cx, count_recv, sym::Iterator);
let closure = expr_or_init(cx, map_arg);
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
index 1966a85f7..52a4ff7d1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
@@ -2,10 +2,10 @@ use super::utils::clone_or_copy_needed;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::ForLoop;
use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{get_associated_type, get_iterator_item_ty, implements_trait};
+use clippy_utils::ty::{get_iterator_item_ty, implements_trait};
use clippy_utils::{fn_def_id, get_parent_expr};
use rustc_errors::Applicability;
-use rustc_hir::{def_id::DefId, Expr, ExprKind, LangItem};
+use rustc_hir::{def_id::DefId, Expr, ExprKind};
use rustc_lint::LateContext;
use rustc_span::{sym, Symbol};
@@ -54,7 +54,7 @@ pub fn check_for_loop_iter(
if let Some(into_iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator);
let collection_ty = cx.typeck_results().expr_ty(collection);
if implements_trait(cx, collection_ty, into_iterator_trait_id, &[]);
- if let Some(into_iter_item_ty) = get_associated_type(cx, collection_ty, into_iterator_trait_id, "Item");
+ if let Some(into_iter_item_ty) = cx.get_associated_type(collection_ty, into_iterator_trait_id, "Item");
if iter_item_ty == into_iter_item_ty;
if let Some(collection_snippet) = snippet_opt(cx, collection.span);
@@ -100,5 +100,5 @@ pub fn check_for_loop_iter(
/// Returns true if the named method is `IntoIterator::into_iter`.
pub fn is_into_iter(cx: &LateContext<'_>, callee_def_id: DefId) -> bool {
- cx.tcx.lang_items().require(LangItem::IntoIterIntoIter) == Ok(callee_def_id)
+ Some(callee_def_id) == cx.tcx.lang_items().into_iter_fn()
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs
index 973b8a7e6..087e1e434 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs
@@ -1,10 +1,10 @@
-use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item};
+use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{Expr, ExprKind, LangItem};
use rustc_lint::LateContext;
use rustc_middle::ty::{Ref, Slice};
-use rustc_span::{sym, Span};
+use rustc_span::Span;
use super::UNNECESSARY_JOIN;
@@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
// the turbofish for collect is ::<Vec<String>>
if let Ref(_, ref_type, _) = collect_output_adjusted_type.kind();
if let Slice(slice) = ref_type.kind();
- if is_type_diagnostic_item(cx, *slice, sym::String);
+ if is_type_lang_item(cx, *slice, LangItem::String);
// the argument for join is ""
if let ExprKind::Lit(spanned) = &join_arg.kind;
if let LitKind::Str(symbol, _) = spanned.node;
@@ -31,7 +31,7 @@ pub(super) fn check<'tcx>(
cx,
UNNECESSARY_JOIN,
span.with_hi(expr.span.hi()),
- r#"called `.collect<Vec<String>>().join("")` on an iterator"#,
+ r#"called `.collect::<Vec<String>>().join("")` on an iterator"#,
"try using",
"collect::<String>()".to_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 3566fe9a0..9263f0519 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
@@ -1,25 +1,22 @@
use super::implicit_clone::is_clone_like;
use super::unnecessary_iter_cloned::{self, is_into_iter};
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{get_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs};
+use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs};
use clippy_utils::visitors::find_all_ret_expressions;
use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty};
-use clippy_utils::{meets_msrv, msrvs};
use rustc_errors::Applicability;
-use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};
+use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, Node};
use rustc_hir_typeck::{FnCtxt, Inherited};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext;
use rustc_middle::mir::Mutability;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
-use rustc_middle::ty::EarlyBinder;
-use rustc_middle::ty::{self, ParamTy, PredicateKind, ProjectionPredicate, TraitPredicate, Ty};
-use rustc_semver::RustcVersion;
+use rustc_middle::ty::{self, Clause, EarlyBinder, ParamTy, PredicateKind, ProjectionPredicate, TraitPredicate, Ty};
use rustc_span::{sym, Symbol};
use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
-use std::cmp::max;
use super::UNNECESSARY_TO_OWNED;
@@ -29,7 +26,7 @@ pub fn check<'tcx>(
method_name: Symbol,
receiver: &'tcx Expr<'_>,
args: &'tcx [Expr<'_>],
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) {
if_chain! {
if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
@@ -146,7 +143,7 @@ fn check_addr_of_expr(
if_chain! {
if let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref);
if implements_trait(cx, receiver_ty, deref_trait_id, &[]);
- if get_associated_type(cx, receiver_ty, deref_trait_id, "Target") == Some(target_ty);
+ if cx.get_associated_type(receiver_ty, deref_trait_id, "Target") == Some(target_ty);
then {
if n_receiver_refs > 0 {
span_lint_and_sugg(
@@ -200,7 +197,7 @@ fn check_into_iter_call_arg(
expr: &Expr<'_>,
method_name: Symbol,
receiver: &Expr<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) -> bool {
if_chain! {
if let Some(parent) = get_parent_expr(cx, expr);
@@ -215,7 +212,7 @@ fn check_into_iter_call_arg(
if unnecessary_iter_cloned::check_for_loop_iter(cx, parent, method_name, receiver, true) {
return true;
}
- let cloned_or_copied = if is_copy(cx, item_ty) && meets_msrv(msrv, msrvs::ITERATOR_COPIED) {
+ let cloned_or_copied = if is_copy(cx, item_ty) && msrv.meets(msrvs::ITERATOR_COPIED) {
"copied"
} else {
"cloned"
@@ -263,11 +260,22 @@ fn check_other_call_arg<'tcx>(
if let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef);
if trait_predicate.def_id() == deref_trait_id || trait_predicate.def_id() == as_ref_trait_id;
let receiver_ty = cx.typeck_results().expr_ty(receiver);
- if can_change_type(cx, maybe_arg, receiver_ty);
// We can't add an `&` when the trait is `Deref` because `Target = &T` won't match
// `Target = T`.
- if n_refs > 0 || is_copy(cx, receiver_ty) || trait_predicate.def_id() != deref_trait_id;
- let n_refs = max(n_refs, usize::from(!is_copy(cx, receiver_ty)));
+ if let Some((n_refs, receiver_ty)) = if n_refs > 0 || is_copy(cx, receiver_ty) {
+ Some((n_refs, receiver_ty))
+ } else if trait_predicate.def_id() != deref_trait_id {
+ Some((1, cx.tcx.mk_ref(
+ cx.tcx.lifetimes.re_erased,
+ ty::TypeAndMut {
+ ty: receiver_ty,
+ mutbl: Mutability::Not,
+ },
+ )))
+ } else {
+ None
+ };
+ if can_change_type(cx, maybe_arg, receiver_ty);
if let Some(receiver_snippet) = snippet_opt(cx, receiver.span);
then {
span_lint_and_sugg(
@@ -337,12 +345,12 @@ fn get_input_traits_and_projections<'tcx>(
let mut projection_predicates = Vec::new();
for predicate in cx.tcx.param_env(callee_def_id).caller_bounds() {
match predicate.kind().skip_binder() {
- PredicateKind::Trait(trait_predicate) => {
+ PredicateKind::Clause(Clause::Trait(trait_predicate)) => {
if trait_predicate.trait_ref.self_ty() == input {
trait_predicates.push(trait_predicate);
}
},
- PredicateKind::Projection(projection_predicate) => {
+ PredicateKind::Clause(Clause::Projection(projection_predicate)) => {
if projection_predicate.projection_ty.self_ty() == input {
projection_predicates.push(projection_predicate);
}
@@ -378,14 +386,12 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
Node::Expr(parent_expr) => {
if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr)
{
- if cx.tcx.lang_items().require(LangItem::IntoFutureIntoFuture) == Ok(callee_def_id) {
- return false;
- }
-
let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder();
if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
&& let Some(param_ty) = fn_sig.inputs().get(arg_index)
&& let ty::Param(ParamTy { index: param_index , ..}) = param_ty.kind()
+ // https://github.com/rust-lang/rust-clippy/issues/9504 and https://github.com/rust-lang/rust-clippy/issues/10021
+ && (*param_index as usize) < call_substs.len()
{
if fn_sig
.inputs()
@@ -399,10 +405,12 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
let mut trait_predicates = cx.tcx.param_env(callee_def_id)
.caller_bounds().iter().filter(|predicate| {
- if let PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder()
- && trait_predicate.trait_ref.self_ty() == *param_ty {
- true
- } else {
+ if let PredicateKind::Clause(Clause::Trait(trait_predicate))
+ = predicate.kind().skip_binder()
+ && trait_predicate.trait_ref.self_ty() == *param_ty
+ {
+ true
+ } else {
false
}
});
@@ -419,7 +427,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
if trait_predicates.any(|predicate| {
let predicate = EarlyBinder(predicate).subst(cx.tcx, new_subst);
- let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
+ let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
!cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
}) {
return false;
@@ -474,7 +482,7 @@ fn is_cow_into_owned(cx: &LateContext<'_>, method_name: Symbol, method_def_id: D
}
/// Returns true if the named method is `ToString::to_string` and it's called on a type that
-/// is string-like i.e. implements `AsRef<str>` or `Deref<str>`.
+/// is string-like i.e. implements `AsRef<str>` or `Deref<Target = str>`.
fn is_to_string_on_string_like<'a>(
cx: &LateContext<'_>,
call_expr: &'a Expr<'a>,
@@ -490,7 +498,7 @@ fn is_to_string_on_string_like<'a>(
&& let GenericArgKind::Type(ty) = generic_arg.unpack()
&& let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
&& let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)
- && (implements_trait(cx, ty, deref_trait_id, &[cx.tcx.types.str_.into()]) ||
+ && (cx.get_associated_type(ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) ||
implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) {
true
} else {
diff --git a/src/tools/clippy/clippy_lints/src/methods/unwrap_used.rs b/src/tools/clippy/clippy_lints/src/methods/unwrap_used.rs
index ee17f2d78..90983f249 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unwrap_used.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unwrap_used.rs
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{is_in_test_function, is_lint_allowed};
+use clippy_utils::{is_in_cfg_test, is_lint_allowed};
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_span::sym;
@@ -18,16 +18,16 @@ pub(super) fn check(
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) && !is_err {
- Some((UNWRAP_USED, "an Option", "None", ""))
+ Some((UNWRAP_USED, "an `Option`", "None", ""))
} else if is_type_diagnostic_item(cx, obj_ty, sym::Result) {
- Some((UNWRAP_USED, "a Result", if is_err { "Ok" } else { "Err" }, "an "))
+ Some((UNWRAP_USED, "a `Result`", if is_err { "Ok" } else { "Err" }, "an "))
} else {
None
};
let method_suffix = if is_err { "_err" } else { "" };
- if allow_unwrap_in_tests && is_in_test_function(cx.tcx, expr.hir_id) {
+ if allow_unwrap_in_tests && is_in_cfg_test(cx.tcx, expr.hir_id) {
return;
}
@@ -45,7 +45,7 @@ pub(super) fn check(
cx,
lint,
expr.span,
- &format!("used `unwrap{method_suffix}()` on `{kind}` value"),
+ &format!("used `unwrap{method_suffix}()` on {kind} value"),
None,
&help,
);
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs b/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs
index 27e7f8505..eda4376f2 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs
@@ -1,11 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
-use rustc_ast::ast::Lit;
use rustc_errors::Applicability;
use rustc_lint::EarlyContext;
+use rustc_span::Span;
use super::{SEPARATED_LITERAL_SUFFIX, UNSEPARATED_LITERAL_SUFFIX};
-pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &str, sugg_type: &str) {
+pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str, suffix: &str, sugg_type: &str) {
let Some(maybe_last_sep_idx) = lit_snip.len().checked_sub(suffix.len() + 1) else {
return; // It's useless so shouldn't lint.
};
@@ -15,7 +15,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &s
span_lint_and_sugg(
cx,
SEPARATED_LITERAL_SUFFIX,
- lit.span,
+ lit_span,
&format!("{sugg_type} type suffix should not be separated by an underscore"),
"remove the underscore",
format!("{}{suffix}", &lit_snip[..maybe_last_sep_idx]),
@@ -25,7 +25,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &s
span_lint_and_sugg(
cx,
UNSEPARATED_LITERAL_SUFFIX,
- lit.span,
+ lit_span,
&format!("{sugg_type} type suffix should be separated by an underscore"),
"add an underscore",
format!("{}_{suffix}", &lit_snip[..=maybe_last_sep_idx]),
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs b/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs
index 263ee1e94..ddb8b9173 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs
@@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint;
-use rustc_ast::ast::Lit;
use rustc_lint::EarlyContext;
+use rustc_span::Span;
use super::MIXED_CASE_HEX_LITERALS;
-pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, suffix: &str, lit_snip: &str) {
+pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, suffix: &str, lit_snip: &str) {
let Some(maybe_last_sep_idx) = lit_snip.len().checked_sub(suffix.len() + 1) else {
return; // It's useless so shouldn't lint.
};
@@ -23,7 +23,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, suffix: &str, lit_snip: &s
span_lint(
cx,
MIXED_CASE_HEX_LITERALS,
- lit.span,
+ lit_span,
"inconsistent casing in hexadecimal literal",
);
break;
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
index c8227ca44..78be6b9e2 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
@@ -9,7 +9,8 @@ mod zero_prefixed_literal;
use clippy_utils::diagnostics::span_lint;
use clippy_utils::source::snippet_opt;
-use rustc_ast::ast::{Expr, ExprKind, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
+use rustc_ast::ast::{Expr, ExprKind, Generics, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
+use rustc_ast::token;
use rustc_ast::visit::FnKind;
use rustc_data_structures::fx::FxHashMap;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
@@ -374,42 +375,43 @@ impl EarlyLintPass for MiscEarlyLints {
return;
}
- if let ExprKind::Lit(ref lit) = expr.kind {
- MiscEarlyLints::check_lit(cx, lit);
+ if let ExprKind::Lit(lit) = expr.kind {
+ MiscEarlyLints::check_lit(cx, lit, expr.span);
}
double_neg::check(cx, expr);
}
}
impl MiscEarlyLints {
- fn check_lit(cx: &EarlyContext<'_>, lit: &Lit) {
+ fn check_lit(cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
// We test if first character in snippet is a number, because the snippet could be an expansion
// from a built-in macro like `line!()` or a proc-macro like `#[wasm_bindgen]`.
// Note that this check also covers special case that `line!()` is eagerly expanded by compiler.
// See <https://github.com/rust-lang/rust-clippy/issues/4507> for a regression.
// FIXME: Find a better way to detect those cases.
- let lit_snip = match snippet_opt(cx, lit.span) {
+ let lit_snip = match snippet_opt(cx, span) {
Some(snip) if snip.chars().next().map_or(false, |c| c.is_ascii_digit()) => snip,
_ => return,
};
- if let LitKind::Int(value, lit_int_type) = lit.kind {
+ let lit_kind = LitKind::from_token_lit(lit);
+ if let Ok(LitKind::Int(value, lit_int_type)) = lit_kind {
let suffix = match lit_int_type {
LitIntType::Signed(ty) => ty.name_str(),
LitIntType::Unsigned(ty) => ty.name_str(),
LitIntType::Unsuffixed => "",
};
- literal_suffix::check(cx, lit, &lit_snip, suffix, "integer");
+ literal_suffix::check(cx, span, &lit_snip, suffix, "integer");
if lit_snip.starts_with("0x") {
- mixed_case_hex_literals::check(cx, lit, suffix, &lit_snip);
+ mixed_case_hex_literals::check(cx, span, suffix, &lit_snip);
} else if lit_snip.starts_with("0b") || lit_snip.starts_with("0o") {
// nothing to do
} else if value != 0 && lit_snip.starts_with('0') {
- zero_prefixed_literal::check(cx, lit, &lit_snip);
+ zero_prefixed_literal::check(cx, span, &lit_snip);
}
- } else if let LitKind::Float(_, LitFloatType::Suffixed(float_ty)) = lit.kind {
+ } else if let Ok(LitKind::Float(_, LitFloatType::Suffixed(float_ty))) = lit_kind {
let suffix = float_ty.name_str();
- literal_suffix::check(cx, lit, &lit_snip, suffix, "float");
+ literal_suffix::check(cx, span, &lit_snip, suffix, "float");
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/zero_prefixed_literal.rs b/src/tools/clippy/clippy_lints/src/misc_early/zero_prefixed_literal.rs
index 9ead43ea4..4f9578d1b 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/zero_prefixed_literal.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/zero_prefixed_literal.rs
@@ -1,20 +1,20 @@
use clippy_utils::diagnostics::span_lint_and_then;
-use rustc_ast::ast::Lit;
use rustc_errors::Applicability;
use rustc_lint::EarlyContext;
+use rustc_span::Span;
use super::ZERO_PREFIXED_LITERAL;
-pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str) {
+pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str) {
let trimmed_lit_snip = lit_snip.trim_start_matches(|c| c == '_' || c == '0');
span_lint_and_then(
cx,
ZERO_PREFIXED_LITERAL,
- lit.span,
+ lit_span,
"this is a decimal constant",
|diag| {
diag.span_suggestion(
- lit.span,
+ lit_span,
"if you mean to use a decimal constant, remove the `0` to avoid confusion",
trimmed_lit_snip.to_string(),
Applicability::MaybeIncorrect,
@@ -22,7 +22,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str) {
// do not advise to use octal form if the literal cannot be expressed in base 8.
if !lit_snip.contains(|c| c == '8' || c == '9') {
diag.span_suggestion(
- lit.span,
+ lit_span,
"if you mean to use an octal constant, use `0o`",
format!("0o{trimmed_lit_snip}"),
Applicability::MaybeIncorrect,
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 71cc0d0a8..5bc04bc17 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
@@ -1,9 +1,8 @@
use clippy_utils::diagnostics::span_lint;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::qualify_min_const_fn::is_min_const_fn;
use clippy_utils::ty::has_drop;
-use clippy_utils::{
- fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, meets_msrv, msrvs, trait_ref_of_method,
-};
+use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, trait_ref_of_method};
use rustc_hir as hir;
use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_hir::intravisit::FnKind;
@@ -11,7 +10,6 @@ use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span;
@@ -75,12 +73,12 @@ declare_clippy_lint! {
impl_lint_pass!(MissingConstForFn => [MISSING_CONST_FOR_FN]);
pub struct MissingConstForFn {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl MissingConstForFn {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -95,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
span: Span,
hir_id: HirId,
) {
- if !meets_msrv(self.msrv, msrvs::CONST_IF_MATCH) {
+ if !self.msrv.meets(msrvs::CONST_IF_MATCH) {
return;
}
@@ -152,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
let mir = cx.tcx.optimized_mir(def_id);
- if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, self.msrv) {
+ if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, &self.msrv) {
if cx.tcx.is_const_fn_raw(def_id.to_def_id()) {
cx.tcx.sess.span_err(span, err.as_ref());
}
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index 2a63681db..6fd100762 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -199,7 +199,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
}
fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) {
- let attrs = cx.tcx.hir().attrs(v.id);
+ let attrs = cx.tcx.hir().attrs(v.hir_id);
if !is_from_proc_macro(cx, v) {
self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
}
diff --git a/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs b/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs
index 872679f25..773174679 100644
--- a/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs
@@ -59,42 +59,45 @@ impl LateLintPass<'_> for ImportRename {
fn check_crate(&mut self, cx: &LateContext<'_>) {
for Rename { path, rename } in &self.conf_renames {
let segs = path.split("::").collect::<Vec<_>>();
- if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, None) {
+ for id in clippy_utils::def_path_def_ids(cx, &segs) {
self.renames.insert(id, Symbol::intern(rename));
}
}
}
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
- if_chain! {
- if let ItemKind::Use(path, UseKind::Single) = &item.kind;
- if let Res::Def(_, id) = path.res;
- if let Some(name) = self.renames.get(&id);
- // Remove semicolon since it is not present for nested imports
- let span_without_semi = cx.sess().source_map().span_until_char(item.span, ';');
- if let Some(snip) = snippet_opt(cx, span_without_semi);
- if let Some(import) = match snip.split_once(" as ") {
- None => Some(snip.as_str()),
- Some((import, rename)) => {
- if rename.trim() == name.as_str() {
- None
- } else {
- Some(import.trim())
+ if let ItemKind::Use(path, UseKind::Single) = &item.kind {
+ for &res in &path.res {
+ if_chain! {
+ if let Res::Def(_, id) = res;
+ if let Some(name) = self.renames.get(&id);
+ // Remove semicolon since it is not present for nested imports
+ let span_without_semi = cx.sess().source_map().span_until_char(item.span, ';');
+ if let Some(snip) = snippet_opt(cx, span_without_semi);
+ if let Some(import) = match snip.split_once(" as ") {
+ None => Some(snip.as_str()),
+ Some((import, rename)) => {
+ if rename.trim() == name.as_str() {
+ None
+ } else {
+ Some(import.trim())
+ }
+ },
+ };
+ then {
+ span_lint_and_sugg(
+ cx,
+ MISSING_ENFORCED_IMPORT_RENAMES,
+ span_without_semi,
+ "this import should be renamed",
+ "try",
+ format!(
+ "{import} as {name}",
+ ),
+ Applicability::MachineApplicable,
+ );
}
- },
- };
- then {
- span_lint_and_sugg(
- cx,
- MISSING_ENFORCED_IMPORT_RENAMES,
- span_without_semi,
- "this import should be renamed",
- "try",
- format!(
- "{import} as {name}",
- ),
- Applicability::MachineApplicable,
- );
+ }
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
index 675297634..321fa4b7f 100644
--- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -218,7 +218,7 @@ enum StopEarly {
Stop,
}
-fn check_expr<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, expr: &'tcx Expr<'_>) -> StopEarly {
+fn check_expr<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, expr: &'tcx Expr<'_>) -> StopEarly {
if expr.hir_id == vis.last_expr.hir_id {
return StopEarly::KeepGoing;
}
@@ -265,7 +265,7 @@ fn check_expr<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, expr: &'tcx Expr<'_>) -
StopEarly::KeepGoing
}
-fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt<'_>) -> StopEarly {
+fn check_stmt<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, stmt: &'tcx Stmt<'_>) -> StopEarly {
match stmt.kind {
StmtKind::Expr(expr) | StmtKind::Semi(expr) => check_expr(vis, expr),
// If the declaration is of a local variable, check its initializer
diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs
index 4b62dcdff..a651020ca 100644
--- a/src/tools/clippy/clippy_lints/src/mut_key.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_key.rs
@@ -1,10 +1,11 @@
use clippy_utils::diagnostics::span_lint;
-use clippy_utils::trait_ref_of_method;
+use clippy_utils::{def_path_def_ids, trait_ref_of_method};
+use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TypeVisitable;
use rustc_middle::ty::{Adt, Array, Ref, Slice, Tuple, Ty};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
use rustc_span::symbol::sym;
use std::iter;
@@ -78,26 +79,44 @@ declare_clippy_lint! {
"Check for mutable `Map`/`Set` key type"
}
-declare_lint_pass!(MutableKeyType => [ MUTABLE_KEY_TYPE ]);
+#[derive(Clone)]
+pub struct MutableKeyType {
+ ignore_interior_mutability: Vec<String>,
+ ignore_mut_def_ids: FxHashSet<hir::def_id::DefId>,
+}
+
+impl_lint_pass!(MutableKeyType => [ MUTABLE_KEY_TYPE ]);
impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
+ fn check_crate(&mut self, cx: &LateContext<'tcx>) {
+ self.ignore_mut_def_ids.clear();
+ let mut path = Vec::new();
+ for ty in &self.ignore_interior_mutability {
+ path.extend(ty.split("::"));
+ for id in def_path_def_ids(cx, &path[..]) {
+ self.ignore_mut_def_ids.insert(id);
+ }
+ path.clear();
+ }
+ }
+
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
if let hir::ItemKind::Fn(ref sig, ..) = item.kind {
- check_sig(cx, item.hir_id(), sig.decl);
+ self.check_sig(cx, item.hir_id(), sig.decl);
}
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'tcx>) {
if let hir::ImplItemKind::Fn(ref sig, ..) = item.kind {
if trait_ref_of_method(cx, item.owner_id.def_id).is_none() {
- check_sig(cx, item.hir_id(), sig.decl);
+ self.check_sig(cx, item.hir_id(), sig.decl);
}
}
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'tcx>) {
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
- check_sig(cx, item.hir_id(), sig.decl);
+ self.check_sig(cx, item.hir_id(), sig.decl);
}
}
@@ -105,73 +124,81 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
if let hir::PatKind::Wild = local.pat.kind {
return;
}
- check_ty(cx, local.span, cx.typeck_results().pat_ty(local.pat));
+ self.check_ty_(cx, local.span, cx.typeck_results().pat_ty(local.pat));
}
}
-fn check_sig<'tcx>(cx: &LateContext<'tcx>, item_hir_id: hir::HirId, decl: &hir::FnDecl<'_>) {
- let fn_def_id = cx.tcx.hir().local_def_id(item_hir_id);
- let fn_sig = cx.tcx.fn_sig(fn_def_id);
- for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) {
- check_ty(cx, hir_ty.span, *ty);
+impl MutableKeyType {
+ pub fn new(ignore_interior_mutability: Vec<String>) -> Self {
+ Self {
+ ignore_interior_mutability,
+ ignore_mut_def_ids: FxHashSet::default(),
+ }
}
- check_ty(cx, decl.output.span(), cx.tcx.erase_late_bound_regions(fn_sig.output()));
-}
-// We want to lint 1. sets or maps with 2. not immutable key types and 3. no unerased
-// generics (because the compiler cannot ensure immutability for unknown types).
-fn check_ty<'tcx>(cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
- let ty = ty.peel_refs();
- if let Adt(def, substs) = ty.kind() {
- let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet]
- .iter()
- .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
- if is_keyed_type && is_interior_mutable_type(cx, substs.type_at(0), span) {
- span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type");
+ fn check_sig(&self, cx: &LateContext<'_>, item_hir_id: hir::HirId, decl: &hir::FnDecl<'_>) {
+ let fn_def_id = cx.tcx.hir().local_def_id(item_hir_id);
+ let fn_sig = cx.tcx.fn_sig(fn_def_id);
+ for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) {
+ self.check_ty_(cx, hir_ty.span, *ty);
}
+ self.check_ty_(cx, decl.output.span(), cx.tcx.erase_late_bound_regions(fn_sig.output()));
}
-}
-/// Determines if a type contains interior mutability which would affect its implementation of
-/// [`Hash`] or [`Ord`].
-fn is_interior_mutable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span) -> bool {
- match *ty.kind() {
- Ref(_, inner_ty, mutbl) => {
- mutbl == hir::Mutability::Mut || is_interior_mutable_type(cx, inner_ty, span)
- }
- Slice(inner_ty) => is_interior_mutable_type(cx, inner_ty, span),
- Array(inner_ty, size) => {
- size.try_eval_usize(cx.tcx, cx.param_env).map_or(true, |u| u != 0)
- && is_interior_mutable_type(cx, inner_ty, span)
- }
- Tuple(fields) => fields.iter().any(|ty| is_interior_mutable_type(cx, ty, span)),
- Adt(def, substs) => {
- // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to
- // that of their type parameters. Note: we don't include `HashSet` and `HashMap`
- // because they have no impl for `Hash` or `Ord`.
- let is_std_collection = [
- sym::Option,
- sym::Result,
- sym::LinkedList,
- sym::Vec,
- sym::VecDeque,
- sym::BTreeMap,
- sym::BTreeSet,
- sym::Rc,
- sym::Arc,
- ]
- .iter()
- .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
- let is_box = Some(def.did()) == cx.tcx.lang_items().owned_box();
- if is_std_collection || is_box {
- // The type is mutable if any of its type parameters are
- substs.types().any(|ty| is_interior_mutable_type(cx, ty, span))
- } else {
- !ty.has_escaping_bound_vars()
- && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok()
- && !ty.is_freeze(cx.tcx, cx.param_env)
+ // We want to lint 1. sets or maps with 2. not immutable key types and 3. no unerased
+ // generics (because the compiler cannot ensure immutability for unknown types).
+ fn check_ty_<'tcx>(&self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
+ let ty = ty.peel_refs();
+ if let Adt(def, substs) = ty.kind() {
+ let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet]
+ .iter()
+ .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
+ if is_keyed_type && self.is_interior_mutable_type(cx, substs.type_at(0)) {
+ span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type");
}
}
- _ => false,
+ }
+
+ /// Determines if a type contains interior mutability which would affect its implementation of
+ /// [`Hash`] or [`Ord`].
+ fn is_interior_mutable_type<'tcx>(&self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
+ match *ty.kind() {
+ Ref(_, inner_ty, mutbl) => mutbl == hir::Mutability::Mut || self.is_interior_mutable_type(cx, inner_ty),
+ Slice(inner_ty) => self.is_interior_mutable_type(cx, inner_ty),
+ Array(inner_ty, size) => {
+ size.try_eval_usize(cx.tcx, cx.param_env).map_or(true, |u| u != 0)
+ && self.is_interior_mutable_type(cx, inner_ty)
+ },
+ Tuple(fields) => fields.iter().any(|ty| self.is_interior_mutable_type(cx, ty)),
+ Adt(def, substs) => {
+ // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to
+ // that of their type parameters. Note: we don't include `HashSet` and `HashMap`
+ // because they have no impl for `Hash` or `Ord`.
+ let def_id = def.did();
+ let is_std_collection = [
+ sym::Option,
+ sym::Result,
+ sym::LinkedList,
+ sym::Vec,
+ sym::VecDeque,
+ sym::BTreeMap,
+ sym::BTreeSet,
+ sym::Rc,
+ sym::Arc,
+ ]
+ .iter()
+ .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def_id));
+ let is_box = Some(def_id) == cx.tcx.lang_items().owned_box();
+ if is_std_collection || is_box || self.ignore_mut_def_ids.contains(&def_id) {
+ // The type is mutable if any of its type parameters are
+ substs.types().any(|ty| self.is_interior_mutable_type(cx, ty))
+ } else {
+ !ty.has_escaping_bound_vars()
+ && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok()
+ && !ty.is_freeze(cx.tcx, cx.param_env)
+ }
+ },
+ _ => false,
+ }
}
}
diff --git a/src/tools/clippy/clippy_lints/src/mut_mut.rs b/src/tools/clippy/clippy_lints/src/mut_mut.rs
index cb16f0004..bc90e131b 100644
--- a/src/tools/clippy/clippy_lints/src/mut_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_mut.rs
@@ -68,13 +68,15 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
expr.span,
"generally you want to avoid `&mut &mut _` if possible",
);
- } else if let ty::Ref(_, _, hir::Mutability::Mut) = self.cx.typeck_results().expr_ty(e).kind() {
- span_lint(
- self.cx,
- MUT_MUT,
- expr.span,
- "this expression mutably borrows a mutable reference. Consider reborrowing",
- );
+ } else if let ty::Ref(_, ty, hir::Mutability::Mut) = self.cx.typeck_results().expr_ty(e).kind() {
+ if ty.peel_refs().is_sized(self.cx.tcx, self.cx.param_env) {
+ span_lint(
+ self.cx,
+ MUT_MUT,
+ expr.span,
+ "this expression mutably borrows a mutable reference. Consider reborrowing",
+ );
+ }
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs
index 10c3ff026..498e1408e 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs
@@ -36,14 +36,14 @@ declare_clippy_lint! {
declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]);
impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
- fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
- if pat.span.from_expansion() {
+ fn check_pat(&mut self, cx: &LateContext<'tcx>, ref_pat: &'tcx Pat<'_>) {
+ if ref_pat.span.from_expansion() {
// OK, simple enough, lints doesn't check in macro.
return;
}
// Do not lint patterns that are part of an OR `|` pattern, the binding mode must match in all arms
- for (_, node) in cx.tcx.hir().parent_iter(pat.hir_id) {
+ for (_, node) in cx.tcx.hir().parent_iter(ref_pat.hir_id) {
let Node::Pat(pat) = node else { break };
if matches!(pat.kind, PatKind::Or(_)) {
@@ -52,20 +52,20 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
}
// Only lint immutable refs, because `&mut ref T` may be useful.
- let PatKind::Ref(sub_pat, Mutability::Not) = pat.kind else { return };
+ let PatKind::Ref(pat, Mutability::Not) = ref_pat.kind else { return };
- match sub_pat.kind {
+ match pat.kind {
// Check sub_pat got a `ref` keyword (excluding `ref mut`).
PatKind::Binding(BindingAnnotation::REF, _, ident, None) => {
span_lint_and_then(
cx,
NEEDLESS_BORROWED_REFERENCE,
- pat.span,
+ ref_pat.span,
"this pattern takes a reference on something that is being dereferenced",
|diag| {
// `&ref ident`
// ^^^^^
- let span = pat.span.until(ident.span);
+ let span = ref_pat.span.until(ident.span);
diag.span_suggestion_verbose(
span,
"try removing the `&ref` part",
@@ -84,41 +84,71 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
}),
after,
) => {
- let mut suggestions = Vec::new();
-
- for element_pat in itertools::chain(before, after) {
- if let PatKind::Binding(BindingAnnotation::REF, _, ident, None) = element_pat.kind {
- // `&[..., ref ident, ...]`
- // ^^^^
- let span = element_pat.span.until(ident.span);
- suggestions.push((span, String::new()));
- } else {
- return;
- }
- }
+ check_subpatterns(
+ cx,
+ "dereferencing a slice pattern where every element takes a reference",
+ ref_pat,
+ pat,
+ itertools::chain(before, after),
+ );
+ },
+ PatKind::Tuple(subpatterns, _) | PatKind::TupleStruct(_, subpatterns, _) => {
+ check_subpatterns(
+ cx,
+ "dereferencing a tuple pattern where every element takes a reference",
+ ref_pat,
+ pat,
+ subpatterns,
+ );
+ },
+ PatKind::Struct(_, fields, _) => {
+ check_subpatterns(
+ cx,
+ "dereferencing a struct pattern where every field's pattern takes a reference",
+ ref_pat,
+ pat,
+ fields.iter().map(|field| field.pat),
+ );
+ },
+ _ => {},
+ }
+ }
+}
- if !suggestions.is_empty() {
- span_lint_and_then(
- cx,
- NEEDLESS_BORROWED_REFERENCE,
- pat.span,
- "dereferencing a slice pattern where every element takes a reference",
- |diag| {
- // `&[...]`
- // ^
- let span = pat.span.until(sub_pat.span);
- suggestions.push((span, String::new()));
+fn check_subpatterns<'tcx>(
+ cx: &LateContext<'tcx>,
+ message: &str,
+ ref_pat: &Pat<'_>,
+ pat: &Pat<'_>,
+ subpatterns: impl IntoIterator<Item = &'tcx Pat<'tcx>>,
+) {
+ let mut suggestions = Vec::new();
- diag.multipart_suggestion(
- "try removing the `&` and `ref` parts",
- suggestions,
- Applicability::MachineApplicable,
- );
- },
- );
- }
+ for subpattern in subpatterns {
+ match subpattern.kind {
+ PatKind::Binding(BindingAnnotation::REF, _, ident, None) => {
+ // `ref ident`
+ // ^^^^
+ let span = subpattern.span.until(ident.span);
+ suggestions.push((span, String::new()));
},
- _ => {},
+ PatKind::Wild => {},
+ _ => return,
}
}
+
+ if !suggestions.is_empty() {
+ span_lint_and_then(cx, NEEDLESS_BORROWED_REFERENCE, ref_pat.span, message, |diag| {
+ // `&pat`
+ // ^
+ let span = ref_pat.span.until(pat.span);
+ suggestions.push((span, String::new()));
+
+ diag.multipart_suggestion(
+ "try removing the `&` and `ref` parts",
+ suggestions,
+ Applicability::MachineApplicable,
+ );
+ });
+ }
}
diff --git a/src/tools/clippy/clippy_lints/src/needless_continue.rs b/src/tools/clippy/clippy_lints/src/needless_continue.rs
index 6f0e75546..38a75034c 100644
--- a/src/tools/clippy/clippy_lints/src/needless_continue.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_continue.rs
@@ -287,7 +287,7 @@ const DROP_ELSE_BLOCK_MSG: &str = "consider dropping the `else` clause";
const DROP_CONTINUE_EXPRESSION_MSG: &str = "consider dropping the `continue` expression";
-fn emit_warning<'a>(cx: &EarlyContext<'_>, data: &'a LintData<'_>, header: &str, typ: LintType) {
+fn emit_warning(cx: &EarlyContext<'_>, data: &LintData<'_>, header: &str, typ: LintType) {
// snip is the whole *help* message that appears after the warning.
// message is the warning message.
// expr is the expression which the lint warning message refers to.
@@ -313,7 +313,7 @@ fn emit_warning<'a>(cx: &EarlyContext<'_>, data: &'a LintData<'_>, header: &str,
);
}
-fn suggestion_snippet_for_continue_inside_if<'a>(cx: &EarlyContext<'_>, data: &'a LintData<'_>) -> String {
+fn suggestion_snippet_for_continue_inside_if(cx: &EarlyContext<'_>, data: &LintData<'_>) -> String {
let cond_code = snippet(cx, data.if_cond.span, "..");
let continue_code = snippet_block(cx, data.if_block.span, "..", Some(data.if_expr.span));
@@ -327,7 +327,7 @@ fn suggestion_snippet_for_continue_inside_if<'a>(cx: &EarlyContext<'_>, data: &'
)
}
-fn suggestion_snippet_for_continue_inside_else<'a>(cx: &EarlyContext<'_>, data: &'a LintData<'_>) -> String {
+fn suggestion_snippet_for_continue_inside_else(cx: &EarlyContext<'_>, data: &LintData<'_>) -> String {
let cond_code = snippet(cx, data.if_cond.span, "..");
// Region B
@@ -361,7 +361,7 @@ fn suggestion_snippet_for_continue_inside_else<'a>(cx: &EarlyContext<'_>, data:
)
}
-fn check_and_warn<'a>(cx: &EarlyContext<'_>, expr: &'a ast::Expr) {
+fn check_and_warn(cx: &EarlyContext<'_>, expr: &ast::Expr) {
if_chain! {
if let ast::ExprKind::Loop(loop_block, ..) = &expr.kind;
if let Some(last_stmt) = loop_block.stmts.last();
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index b2e9ce5c9..2f0b7ce16 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -1,7 +1,9 @@
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
use clippy_utils::ptr::get_spans;
use clippy_utils::source::{snippet, snippet_opt};
-use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item};
+use clippy_utils::ty::{
+ implements_trait, implements_trait_with_env, is_copy, is_type_diagnostic_item, is_type_lang_item,
+};
use clippy_utils::{get_trait_def_id, is_self, paths};
use if_chain::if_chain;
use rustc_ast::ast::Attribute;
@@ -11,7 +13,7 @@ use rustc_hir::intravisit::FnKind;
use rustc_hir::{
BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Mutability, Node, PatKind, QPath, TyKind,
};
-use rustc_hir::{HirIdMap, HirIdSet};
+use rustc_hir::{HirIdMap, HirIdSet, LangItem};
use rustc_hir_typeck::expr_use_visitor as euv;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
@@ -124,7 +126,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
.filter_map(|obligation| {
// Note that we do not want to deal with qualified predicates here.
match obligation.predicate.kind().no_bound_vars() {
- Some(ty::PredicateKind::Trait(pred)) if pred.def_id() != sized_trait => Some(pred),
+ Some(ty::PredicateKind::Clause(ty::Clause::Trait(pred))) if pred.def_id() != sized_trait => {
+ Some(pred)
+ },
_ => None,
}
})
@@ -185,7 +189,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
if !ty.is_mutable_ptr();
if !is_copy(cx, ty);
if ty.is_sized(cx.tcx, cx.param_env);
- if !allowed_traits.iter().any(|&t| implements_trait(cx, ty, t, &[]));
+ if !allowed_traits.iter().any(|&t| implements_trait_with_env(cx.tcx, cx.param_env, ty, t, [None]));
if !implements_borrow_trait;
if !all_borrowable_trait;
@@ -249,7 +253,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
}
}
- if is_type_diagnostic_item(cx, ty, sym::String) {
+ if is_type_lang_item(cx, ty, LangItem::String) {
if let Some(clone_spans) =
get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) {
diag.span_suggestion(
@@ -340,11 +344,5 @@ impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt {
fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {}
- fn fake_read(
- &mut self,
- _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>,
- _: FakeReadCause,
- _: HirId,
- ) {
- }
+ fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
}
diff --git a/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs b/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs
index 5c2b96f5b..a022fc156 100644
--- a/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs
+++ b/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs
@@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for NoNegCompOpForPartialOrd {
let implements_partial_ord = {
if let Some(id) = cx.tcx.lang_items().partial_ord_trait() {
- implements_trait(cx, ty, id, &[])
+ implements_trait(cx, ty, id, &[ty.into()])
} else {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 819646bb6..79c1ae486 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -6,7 +6,8 @@ use clippy_utils::ty::has_drop;
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, PatKind, Stmt, StmtKind, UnsafeSource};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use std::ops::Deref;
@@ -159,8 +160,11 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
fn check_unnecessary_operation(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
if_chain! {
if let StmtKind::Semi(expr) = stmt.kind;
+ let ctxt = stmt.span.ctxt();
+ if expr.span.ctxt() == ctxt;
if let Some(reduced) = reduce_expression(cx, expr);
- if !&reduced.iter().any(|e| e.span.from_expansion());
+ if !in_external_macro(cx.sess(), stmt.span);
+ if reduced.iter().all(|e| e.span.ctxt() == ctxt);
then {
if let ExprKind::Index(..) = &expr.kind {
let snippet = if let (Some(arr), Some(func)) =
diff --git a/src/tools/clippy/clippy_lints/src/octal_escapes.rs b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
index f380a5065..ae0a41db9 100644
--- a/src/tools/clippy/clippy_lints/src/octal_escapes.rs
+++ b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
@@ -56,11 +56,11 @@ impl EarlyLintPass for OctalEscapes {
return;
}
- if let ExprKind::Lit(lit) = &expr.kind {
- if matches!(lit.token_lit.kind, LitKind::Str) {
- check_lit(cx, &lit.token_lit, lit.span, true);
- } else if matches!(lit.token_lit.kind, LitKind::ByteStr) {
- check_lit(cx, &lit.token_lit, lit.span, false);
+ if let ExprKind::Lit(token_lit) = &expr.kind {
+ if matches!(token_lit.kind, LitKind::Str) {
+ check_lit(cx, token_lit, expr.span, true);
+ } else if matches!(token_lit.kind, LitKind::ByteStr) {
+ check_lit(cx, token_lit, expr.span, false);
}
}
}
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 8827daaa3..20b82d81a 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,5 +1,9 @@
use super::ARITHMETIC_SIDE_EFFECTS;
-use clippy_utils::{consts::constant_simple, diagnostics::span_lint};
+use clippy_utils::{
+ consts::{constant, constant_simple},
+ diagnostics::span_lint,
+ peel_hir_expr_refs,
+};
use rustc_ast as ast;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
@@ -38,24 +42,6 @@ impl ArithmeticSideEffects {
}
}
- /// Assuming that `expr` is a literal integer, checks operators (+=, -=, *, /) in a
- /// non-constant environment that won't overflow.
- fn has_valid_op(op: &Spanned<hir::BinOpKind>, expr: &hir::Expr<'_>) -> bool {
- if let hir::ExprKind::Lit(ref lit) = expr.kind &&
- let ast::LitKind::Int(value, _) = lit.node
- {
- match (&op.node, value) {
- (hir::BinOpKind::Div | hir::BinOpKind::Rem, 0) => false,
- (hir::BinOpKind::Add | hir::BinOpKind::Sub, 0)
- | (hir::BinOpKind::Div | hir::BinOpKind::Rem, _)
- | (hir::BinOpKind::Mul, 0 | 1) => true,
- _ => false,
- }
- } else {
- false
- }
- }
-
/// Checks if the given `expr` has any of the inner `allowed` elements.
fn is_allowed_ty(&self, ty: Ty<'_>) -> bool {
self.allowed
@@ -74,15 +60,14 @@ impl ArithmeticSideEffects {
self.expr_span = Some(expr.span);
}
- /// If `expr` does not match any variant of `LiteralIntegerTy`, returns `None`.
- fn literal_integer<'expr, 'tcx>(expr: &'expr hir::Expr<'tcx>) -> Option<LiteralIntegerTy<'expr, 'tcx>> {
- if matches!(expr.kind, hir::ExprKind::Lit(_)) {
- return Some(LiteralIntegerTy::Value(expr));
+ /// If `expr` is not a literal integer like `1`, returns `None`.
+ fn literal_integer(expr: &hir::Expr<'_>) -> Option<u128> {
+ if let hir::ExprKind::Lit(ref lit) = expr.kind && let ast::LitKind::Int(n, _) = lit.node {
+ Some(n)
}
- if let hir::ExprKind::AddrOf(.., inn) = expr.kind && let hir::ExprKind::Lit(_) = inn.kind {
- return Some(LiteralIntegerTy::Ref(inn));
+ else {
+ None
}
- None
}
/// Manages when the lint should be triggered. Operations in constant environments, hard coded
@@ -117,10 +102,20 @@ impl ArithmeticSideEffects {
return;
}
let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) {
- match (Self::literal_integer(lhs), Self::literal_integer(rhs)) {
- (None, Some(lit_int_ty)) | (Some(lit_int_ty), None) => Self::has_valid_op(op, lit_int_ty.into()),
- (Some(LiteralIntegerTy::Value(_)), Some(LiteralIntegerTy::Value(_))) => true,
- (None, None) | (Some(_), Some(_)) => false,
+ let (actual_lhs, lhs_ref_counter) = peel_hir_expr_refs(lhs);
+ let (actual_rhs, rhs_ref_counter) = peel_hir_expr_refs(rhs);
+ match (Self::literal_integer(actual_lhs), Self::literal_integer(actual_rhs)) {
+ (None, None) => false,
+ (None, Some(n)) | (Some(n), None) => match (&op.node, n) {
+ (hir::BinOpKind::Div | hir::BinOpKind::Rem, 0) => false,
+ (hir::BinOpKind::Add | hir::BinOpKind::Sub, 0)
+ | (hir::BinOpKind::Div | hir::BinOpKind::Rem, _)
+ | (hir::BinOpKind::Mul, 0 | 1) => true,
+ _ => false,
+ },
+ (Some(_), Some(_)) => {
+ matches!((lhs_ref_counter, rhs_ref_counter), (0, 0))
+ },
}
} else {
false
@@ -129,21 +124,45 @@ impl ArithmeticSideEffects {
self.issue_lint(cx, expr);
}
}
+
+ fn manage_unary_ops<'tcx>(
+ &mut self,
+ cx: &LateContext<'tcx>,
+ expr: &hir::Expr<'tcx>,
+ un_expr: &hir::Expr<'tcx>,
+ un_op: hir::UnOp,
+ ) {
+ let hir::UnOp::Neg = un_op else { return; };
+ if constant(cx, cx.typeck_results(), un_expr).is_some() {
+ return;
+ }
+ let ty = cx.typeck_results().expr_ty(expr).peel_refs();
+ if self.is_allowed_ty(ty) {
+ return;
+ }
+ let actual_un_expr = peel_hir_expr_refs(un_expr).0;
+ if Self::literal_integer(actual_un_expr).is_some() {
+ return;
+ }
+ self.issue_lint(cx, expr);
+ }
+
+ fn should_skip_expr(&mut self, expr: &hir::Expr<'_>) -> bool {
+ self.expr_span.is_some() || self.const_span.map_or(false, |sp| sp.contains(expr.span))
+ }
}
impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) {
- if self.expr_span.is_some() || self.const_span.map_or(false, |sp| sp.contains(expr.span)) {
+ if self.should_skip_expr(expr) {
return;
}
match &expr.kind {
- hir::ExprKind::Binary(op, lhs, rhs) | hir::ExprKind::AssignOp(op, lhs, rhs) => {
+ hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => {
self.manage_bin_ops(cx, expr, op, lhs, rhs);
},
- hir::ExprKind::Unary(hir::UnOp::Neg, _) => {
- if constant_simple(cx, cx.typeck_results(), expr).is_none() {
- self.issue_lint(cx, expr);
- }
+ hir::ExprKind::Unary(un_op, un_expr) => {
+ self.manage_unary_ops(cx, expr, un_expr, *un_op);
},
_ => {},
}
@@ -177,22 +196,3 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
}
}
}
-
-/// Tells if an expression is a integer declared by value or by reference.
-///
-/// If `LiteralIntegerTy::Ref`, then the contained value will be `hir::ExprKind::Lit` rather
-/// than `hirExprKind::Addr`.
-enum LiteralIntegerTy<'expr, 'tcx> {
- /// For example, `&199`
- Ref(&'expr hir::Expr<'tcx>),
- /// For example, `1` or `i32::MAX`
- Value(&'expr hir::Expr<'tcx>),
-}
-
-impl<'expr, 'tcx> From<LiteralIntegerTy<'expr, 'tcx>> for &'expr hir::Expr<'tcx> {
- fn from(from: LiteralIntegerTy<'expr, 'tcx>) -> Self {
- match from {
- LiteralIntegerTy::Ref(elem) | LiteralIntegerTy::Value(elem) => elem,
- }
- }
-}
diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
index ee9fd9406..9bbf385fb 100644
--- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
@@ -28,7 +28,7 @@ pub(super) fn check<'tcx>(
let rty = cx.typeck_results().expr_ty(rhs);
if_chain! {
if let Some((_, lang_item)) = binop_traits(op.node);
- if let Ok(trait_id) = cx.tcx.lang_items().require(lang_item);
+ if let Some(trait_id) = cx.tcx.lang_items().get(lang_item);
let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id).def_id;
if trait_ref_of_method(cx, parent_fn)
.map_or(true, |t| t.path.res.def_id() != trait_id);
diff --git a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
index 71b31b5e4..d7917e86a 100644
--- a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
@@ -199,7 +199,7 @@ fn in_impl<'tcx>(
}
}
-fn are_equal<'tcx>(cx: &LateContext<'tcx>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool {
+fn are_equal(cx: &LateContext<'_>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool {
if_chain! {
if let ty::Adt(adt_def, _) = middle_ty.kind();
if let Some(local_did) = adt_def.did().as_local();
diff --git a/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs b/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs
index d9ee031c9..377bddeaa 100644
--- a/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/option_env_unwrap.rs
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::is_direct_expn_of;
use if_chain::if_chain;
-use rustc_ast::ast::{Expr, ExprKind};
+use rustc_ast::ast::{Expr, ExprKind, MethodCall};
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
@@ -37,8 +37,8 @@ declare_lint_pass!(OptionEnvUnwrap => [OPTION_ENV_UNWRAP]);
impl EarlyLintPass for OptionEnvUnwrap {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
if_chain! {
- if let ExprKind::MethodCall(path_segment, receiver, _, _) = &expr.kind;
- if matches!(path_segment.ident.name, sym::expect | sym::unwrap);
+ if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind;
+ if matches!(seg.ident.name, sym::expect | sym::unwrap);
if let ExprKind::Call(caller, _) = &receiver.kind;
if is_direct_expn_of(caller.span, "option_env").is_some();
then {
diff --git a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
index 4eb42da1f..472f52380 100644
--- a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
@@ -213,11 +213,14 @@ fn try_convert_match<'tcx>(
cx: &LateContext<'tcx>,
arms: &[Arm<'tcx>],
) -> Option<(&'tcx Pat<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> {
- if arms.len() == 2 {
- return if is_none_or_err_arm(cx, &arms[1]) {
- Some((arms[0].pat, arms[0].body, arms[1].body))
- } else if is_none_or_err_arm(cx, &arms[0]) {
- Some((arms[1].pat, arms[1].body, arms[0].body))
+ if let [first_arm, second_arm] = arms
+ && first_arm.guard.is_none()
+ && second_arm.guard.is_none()
+ {
+ return if is_none_or_err_arm(cx, second_arm) {
+ Some((first_arm.pat, first_arm.body, second_arm.body))
+ } else if is_none_or_err_arm(cx, first_arm) {
+ Some((second_arm.pat, second_arm.body, first_arm.body))
} else {
None
};
diff --git a/src/tools/clippy/clippy_lints/src/partialeq_to_none.rs b/src/tools/clippy/clippy_lints/src/partialeq_to_none.rs
index 6810a2431..456ded3fc 100644
--- a/src/tools/clippy/clippy_lints/src/partialeq_to_none.rs
+++ b/src/tools/clippy/clippy_lints/src/partialeq_to_none.rs
@@ -33,7 +33,7 @@ declare_clippy_lint! {
/// if f.is_some() { "yay" } else { "nay" }
/// }
/// ```
- #[clippy::version = "1.64.0"]
+ #[clippy::version = "1.65.0"]
pub PARTIALEQ_TO_NONE,
style,
"Binary comparison to `Option<T>::None` relies on `T: PartialEq`, which is unneeded"
diff --git a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
index a4d265111..97b5a4ce3 100644
--- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
@@ -130,7 +130,7 @@ enum DerefPossible {
Impossible,
}
-fn apply_lint<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>, deref_possible: DerefPossible) -> bool {
+fn apply_lint(cx: &LateContext<'_>, pat: &Pat<'_>, deref_possible: DerefPossible) -> bool {
let maybe_mismatch = find_first_mismatch(cx, pat);
if let Some((span, mutability, level)) = maybe_mismatch {
span_lint_and_help(
@@ -163,7 +163,7 @@ enum Level {
Lower,
}
-fn find_first_mismatch<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>) -> Option<(Span, Mutability, Level)> {
+fn find_first_mismatch(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(Span, Mutability, Level)> {
let mut result = None;
pat.walk(|p| {
if result.is_some() {
diff --git a/src/tools/clippy/clippy_lints/src/precedence.rs b/src/tools/clippy/clippy_lints/src/precedence.rs
index e6e3ad05a..057b7e306 100644
--- a/src/tools/clippy/clippy_lints/src/precedence.rs
+++ b/src/tools/clippy/clippy_lints/src/precedence.rs
@@ -1,7 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use if_chain::if_chain;
-use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind, UnOp};
+use rustc_ast::ast::{BinOpKind, Expr, ExprKind, MethodCall, UnOp};
+use rustc_ast::token;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -109,18 +110,18 @@ impl EarlyLintPass for Precedence {
let mut arg = operand;
let mut all_odd = true;
- while let ExprKind::MethodCall(path_segment, receiver, _, _) = &arg.kind {
- let path_segment_str = path_segment.ident.name.as_str();
+ while let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &arg.kind {
+ let seg_str = seg.ident.name.as_str();
all_odd &= ALLOWED_ODD_FUNCTIONS
.iter()
- .any(|odd_function| **odd_function == *path_segment_str);
+ .any(|odd_function| **odd_function == *seg_str);
arg = receiver;
}
if_chain! {
if !all_odd;
if let ExprKind::Lit(lit) = &arg.kind;
- if let LitKind::Int(..) | LitKind::Float(..) = &lit.kind;
+ if let token::LitKind::Integer | token::LitKind::Float = &lit.kind;
then {
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 0d74c90a8..e395ff54c 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -12,14 +12,14 @@ use rustc_hir::hir_id::HirIdMap;
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{
self as hir, AnonConst, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg,
- ImplItemKind, ItemKind, Lifetime, LifetimeName, Mutability, Node, Param, ParamName, PatKind, QPath, TraitFn,
- TraitItem, TraitItemKind, TyKind, Unsafety,
+ ImplItemKind, ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind,
+ TyKind, Unsafety,
};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{Obligation, ObligationCause};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::{self, Binder, ExistentialPredicate, List, PredicateKind, Ty};
+use rustc_middle::ty::{self, Binder, Clause, ExistentialPredicate, List, PredicateKind, Ty};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
use rustc_span::sym;
@@ -343,21 +343,16 @@ impl PtrArg<'_> {
}
struct RefPrefix {
- lt: LifetimeName,
+ lt: Lifetime,
mutability: Mutability,
}
impl fmt::Display for RefPrefix {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use fmt::Write;
f.write_char('&')?;
- match self.lt {
- LifetimeName::Param(_, ParamName::Plain(name)) => {
- name.fmt(f)?;
- f.write_char(' ')?;
- },
- LifetimeName::Infer => f.write_str("'_ ")?,
- LifetimeName::Static => f.write_str("'static ")?,
- _ => (),
+ if !self.lt.is_anonymous() {
+ self.lt.ident.fmt(f)?;
+ f.write_char(' ')?;
}
f.write_str(self.mutability.prefix_str())
}
@@ -450,7 +445,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
substs.type_at(0),
),
),
- Some(sym::String) => (
+ _ if Some(adt.did()) == cx.tcx.lang_items().string() => (
[("clone", ".to_owned()"), ("as_str", "")].as_slice(),
DerefTy::Str,
),
@@ -495,7 +490,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
ty_name: name.ident.name,
method_renames,
ref_prefix: RefPrefix {
- lt: lt.name,
+ lt: *lt,
mutability,
},
deref_ty,
@@ -687,23 +682,24 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
fn matches_preds<'tcx>(
cx: &LateContext<'tcx>,
ty: Ty<'tcx>,
- preds: &'tcx [Binder<'tcx, ExistentialPredicate<'tcx>>],
+ preds: &'tcx [ty::PolyExistentialPredicate<'tcx>],
) -> bool {
let infcx = cx.tcx.infer_ctxt().build();
preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) {
ExistentialPredicate::Trait(p) => infcx
- .type_implements_trait(p.def_id, ty, p.substs, cx.param_env)
+ .type_implements_trait(p.def_id, [ty.into()].into_iter().chain(p.substs.iter()), cx.param_env)
.must_apply_modulo_regions(),
ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new(
+ cx.tcx,
ObligationCause::dummy(),
cx.param_env,
- cx.tcx.mk_predicate(Binder::bind_with_vars(
- PredicateKind::Projection(p.with_self_ty(cx.tcx, ty)),
- List::empty(),
- )),
+ cx.tcx
+ .mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Projection(
+ p.with_self_ty(cx.tcx, ty),
+ )))),
)),
ExistentialPredicate::AutoTrait(p) => infcx
- .type_implements_trait(p, ty, List::empty(), cx.param_env)
+ .type_implements_trait(p, [ty], cx.param_env)
.must_apply_modulo_regions(),
})
}
diff --git a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
index 72dda67c7..47b8891e1 100644
--- a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
@@ -105,17 +105,17 @@ fn expr_as_ptr_offset_call<'tcx>(
}
// Is the type of the expression a usize?
-fn is_expr_ty_usize<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> bool {
+fn is_expr_ty_usize(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
cx.typeck_results().expr_ty(expr) == cx.tcx.types.usize
}
// Is the type of the expression a raw pointer?
-fn is_expr_ty_raw_ptr<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> bool {
+fn is_expr_ty_raw_ptr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
cx.typeck_results().expr_ty(expr).is_unsafe_ptr()
}
-fn build_suggestion<'tcx>(
- cx: &LateContext<'tcx>,
+fn build_suggestion(
+ cx: &LateContext<'_>,
method: Method,
receiver_expr: &Expr<'_>,
cast_lhs_expr: &Expr<'_>,
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index bb86fb3b7..5269bbd1f 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -189,6 +189,7 @@ fn is_early_return(smbl: Symbol, cx: &LateContext<'_>, if_block: &IfBlockType<'_
&& expr_return_none_or_err(smbl, cx, if_else.unwrap(), let_expr, Some(let_pat_sym)))
|| is_res_lang_ctor(cx, res, ResultErr)
&& expr_return_none_or_err(smbl, cx, if_then, let_expr, Some(let_pat_sym))
+ && if_else.is_none()
},
_ => false,
}
diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs
index c6fbb5e80..0a1b9d173 100644
--- a/src/tools/clippy/clippy_lints/src/ranges.rs
+++ b/src/tools/clippy/clippy_lints/src/ranges.rs
@@ -1,16 +1,16 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::higher;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
-use clippy_utils::{get_parent_expr, in_constant, is_integer_const, meets_msrv, msrvs, path_to_local};
+use clippy_utils::{get_parent_expr, in_constant, is_integer_const, path_to_local};
use if_chain::if_chain;
use rustc_ast::ast::RangeLimits;
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, HirId};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::{Span, Spanned};
use std::cmp::Ordering;
@@ -161,12 +161,12 @@ declare_clippy_lint! {
}
pub struct Ranges {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl Ranges {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -181,7 +181,7 @@ impl_lint_pass!(Ranges => [
impl<'tcx> LateLintPass<'tcx> for Ranges {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let ExprKind::Binary(ref op, l, r) = expr.kind {
- if meets_msrv(self.msrv, msrvs::RANGE_CONTAINS) {
+ if self.msrv.meets(msrvs::RANGE_CONTAINS) {
check_possible_range_contains(cx, op.node, l, r, expr, expr.span);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
index aedbe08e3..c1677fb3d 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
@@ -1,12 +1,12 @@
use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
use clippy_utils::mir::{visit_local_usage, LocalUsage, PossibleBorrowerMap};
use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, walk_ptrs_ty_depth};
+use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, is_type_lang_item, walk_ptrs_ty_depth};
use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
-use rustc_hir::{def_id, Body, FnDecl, HirId};
+use rustc_hir::{def_id, Body, FnDecl, HirId, LangItem};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir;
use rustc_middle::ty::{self, Ty};
@@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD)
|| match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD)
|| (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD)
- && is_type_diagnostic_item(cx, arg_ty, sym::String));
+ && is_type_lang_item(cx, arg_ty, LangItem::String));
let from_deref = !from_borrow
&& (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)
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 74eea6de4..2a42e7348 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -69,10 +69,10 @@ impl EarlyLintPass for RedundantClosureCall {
if_chain! {
if let ast::ExprKind::Call(ref paren, _) = expr.kind;
if let ast::ExprKind::Paren(ref closure) = paren.kind;
- if let ast::ExprKind::Closure(_, _, ref r#async, _, ref decl, ref block, _) = closure.kind;
+ if let ast::ExprKind::Closure(box ast::Closure { ref asyncness, ref fn_decl, ref body, .. }) = closure.kind;
then {
let mut visitor = ReturnVisitor::new();
- visitor.visit_expr(block);
+ visitor.visit_expr(body);
if !visitor.found_return {
span_lint_and_then(
cx,
@@ -80,13 +80,13 @@ impl EarlyLintPass for RedundantClosureCall {
expr.span,
"try not to call a closure in the expression where it is declared",
|diag| {
- if decl.inputs.is_empty() {
- let app = Applicability::MachineApplicable;
- let mut hint = Sugg::ast(cx, block, "..");
+ if fn_decl.inputs.is_empty() {
+ let mut app = Applicability::MachineApplicable;
+ let mut hint = Sugg::ast(cx, body, "..", closure.span.ctxt(), &mut app);
- if r#async.is_async() {
+ if asyncness.is_async() {
// `async x` is a syntax error, so it becomes `async { x }`
- if !matches!(block.kind, ast::ExprKind::Block(_, _)) {
+ if !matches!(body.kind, ast::ExprKind::Block(_, _)) {
hint = hint.blockify();
}
@@ -105,8 +105,8 @@ impl EarlyLintPass for RedundantClosureCall {
impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
- fn count_closure_usage<'a, 'tcx>(
- cx: &'a LateContext<'tcx>,
+ fn count_closure_usage<'tcx>(
+ cx: &LateContext<'tcx>,
block: &'tcx hir::Block<'_>,
path: &'tcx hir::Path<'tcx>,
) -> usize {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
index 40b03068f..61bff4a0e 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
@@ -1,10 +1,9 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{meets_msrv, msrvs};
+use clippy_utils::msrvs::{self, Msrv};
use rustc_ast::ast::{Expr, ExprKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! {
@@ -37,12 +36,12 @@ declare_clippy_lint! {
}
pub struct RedundantFieldNames {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl RedundantFieldNames {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -51,7 +50,7 @@ impl_lint_pass!(RedundantFieldNames => [REDUNDANT_FIELD_NAMES]);
impl EarlyLintPass for RedundantFieldNames {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
- if !meets_msrv(self.msrv, msrvs::FIELD_INIT_SHORTHAND) {
+ if !self.msrv.meets(msrvs::FIELD_INIT_SHORTHAND) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
index 26075e9f7..d612d249c 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
@@ -70,7 +70,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
}
if let ItemKind::Mod { .. } = item.kind {
- self.is_exported.push(cx.effective_visibilities.is_exported(item.owner_id.def_id));
+ self.is_exported
+ .push(cx.effective_visibilities.is_exported(item.owner_id.def_id));
}
}
@@ -83,7 +84,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
fn is_not_macro_export<'tcx>(item: &'tcx Item<'tcx>) -> bool {
if let ItemKind::Use(path, _) = item.kind {
- if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = path.res {
+ if path.res.iter().all(|res| matches!(res, Res::Def(DefKind::Macro(MacroKind::Bang), _))) {
return false;
}
} else if let ItemKind::Macro(..) = item.kind {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
index 60ba62c4a..3aa2490bc 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
@@ -1,10 +1,9 @@
use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
-use clippy_utils::{meets_msrv, msrvs};
use rustc_ast::ast::{Item, ItemKind, Ty, TyKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
declare_clippy_lint! {
@@ -34,12 +33,12 @@ declare_clippy_lint! {
}
pub struct RedundantStaticLifetimes {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl RedundantStaticLifetimes {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -96,7 +95,7 @@ impl RedundantStaticLifetimes {
impl EarlyLintPass for RedundantStaticLifetimes {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
- if !meets_msrv(self.msrv, msrvs::STATIC_IN_CONST) {
+ if !self.msrv.meets(msrvs::STATIC_IN_CONST) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
index 76d6ad0b2..8e214218f 100644
--- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
@@ -11,8 +11,6 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
("clippy::disallowed_method", "clippy::disallowed_methods"),
("clippy::disallowed_type", "clippy::disallowed_types"),
("clippy::eval_order_dependence", "clippy::mixed_read_write_in_expression"),
- ("clippy::for_loop_over_option", "for_loops_over_fallibles"),
- ("clippy::for_loop_over_result", "for_loops_over_fallibles"),
("clippy::identity_conversion", "clippy::useless_conversion"),
("clippy::if_let_some_result", "clippy::match_result_ok"),
("clippy::logic_bug", "clippy::overly_complex_bool_expr"),
@@ -31,10 +29,13 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
("clippy::to_string_in_display", "clippy::recursive_format_impl"),
("clippy::zero_width_space", "clippy::invisible_characters"),
("clippy::drop_bounds", "drop_bounds"),
+ ("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::into_iter_on_array", "array_into_iter"),
("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"),
("clippy::invalid_ref", "invalid_value"),
+ ("clippy::let_underscore_drop", "let_underscore_drop"),
("clippy::mem_discriminant_non_enum", "enum_intrinsics_non_enums"),
("clippy::panic_params", "non_fmt_panics"),
("clippy::positional_named_format_parameters", "named_arguments_used_positionally"),
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 2b2a41d16..81143d779 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -12,6 +12,7 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
+use rustc_span::{BytePos, Pos};
declare_clippy_lint! {
/// ### What it does
@@ -209,13 +210,14 @@ fn check_final_expr<'tcx>(
if cx.tcx.hir().attrs(expr.hir_id).is_empty() {
let borrows = inner.map_or(false, |inner| last_statement_borrows(cx, inner));
if !borrows {
- emit_return_lint(
- cx,
- peeled_drop_expr.span,
- semi_spans,
- inner.as_ref().map(|i| i.span),
- replacement,
- );
+ // check if expr return nothing
+ let ret_span = if inner.is_none() && replacement == RetReplacement::Empty {
+ extend_span_to_previous_non_ws(cx, peeled_drop_expr.span)
+ } else {
+ peeled_drop_expr.span
+ };
+
+ emit_return_lint(cx, ret_span, semi_spans, inner.as_ref().map(|i| i.span), replacement);
}
}
},
@@ -289,3 +291,16 @@ fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>)
})
.is_some()
}
+
+// Go backwards while encountering whitespace and extend the given Span to that point.
+fn extend_span_to_previous_non_ws(cx: &LateContext<'_>, sp: Span) -> Span {
+ if let Ok(prev_source) = cx.sess().source_map().span_to_prev_source(sp) {
+ let ws = [' ', '\t', '\n'];
+ if let Some(non_ws_pos) = prev_source.rfind(|c| !ws.contains(&c)) {
+ let len = prev_source.len() - non_ws_pos - 1;
+ return sp.with_lo(sp.lo() - BytePos::from_usize(len));
+ }
+ }
+
+ sp
+}
diff --git a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
index 66b795130..d46f6a635 100644
--- a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
@@ -1,8 +1,9 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
+use rustc_ast::node_id::{NodeId, NodeMap};
use rustc_ast::{ptr::P, Crate, Item, ItemKind, MacroDef, ModKind, UseTreeKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::{edition::Edition, symbol::kw, Span, Symbol};
declare_clippy_lint! {
@@ -33,51 +34,32 @@ declare_clippy_lint! {
"imports with single component path are redundant"
}
-declare_lint_pass!(SingleComponentPathImports => [SINGLE_COMPONENT_PATH_IMPORTS]);
+#[derive(Default)]
+pub struct SingleComponentPathImports {
+ /// Buffer found usages to emit when visiting that item so that `#[allow]` works as expected
+ found: NodeMap<Vec<SingleUse>>,
+}
+
+struct SingleUse {
+ name: Symbol,
+ span: Span,
+ item_id: NodeId,
+ can_suggest: bool,
+}
+
+impl_lint_pass!(SingleComponentPathImports => [SINGLE_COMPONENT_PATH_IMPORTS]);
impl EarlyLintPass for SingleComponentPathImports {
fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) {
if cx.sess().opts.edition < Edition::Edition2018 {
return;
}
- check_mod(cx, &krate.items);
- }
-}
-fn check_mod(cx: &EarlyContext<'_>, items: &[P<Item>]) {
- // keep track of imports reused with `self` keyword,
- // such as `self::crypto_hash` in the example below
- // ```rust,ignore
- // use self::crypto_hash::{Algorithm, Hasher};
- // ```
- let mut imports_reused_with_self = Vec::new();
-
- // keep track of single use statements
- // such as `crypto_hash` in the example below
- // ```rust,ignore
- // use crypto_hash;
- // ```
- let mut single_use_usages = Vec::new();
-
- // keep track of macros defined in the module as we don't want it to trigger on this (#7106)
- // ```rust,ignore
- // macro_rules! foo { () => {} };
- // pub(crate) use foo;
- // ```
- let mut macros = Vec::new();
-
- for item in items {
- track_uses(
- cx,
- item,
- &mut imports_reused_with_self,
- &mut single_use_usages,
- &mut macros,
- );
+ self.check_mod(cx, &krate.items);
}
- for (name, span, can_suggest) in single_use_usages {
- if !imports_reused_with_self.contains(&name) {
+ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
+ for SingleUse { span, can_suggest, .. } in self.found.remove(&item.id).into_iter().flatten() {
if can_suggest {
span_lint_and_sugg(
cx,
@@ -102,74 +84,127 @@ fn check_mod(cx: &EarlyContext<'_>, items: &[P<Item>]) {
}
}
-fn track_uses(
- cx: &EarlyContext<'_>,
- item: &Item,
- imports_reused_with_self: &mut Vec<Symbol>,
- single_use_usages: &mut Vec<(Symbol, Span, bool)>,
- macros: &mut Vec<Symbol>,
-) {
- if item.span.from_expansion() || item.vis.kind.is_pub() {
- return;
- }
+impl SingleComponentPathImports {
+ fn check_mod(&mut self, cx: &EarlyContext<'_>, items: &[P<Item>]) {
+ // keep track of imports reused with `self` keyword, such as `self::crypto_hash` in the example
+ // below. Removing the `use crypto_hash;` would make this a compile error
+ // ```
+ // use crypto_hash;
+ //
+ // use self::crypto_hash::{Algorithm, Hasher};
+ // ```
+ let mut imports_reused_with_self = Vec::new();
- match &item.kind {
- ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) => {
- check_mod(cx, items);
- },
- ItemKind::MacroDef(MacroDef { macro_rules: true, .. }) => {
- macros.push(item.ident.name);
- },
- ItemKind::Use(use_tree) => {
- let segments = &use_tree.prefix.segments;
-
- // keep track of `use some_module;` usages
- if segments.len() == 1 {
- if let UseTreeKind::Simple(None, _, _) = use_tree.kind {
- let name = segments[0].ident.name;
- if !macros.contains(&name) {
- single_use_usages.push((name, item.span, true));
- }
- }
- return;
+ // keep track of single use statements such as `crypto_hash` in the example below
+ // ```
+ // use crypto_hash;
+ // ```
+ let mut single_use_usages = Vec::new();
+
+ // keep track of macros defined in the module as we don't want it to trigger on this (#7106)
+ // ```
+ // macro_rules! foo { () => {} };
+ // pub(crate) use foo;
+ // ```
+ let mut macros = Vec::new();
+
+ for item in items {
+ self.track_uses(
+ cx,
+ item,
+ &mut imports_reused_with_self,
+ &mut single_use_usages,
+ &mut macros,
+ );
+ }
+
+ for usage in single_use_usages {
+ if !imports_reused_with_self.contains(&usage.name) {
+ self.found.entry(usage.item_id).or_default().push(usage);
}
+ }
+ }
- if segments.is_empty() {
- // keep track of `use {some_module, some_other_module};` usages
- if let UseTreeKind::Nested(trees) = &use_tree.kind {
- for tree in trees {
- let segments = &tree.0.prefix.segments;
- if segments.len() == 1 {
- if let UseTreeKind::Simple(None, _, _) = tree.0.kind {
- let name = segments[0].ident.name;
- if !macros.contains(&name) {
- single_use_usages.push((name, tree.0.span, false));
- }
- }
+ fn track_uses(
+ &mut self,
+ cx: &EarlyContext<'_>,
+ item: &Item,
+ imports_reused_with_self: &mut Vec<Symbol>,
+ single_use_usages: &mut Vec<SingleUse>,
+ macros: &mut Vec<Symbol>,
+ ) {
+ if item.span.from_expansion() || item.vis.kind.is_pub() {
+ return;
+ }
+
+ match &item.kind {
+ ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) => {
+ self.check_mod(cx, items);
+ },
+ ItemKind::MacroDef(MacroDef { macro_rules: true, .. }) => {
+ macros.push(item.ident.name);
+ },
+ ItemKind::Use(use_tree) => {
+ let segments = &use_tree.prefix.segments;
+
+ // keep track of `use some_module;` usages
+ if segments.len() == 1 {
+ if let UseTreeKind::Simple(None) = use_tree.kind {
+ let name = segments[0].ident.name;
+ if !macros.contains(&name) {
+ single_use_usages.push(SingleUse {
+ name,
+ span: item.span,
+ item_id: item.id,
+ can_suggest: true,
+ });
}
}
+ return;
}
- } else {
- // keep track of `use self::some_module` usages
- if segments[0].ident.name == kw::SelfLower {
- // simple case such as `use self::module::SomeStruct`
- if segments.len() > 1 {
- imports_reused_with_self.push(segments[1].ident.name);
- return;
- }
- // nested case such as `use self::{module1::Struct1, module2::Struct2}`
+ if segments.is_empty() {
+ // keep track of `use {some_module, some_other_module};` usages
if let UseTreeKind::Nested(trees) = &use_tree.kind {
for tree in trees {
let segments = &tree.0.prefix.segments;
- if !segments.is_empty() {
- imports_reused_with_self.push(segments[0].ident.name);
+ if segments.len() == 1 {
+ if let UseTreeKind::Simple(None) = tree.0.kind {
+ let name = segments[0].ident.name;
+ if !macros.contains(&name) {
+ single_use_usages.push(SingleUse {
+ name,
+ span: tree.0.span,
+ item_id: item.id,
+ can_suggest: false,
+ });
+ }
+ }
+ }
+ }
+ }
+ } else {
+ // keep track of `use self::some_module` usages
+ if segments[0].ident.name == kw::SelfLower {
+ // simple case such as `use self::module::SomeStruct`
+ if segments.len() > 1 {
+ imports_reused_with_self.push(segments[1].ident.name);
+ return;
+ }
+
+ // nested case such as `use self::{module1::Struct1, module2::Struct2}`
+ if let UseTreeKind::Nested(trees) = &use_tree.kind {
+ for tree in trees {
+ let segments = &tree.0.prefix.segments;
+ if !segments.is_empty() {
+ imports_reused_with_self.push(segments[0].ident.name);
+ }
}
}
}
}
- }
- },
- _ => {},
+ },
+ _ => {},
+ }
}
}
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 760399231..a2109038a 100644
--- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
@@ -168,7 +168,7 @@ impl SlowVectorInit {
};
}
- fn emit_lint<'tcx>(cx: &LateContext<'tcx>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocation<'_>, msg: &str) {
+ fn emit_lint(cx: &LateContext<'_>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocation<'_>, msg: &str) {
let len_expr = Sugg::hir(cx, vec_alloc.len_expr, "len");
span_lint_and_then(cx, SLOW_VECTOR_INITIALIZATION, slow_fill.span, msg, |diag| {
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index d356c99c8..f4705481d 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg};
use clippy_utils::source::{snippet, snippet_with_applicability};
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{get_parent_expr, is_lint_allowed, match_function_call, method_calls, paths};
use clippy_utils::{peel_blocks, SpanlessEq};
use if_chain::if_chain;
@@ -190,7 +190,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd {
},
ExprKind::Index(target, _idx) => {
let e_ty = cx.typeck_results().expr_ty(target).peel_refs();
- if matches!(e_ty.kind(), ty::Str) || is_type_diagnostic_item(cx, e_ty, sym::String) {
+ if matches!(e_ty.kind(), ty::Str) || is_type_lang_item(cx, e_ty, LangItem::String) {
span_lint(
cx,
STRING_SLICE,
@@ -205,7 +205,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd {
}
fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
- is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), sym::String)
+ is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
}
fn is_add(cx: &LateContext<'_>, src: &Expr<'_>, target: &Expr<'_>) -> bool {
@@ -446,7 +446,7 @@ impl<'tcx> LateLintPass<'tcx> for StringToString {
if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind;
if path.ident.name == sym::to_string;
let ty = cx.typeck_results().expr_ty(self_arg);
- if is_type_diagnostic_item(cx, ty, sym::String);
+ if is_type_lang_item(cx, ty, LangItem::String);
then {
span_lint_and_help(
cx,
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 eef9bdc78..e111c7d22 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
@@ -580,9 +580,9 @@ fn ident_difference_expr_with_base_location(
| (Await(_), Await(_))
| (Async(_, _, _), Async(_, _, _))
| (Block(_, _), Block(_, _))
- | (Closure(_, _, _, _, _, _, _), Closure(_, _, _, _, _, _, _))
+ | (Closure(_), Closure(_))
| (Match(_, _), Match(_, _))
- | (Loop(_, _), Loop(_, _))
+ | (Loop(_, _, _), Loop(_, _, _))
| (ForLoop(_, _, _, _), ForLoop(_, _, _, _))
| (While(_, _, _), While(_, _, _))
| (If(_, _, _), If(_, _, _))
@@ -593,7 +593,7 @@ fn ident_difference_expr_with_base_location(
| (Unary(_, _), Unary(_, _))
| (Binary(_, _, _), Binary(_, _, _))
| (Tup(_), Tup(_))
- | (MethodCall(_, _, _, _), MethodCall(_, _, _, _))
+ | (MethodCall(_), MethodCall(_))
| (Call(_, _), Call(_, _))
| (ConstBlock(_), ConstBlock(_))
| (Array(_), Array(_))
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
index b57b484bd..6271ea027 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
@@ -60,8 +60,8 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
if_chain! {
if let hir::ExprKind::Binary(binop, _, _) | hir::ExprKind::AssignOp(binop, ..) = expr.kind;
if let Some((binop_trait_lang, op_assign_trait_lang)) = binop_traits(binop.node);
- if let Ok(binop_trait_id) = cx.tcx.lang_items().require(binop_trait_lang);
- if let Ok(op_assign_trait_id) = cx.tcx.lang_items().require(op_assign_trait_lang);
+ if let Some(binop_trait_id) = cx.tcx.lang_items().get(binop_trait_lang);
+ if let Some(op_assign_trait_id) = cx.tcx.lang_items().get(op_assign_trait_lang);
// Check for more than one binary operation in the implemented function
// Linting when multiple operations are involved can result in false positives
@@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
(&OP_ASSIGN_TRAITS, SUSPICIOUS_OP_ASSIGN_IMPL),
]
.iter()
- .find(|&(ts, _)| ts.iter().any(|&t| Ok(trait_id) == cx.tcx.lang_items().require(t)));
+ .find(|&(ts, _)| ts.iter().any(|&t| Some(trait_id) == cx.tcx.lang_items().get(t)));
if count_binops(body.value) == 1;
then {
span_lint(
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs b/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs
new file mode 100644
index 000000000..301aa5798
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs
@@ -0,0 +1,53 @@
+use clippy_utils::{numeric_literal::NumericLiteral, source::snippet_with_context};
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+ /// ### What it does
+ /// Warns for a Bitwise XOR (`^`) operator being probably confused as a powering. It will not trigger if any of the numbers are not in decimal.
+ /// ### Why is this bad?
+ /// It's most probably a typo and may lead to unexpected behaviours.
+ /// ### Example
+ /// ```rust
+ /// let x = 3_i32 ^ 4_i32;
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// let x = 3_i32.pow(4);
+ /// ```
+ #[clippy::version = "1.66.0"]
+ pub SUSPICIOUS_XOR_USED_AS_POW,
+ restriction,
+ "XOR (`^`) operator possibly used as exponentiation operator"
+}
+declare_lint_pass!(ConfusingXorAndPow => [SUSPICIOUS_XOR_USED_AS_POW]);
+
+impl LateLintPass<'_> for ConfusingXorAndPow {
+ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+ if !in_external_macro(cx.sess(), expr.span) &&
+ let ExprKind::Binary(op, left, right) = &expr.kind &&
+ op.node == BinOpKind::BitXor &&
+ left.span.ctxt() == right.span.ctxt() &&
+ let ExprKind::Lit(lit_left) = &left.kind &&
+ let ExprKind::Lit(lit_right) = &right.kind &&
+ let snip_left = snippet_with_context(cx, lit_left.span, lit_left.span.ctxt(), "..", &mut Applicability::MaybeIncorrect) &&
+ let snip_right = snippet_with_context(cx, lit_right.span, lit_right.span.ctxt(), "..", &mut Applicability::MaybeIncorrect) &&
+ let Some(left_val) = NumericLiteral::from_lit_kind(&snip_left.0, &lit_left.node) &&
+ let Some(right_val) = NumericLiteral::from_lit_kind(&snip_right.0, &lit_right.node) &&
+ left_val.is_decimal() &&
+ right_val.is_decimal() {
+ clippy_utils::diagnostics::span_lint_and_sugg(
+ cx,
+ SUSPICIOUS_XOR_USED_AS_POW,
+ expr.span,
+ "`^` is not the exponentiation operator",
+ "did you mean to write",
+ format!("{}.pow({})", left_val.format(), right_val.format()),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs
index f46c21e12..c374529d1 100644
--- a/src/tools/clippy/clippy_lints/src/swap.rs
+++ b/src/tools/clippy/clippy_lints/src/swap.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{can_mut_borrow_both, eq_expr_value, std_or_core};
+use clippy_utils::{can_mut_borrow_both, eq_expr_value, in_constant, std_or_core};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind};
@@ -16,6 +16,8 @@ declare_clippy_lint! {
/// ### What it does
/// Checks for manual swapping.
///
+ /// Note that the lint will not be emitted in const blocks, as the suggestion would not be applicable.
+ ///
/// ### Why is this bad?
/// The `std::mem::swap` function exposes the intent better
/// without deinitializing or copying either variable.
@@ -138,6 +140,10 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa
/// Implementation of the `MANUAL_SWAP` lint.
fn check_manual_swap(cx: &LateContext<'_>, block: &Block<'_>) {
+ if in_constant(cx, block.hir_id) {
+ return;
+ }
+
for w in block.stmts.windows(3) {
if_chain! {
// let t = foo();
diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
index 8cf3efc8d..63b326048 100644
--- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
+++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
@@ -1,9 +1,9 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_hir::{HirId, Item, ItemKind};
+use clippy_utils::has_repr_attr;
+use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Const;
use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
@@ -72,7 +72,3 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'_>, item: &Item<'_
}
}
}
-
-fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {
- cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::repr))
-}
diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
index 424a6e926..83e651aba 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
@@ -16,10 +16,10 @@ mod utils;
mod wrong_transmute;
use clippy_utils::in_constant;
+use clippy_utils::msrvs::Msrv;
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind, QPath};
use rustc_lint::{LateContext, LateLintPass};
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::sym;
@@ -410,7 +410,7 @@ declare_clippy_lint! {
}
pub struct Transmute {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl_lint_pass!(Transmute => [
CROSSPOINTER_TRANSMUTE,
@@ -431,7 +431,7 @@ impl_lint_pass!(Transmute => [
]);
impl Transmute {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -461,7 +461,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
let linted = wrong_transmute::check(cx, e, from_ty, to_ty)
| crosspointer_transmute::check(cx, e, from_ty, to_ty)
| transmuting_null::check(cx, e, arg, to_ty)
- | transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, self.msrv)
+ | transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, &self.msrv)
| transmute_int_to_char::check(cx, e, from_ty, to_ty, arg, const_context)
| transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
| transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg)
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
index 12d0b866e..3dde4eee6 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
@@ -1,12 +1,12 @@
use super::TRANSMUTE_PTR_TO_REF;
use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{meets_msrv, msrvs, sugg};
+use clippy_utils::sugg;
use rustc_errors::Applicability;
use rustc_hir::{self as hir, Expr, GenericArg, Mutability, Path, TyKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, Ty, TypeVisitable};
-use rustc_semver::RustcVersion;
/// Checks for `transmute_ptr_to_ref` lint.
/// Returns `true` if it's triggered, otherwise returns `false`.
@@ -17,7 +17,7 @@ pub(super) fn check<'tcx>(
to_ty: Ty<'tcx>,
arg: &'tcx Expr<'_>,
path: &'tcx Path<'_>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) -> bool {
match (&from_ty.kind(), &to_ty.kind()) {
(ty::RawPtr(from_ptr_ty), ty::Ref(_, to_ref_ty, mutbl)) => {
@@ -37,7 +37,7 @@ pub(super) fn check<'tcx>(
let sugg = if let Some(ty) = get_explicit_type(path) {
let ty_snip = snippet_with_applicability(cx, ty.span, "..", &mut app);
- if meets_msrv(msrv, msrvs::POINTER_CAST) {
+ if msrv.meets(msrvs::POINTER_CAST) {
format!("{deref}{}.cast::<{ty_snip}>()", arg.maybe_par())
} else if from_ptr_ty.has_erased_regions() {
sugg::make_unop(deref, arg.as_ty(format!("{cast} () as {cast} {ty_snip}"))).to_string()
@@ -46,7 +46,7 @@ pub(super) fn check<'tcx>(
}
} else if from_ptr_ty.ty == *to_ref_ty {
if from_ptr_ty.has_erased_regions() {
- if meets_msrv(msrv, msrvs::POINTER_CAST) {
+ if msrv.meets(msrvs::POINTER_CAST) {
format!("{deref}{}.cast::<{to_ref_ty}>()", arg.maybe_par())
} else {
sugg::make_unop(deref, arg.as_ty(format!("{cast} () as {cast} {to_ref_ty}")))
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
index 3d4bbbf64..34642f4b1 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
@@ -27,32 +27,24 @@ pub(super) fn check<'tcx>(
// `Repr(C)` <-> unordered type.
// If the first field of the `Repr(C)` type matches then the transmute is ok
- (
- ReducedTy::OrderedFields(_, Some(from_sub_ty)),
- ReducedTy::UnorderedFields(to_sub_ty),
- )
- | (
- ReducedTy::UnorderedFields(from_sub_ty),
- ReducedTy::OrderedFields(_, Some(to_sub_ty)),
- ) => {
+ (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::UnorderedFields(to_sub_ty))
+ | (ReducedTy::UnorderedFields(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty))) => {
from_ty = from_sub_ty;
to_ty = to_sub_ty;
continue;
- }
- (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::Other(to_sub_ty))
- if reduced_tys.to_fat_ptr =>
- {
+ },
+ (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::Other(to_sub_ty)) if reduced_tys.to_fat_ptr => {
from_ty = from_sub_ty;
to_ty = to_sub_ty;
continue;
- }
+ },
(ReducedTy::Other(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty)))
if reduced_tys.from_fat_ptr =>
{
from_ty = from_sub_ty;
to_ty = to_sub_ty;
continue;
- }
+ },
// ptr <-> ptr
(ReducedTy::Other(from_sub_ty), ReducedTy::Other(to_sub_ty))
@@ -62,19 +54,19 @@ pub(super) fn check<'tcx>(
from_ty = from_sub_ty;
to_ty = to_sub_ty;
continue;
- }
+ },
// fat ptr <-> (*size, *size)
(ReducedTy::Other(_), ReducedTy::UnorderedFields(to_ty))
if reduced_tys.from_fat_ptr && is_size_pair(to_ty) =>
{
return false;
- }
+ },
(ReducedTy::UnorderedFields(from_ty), ReducedTy::Other(_))
if reduced_tys.to_fat_ptr && is_size_pair(from_ty) =>
{
return false;
- }
+ },
// fat ptr -> some struct | some struct -> fat ptr
(ReducedTy::Other(_), _) if reduced_tys.from_fat_ptr => {
@@ -85,14 +77,12 @@ pub(super) fn check<'tcx>(
&format!("transmute from `{from_ty_orig}` which has an undefined layout"),
|diag| {
if from_ty_orig.peel_refs() != from_ty.peel_refs() {
- diag.note(&format!(
- "the contained type `{from_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
}
},
);
return true;
- }
+ },
(_, ReducedTy::Other(_)) if reduced_tys.to_fat_ptr => {
span_lint_and_then(
cx,
@@ -101,18 +91,14 @@ pub(super) fn check<'tcx>(
&format!("transmute to `{to_ty_orig}` which has an undefined layout"),
|diag| {
if to_ty_orig.peel_refs() != to_ty.peel_refs() {
- diag.note(&format!(
- "the contained type `{to_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
}
},
);
return true;
- }
+ },
- (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty))
- if from_ty != to_ty =>
- {
+ (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty)) if from_ty != to_ty => {
let same_adt_did = if let (ty::Adt(from_def, from_subs), ty::Adt(to_def, to_subs))
= (from_ty.kind(), to_ty.kind())
&& from_def == to_def
@@ -139,25 +125,19 @@ pub(super) fn check<'tcx>(
));
} else {
if from_ty_orig.peel_refs() != from_ty {
- diag.note(&format!(
- "the contained type `{from_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
}
if to_ty_orig.peel_refs() != to_ty {
- diag.note(&format!(
- "the contained type `{to_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
}
}
},
);
return true;
- }
+ },
(
ReducedTy::UnorderedFields(from_ty),
- ReducedTy::Other(_)
- | ReducedTy::OrderedFields(..)
- | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },
) => {
span_lint_and_then(
cx,
@@ -166,18 +146,14 @@ pub(super) fn check<'tcx>(
&format!("transmute from `{from_ty_orig}` which has an undefined layout"),
|diag| {
if from_ty_orig.peel_refs() != from_ty {
- diag.note(&format!(
- "the contained type `{from_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
}
},
);
return true;
- }
+ },
(
- ReducedTy::Other(_)
- | ReducedTy::OrderedFields(..)
- | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },
ReducedTy::UnorderedFields(to_ty),
) => {
span_lint_and_then(
@@ -187,25 +163,19 @@ pub(super) fn check<'tcx>(
&format!("transmute into `{to_ty_orig}` which has an undefined layout"),
|diag| {
if to_ty_orig.peel_refs() != to_ty {
- diag.note(&format!(
- "the contained type `{to_ty}` has an undefined layout"
- ));
+ diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
}
},
);
return true;
- }
+ },
(
- ReducedTy::OrderedFields(..)
- | ReducedTy::Other(_)
- | ReducedTy::TypeErasure { raw_ptr_only: true },
- ReducedTy::OrderedFields(..)
- | ReducedTy::Other(_)
- | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },
+ ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },
)
| (ReducedTy::UnorderedFields(_), ReducedTy::UnorderedFields(_)) => {
break;
- }
+ },
}
}
@@ -223,38 +193,42 @@ struct ReducedTys<'tcx> {
}
/// Remove references so long as both types are references.
-fn reduce_refs<'tcx>(
- cx: &LateContext<'tcx>,
- mut from_ty: Ty<'tcx>,
- mut to_ty: Ty<'tcx>,
-) -> ReducedTys<'tcx> {
+fn reduce_refs<'tcx>(cx: &LateContext<'tcx>, mut from_ty: Ty<'tcx>, mut to_ty: Ty<'tcx>) -> ReducedTys<'tcx> {
let mut from_raw_ptr = false;
let mut to_raw_ptr = false;
- let (from_fat_ptr, to_fat_ptr) =
- loop {
- break match (from_ty.kind(), to_ty.kind()) {
- (
- &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
- &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
- ) => {
- from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_));
- from_ty = from_sub_ty;
- to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_));
- to_ty = to_sub_ty;
- continue;
- }
- (
- &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })),
- _,
- ) if !unsized_ty.is_sized(cx.tcx, cx.param_env) => (true, false),
- (
- _,
- &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })),
- ) if !unsized_ty.is_sized(cx.tcx, cx.param_env) => (false, true),
- _ => (false, false),
- };
+ let (from_fat_ptr, to_fat_ptr) = loop {
+ break match (from_ty.kind(), to_ty.kind()) {
+ (
+ &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
+ &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
+ ) => {
+ from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_));
+ from_ty = from_sub_ty;
+ to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_));
+ to_ty = to_sub_ty;
+ continue;
+ },
+ (&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })), _)
+ if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
+ {
+ (true, false)
+ },
+ (_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })))
+ if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
+ {
+ (false, true)
+ },
+ _ => (false, false),
};
- ReducedTys { from_ty, to_ty, from_raw_ptr, to_raw_ptr, from_fat_ptr, to_fat_ptr }
+ };
+ ReducedTys {
+ from_ty,
+ to_ty,
+ from_raw_ptr,
+ to_raw_ptr,
+ from_fat_ptr,
+ to_fat_ptr,
+ }
}
enum ReducedTy<'tcx> {
@@ -277,11 +251,11 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
return match *ty.kind() {
ty::Array(sub_ty, _) if matches!(sub_ty.kind(), ty::Int(_) | ty::Uint(_)) => {
ReducedTy::TypeErasure { raw_ptr_only: false }
- }
+ },
ty::Array(sub_ty, _) | ty::Slice(sub_ty) => {
ty = sub_ty;
continue;
- }
+ },
ty::Tuple(args) if args.is_empty() => ReducedTy::TypeErasure { raw_ptr_only: false },
ty::Tuple(args) => {
let mut iter = args.iter();
@@ -293,7 +267,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
continue;
}
ReducedTy::UnorderedFields(ty)
- }
+ },
ty::Adt(def, substs) if def.is_struct() => {
let mut iter = def
.non_enum_variant()
@@ -312,12 +286,10 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
} else {
ReducedTy::UnorderedFields(ty)
}
- }
- ty::Adt(def, _)
- if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) =>
- {
+ },
+ ty::Adt(def, _) if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) => {
ReducedTy::TypeErasure { raw_ptr_only: false }
- }
+ },
// TODO: Check if the conversion to or from at least one of a union's fields is valid.
ty::Adt(def, _) if def.is_union() => ReducedTy::TypeErasure { raw_ptr_only: false },
ty::Foreign(_) | ty::Param(_) => ReducedTy::TypeErasure { raw_ptr_only: false },
@@ -356,11 +328,7 @@ fn same_except_params<'tcx>(subs1: SubstsRef<'tcx>, subs2: SubstsRef<'tcx>) -> b
for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) {
match (ty1.kind(), ty2.kind()) {
(ty::Param(_), _) | (_, ty::Param(_)) => (),
- (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2))
- if adt1 == adt2 && same_except_params(subs1, subs2) =>
- {
- ()
- }
+ (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2)) if adt1 == adt2 && same_except_params(subs1, subs2) => (),
_ => return false,
}
}
diff --git a/src/tools/clippy/clippy_lints/src/transmute/utils.rs b/src/tools/clippy/clippy_lints/src/transmute/utils.rs
index 641cdf5d3..49d863ec0 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/utils.rs
@@ -1,9 +1,9 @@
+use rustc_hir as hir;
use rustc_hir::Expr;
use rustc_hir_typeck::{cast, FnCtxt, Inherited};
use rustc_lint::LateContext;
use rustc_middle::ty::{cast::CastKind, Ty};
use rustc_span::DUMMY_SP;
-use rustc_hir as hir;
// check if the component types of the transmuted collection and the result have different ABI,
// size or alignment
@@ -55,9 +55,14 @@ fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>
);
if let Ok(check) = cast::CastCheck::new(
- &fn_ctxt, e, from_ty, to_ty,
+ &fn_ctxt,
+ e,
+ from_ty,
+ to_ty,
// We won't show any error to the user, so we don't care what the span is here.
- DUMMY_SP, DUMMY_SP, hir::Constness::NotConst,
+ DUMMY_SP,
+ DUMMY_SP,
+ hir::Constness::NotConst,
) {
let res = check.do_check(&fn_ctxt);
diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
index 9c6629958..65dfe7637 100644
--- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
@@ -31,10 +31,10 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
return false;
}
- let ltopt = if lt.name.is_anonymous() {
+ let ltopt = if lt.is_anonymous() {
String::new()
} else {
- format!("{} ", lt.name.ident().as_str())
+ format!("{} ", lt.ident.as_str())
};
if mut_ty.mutbl == Mutability::Mut {
diff --git a/src/tools/clippy/clippy_lints/src/types/box_collection.rs b/src/tools/clippy/clippy_lints/src/types/box_collection.rs
index 08020ce66..43665a922 100644
--- a/src/tools/clippy/clippy_lints/src/types/box_collection.rs
+++ b/src/tools/clippy/clippy_lints/src/types/box_collection.rs
@@ -37,18 +37,26 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Symbol> {
let param = qpath_generic_tys(qpath).next()?;
let id = path_def_id(cx, param)?;
- cx.tcx.get_diagnostic_name(id).filter(|&name| {
- matches!(
- name,
- sym::HashMap
- | sym::String
- | sym::Vec
- | sym::HashSet
- | sym::VecDeque
- | sym::LinkedList
- | sym::BTreeMap
- | sym::BTreeSet
- | sym::BinaryHeap
- )
- })
+ cx.tcx
+ .get_diagnostic_name(id)
+ .filter(|&name| {
+ matches!(
+ name,
+ sym::HashMap
+ | sym::Vec
+ | sym::HashSet
+ | sym::VecDeque
+ | sym::LinkedList
+ | sym::BTreeMap
+ | sym::BTreeSet
+ | sym::BinaryHeap
+ )
+ })
+ .or_else(|| {
+ cx.tcx
+ .lang_items()
+ .string()
+ .filter(|did| id == *did)
+ .map(|_| sym::String)
+ })
}
diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs
index f6de87b05..20978e81d 100644
--- a/src/tools/clippy/clippy_lints/src/types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/types/mod.rs
@@ -379,7 +379,9 @@ impl<'tcx> LateLintPass<'tcx> for Types {
}
fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
- let is_exported = cx.effective_visibilities.is_exported(cx.tcx.hir().local_def_id(field.hir_id));
+ let is_exported = cx
+ .effective_visibilities
+ .is_exported(cx.tcx.hir().local_def_id(field.hir_id));
self.check_ty(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/types/rc_buffer.rs b/src/tools/clippy/clippy_lints/src/types/rc_buffer.rs
index fa567b9b2..855137b14 100644
--- a/src/tools/clippy/clippy_lints/src/types/rc_buffer.rs
+++ b/src/tools/clippy/clippy_lints/src/types/rc_buffer.rs
@@ -91,10 +91,10 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> {
let ty = qpath_generic_tys(qpath).next()?;
let id = path_def_id(cx, ty)?;
- let path = match cx.tcx.get_diagnostic_name(id)? {
- sym::String => "str",
- sym::OsString => "std::ffi::OsStr",
- sym::PathBuf => "std::path::Path",
+ let path = match cx.tcx.get_diagnostic_name(id) {
+ Some(sym::OsString) => "std::ffi::OsStr",
+ Some(sym::PathBuf) => "std::path::Path",
+ _ if Some(id) == cx.tcx.lang_items().string() => "str",
_ => return None,
};
Some(path)
diff --git a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
index 2b964b64a..fae5385ff 100644
--- a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
+++ b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
@@ -5,16 +5,12 @@ use rustc_errors::Applicability;
use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind};
use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::LateContext;
+use rustc_middle::ty::TypeVisitable;
use rustc_span::symbol::sym;
use super::{utils, REDUNDANT_ALLOCATION};
-pub(super) fn check(
- cx: &LateContext<'_>,
- hir_ty: &hir::Ty<'_>,
- qpath: &QPath<'_>,
- def_id: DefId,
-) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
let mut applicability = Applicability::MaybeIncorrect;
let outer_sym = if Some(def_id) == cx.tcx.lang_items().owned_box() {
"Box"
@@ -34,12 +30,7 @@ pub(super) fn check(
hir_ty.span,
&format!("usage of `{outer_sym}<{generic_snippet}>`"),
|diag| {
- diag.span_suggestion(
- hir_ty.span,
- "try",
- format!("{generic_snippet}"),
- applicability,
- );
+ diag.span_suggestion(hir_ty.span, "try", format!("{generic_snippet}"), applicability);
diag.note(&format!(
"`{generic_snippet}` is already a pointer, `{outer_sym}<{generic_snippet}>` allocates a pointer on the heap"
));
@@ -61,15 +52,16 @@ pub(super) fn check(
return false
};
let inner_span = match qpath_generic_tys(inner_qpath).next() {
- Some(ty) => {
+ Some(hir_ty) => {
// Reallocation of a fat pointer causes it to become thin. `hir_ty_to_ty` is safe to use
// here because `mod.rs` guarantees this lint is only run on types outside of bodies and
// is not run on locals.
- if !hir_ty_to_ty(cx.tcx, ty).is_sized(cx.tcx, cx.param_env) {
+ let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.param_env) {
return false;
}
- ty.span
- }
+ hir_ty.span
+ },
None => return false,
};
if inner_sym == outer_sym {
diff --git a/src/tools/clippy/clippy_lints/src/types/vec_box.rs b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
index 9ad2cb853..7a3c7cd8a 100644
--- a/src/tools/clippy/clippy_lints/src/types/vec_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
@@ -42,7 +42,7 @@ pub(super) fn check(
if !ty_ty.has_escaping_bound_vars();
if ty_ty.is_sized(cx.tcx, cx.param_env);
if let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes());
- if ty_ty_size <= box_size_threshold;
+ if ty_ty_size < box_size_threshold;
then {
span_lint_and_sugg(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
index d2e675a78..2e1b6d8d4 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -1,6 +1,10 @@
+use std::ops::ControlFlow;
+
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::walk_span_to_context;
+use clippy_utils::visitors::{for_each_expr_with_closures, Descend};
use clippy_utils::{get_parent_node, is_lint_allowed};
+use hir::HirId;
use rustc_data_structures::sync::Lrc;
use rustc_hir as hir;
use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource};
@@ -59,16 +63,45 @@ declare_clippy_lint! {
restriction,
"creating an unsafe block without explaining why it is safe"
}
+declare_clippy_lint! {
+ /// ### What it does
+ /// Checks for `// SAFETY: ` comments on safe code.
+ ///
+ /// ### Why is this bad?
+ /// Safe code has no safety requirements, so there is no need to
+ /// describe safety invariants.
+ ///
+ /// ### Example
+ /// ```rust
+ /// use std::ptr::NonNull;
+ /// let a = &mut 42;
+ ///
+ /// // SAFETY: references are guaranteed to be non-null.
+ /// let ptr = NonNull::new(a).unwrap();
+ /// ```
+ /// Use instead:
+ /// ```rust
+ /// use std::ptr::NonNull;
+ /// let a = &mut 42;
+ ///
+ /// let ptr = NonNull::new(a).unwrap();
+ /// ```
+ #[clippy::version = "1.67.0"]
+ pub UNNECESSARY_SAFETY_COMMENT,
+ restriction,
+ "annotating safe code with a safety comment"
+}
-declare_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS]);
+declare_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS, UNNECESSARY_SAFETY_COMMENT]);
-impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
- fn check_block(&mut self, cx: &LateContext<'_>, block: &'_ Block<'_>) {
+impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
+ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
&& !in_external_macro(cx.tcx.sess, block.span)
&& !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id)
&& !is_unsafe_from_proc_macro(cx, block.span)
- && !block_has_safety_comment(cx, block)
+ && !block_has_safety_comment(cx, block.span)
+ && !block_parents_have_safety_comment(cx, block.hir_id)
{
let source_map = cx.tcx.sess.source_map();
let span = if source_map.is_multiline(block.span) {
@@ -86,35 +119,175 @@ impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
"consider adding a safety comment on the preceding line",
);
}
+
+ if let Some(tail) = block.expr
+ && !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, tail.hir_id)
+ && !in_external_macro(cx.tcx.sess, tail.span)
+ && let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, tail.span, tail.hir_id)
+ && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, tail, pos)
+ {
+ span_lint_and_help(
+ cx,
+ UNNECESSARY_SAFETY_COMMENT,
+ tail.span,
+ "expression has unnecessary safety comment",
+ Some(help_span),
+ "consider removing the safety comment",
+ );
+ }
}
- fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
- if let hir::ItemKind::Impl(imple) = item.kind
- && imple.unsafety == hir::Unsafety::Unsafe
- && !in_external_macro(cx.tcx.sess, item.span)
- && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id())
- && !is_unsafe_from_proc_macro(cx, item.span)
- && !item_has_safety_comment(cx, item)
+ fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &hir::Stmt<'tcx>) {
+ let (
+ hir::StmtKind::Local(&hir::Local { init: Some(expr), .. })
+ | hir::StmtKind::Expr(expr)
+ | hir::StmtKind::Semi(expr)
+ ) = stmt.kind else { return };
+ if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, stmt.hir_id)
+ && !in_external_macro(cx.tcx.sess, stmt.span)
+ && let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, stmt.span, stmt.hir_id)
+ && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, expr, pos)
{
+ span_lint_and_help(
+ cx,
+ UNNECESSARY_SAFETY_COMMENT,
+ stmt.span,
+ "statement has unnecessary safety comment",
+ Some(help_span),
+ "consider removing the safety comment",
+ );
+ }
+ }
+
+ fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
+ if in_external_macro(cx.tcx.sess, item.span) {
+ return;
+ }
+
+ let mk_spans = |pos: BytePos| {
let source_map = cx.tcx.sess.source_map();
+ let span = Span::new(pos, pos, SyntaxContext::root(), None);
+ let help_span = source_map.span_extend_to_next_char(span, '\n', true);
let span = if source_map.is_multiline(item.span) {
source_map.span_until_char(item.span, '\n')
} else {
item.span
};
+ (span, help_span)
+ };
- span_lint_and_help(
- cx,
- UNDOCUMENTED_UNSAFE_BLOCKS,
- span,
- "unsafe impl missing a safety comment",
- None,
- "consider adding a safety comment on the preceding line",
- );
+ let item_has_safety_comment = item_has_safety_comment(cx, item);
+ match (&item.kind, item_has_safety_comment) {
+ // lint unsafe impl without safety comment
+ (hir::ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.unsafety == hir::Unsafety::Unsafe => {
+ if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id())
+ && !is_unsafe_from_proc_macro(cx, item.span)
+ {
+ let source_map = cx.tcx.sess.source_map();
+ let span = if source_map.is_multiline(item.span) {
+ source_map.span_until_char(item.span, '\n')
+ } else {
+ item.span
+ };
+
+ span_lint_and_help(
+ cx,
+ UNDOCUMENTED_UNSAFE_BLOCKS,
+ span,
+ "unsafe impl missing a safety comment",
+ None,
+ "consider adding a safety comment on the preceding line",
+ );
+ }
+ },
+ // lint safe impl with unnecessary safety comment
+ (hir::ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.unsafety == hir::Unsafety::Normal => {
+ if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) {
+ let (span, help_span) = mk_spans(pos);
+
+ span_lint_and_help(
+ cx,
+ UNNECESSARY_SAFETY_COMMENT,
+ span,
+ "impl has unnecessary safety comment",
+ Some(help_span),
+ "consider removing the safety comment",
+ );
+ }
+ },
+ (hir::ItemKind::Impl(_), _) => {},
+ // const and static items only need a safety comment if their body is an unsafe block, lint otherwise
+ (&hir::ItemKind::Const(.., body) | &hir::ItemKind::Static(.., body), HasSafetyComment::Yes(pos)) => {
+ if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) {
+ let body = cx.tcx.hir().body(body);
+ if !matches!(
+ body.value.kind, hir::ExprKind::Block(block, _)
+ if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
+ ) {
+ let (span, help_span) = mk_spans(pos);
+
+ span_lint_and_help(
+ cx,
+ UNNECESSARY_SAFETY_COMMENT,
+ span,
+ &format!("{} has unnecessary safety comment", item.kind.descr()),
+ Some(help_span),
+ "consider removing the safety comment",
+ );
+ }
+ }
+ },
+ // Aside from unsafe impls and consts/statics with an unsafe block, items in general
+ // do not have safety invariants that need to be documented, so lint those.
+ (_, HasSafetyComment::Yes(pos)) => {
+ if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) {
+ let (span, help_span) = mk_spans(pos);
+
+ span_lint_and_help(
+ cx,
+ UNNECESSARY_SAFETY_COMMENT,
+ span,
+ &format!("{} has unnecessary safety comment", item.kind.descr()),
+ Some(help_span),
+ "consider removing the safety comment",
+ );
+ }
+ },
+ _ => (),
}
}
}
+fn expr_has_unnecessary_safety_comment<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx hir::Expr<'tcx>,
+ comment_pos: BytePos,
+) -> Option<Span> {
+ // this should roughly be the reverse of `block_parents_have_safety_comment`
+ if for_each_expr_with_closures(cx, expr, |expr| match expr.kind {
+ hir::ExprKind::Block(
+ Block {
+ rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),
+ ..
+ },
+ _,
+ ) => ControlFlow::Break(()),
+ // statements will be handled by check_stmt itself again
+ hir::ExprKind::Block(..) => ControlFlow::Continue(Descend::No),
+ _ => ControlFlow::Continue(Descend::Yes),
+ })
+ .is_some()
+ {
+ return None;
+ }
+
+ let source_map = cx.tcx.sess.source_map();
+ let span = Span::new(comment_pos, comment_pos, SyntaxContext::root(), None);
+ let help_span = source_map.span_extend_to_next_char(span, '\n', true);
+
+ Some(help_span)
+}
+
fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool {
let source_map = cx.sess().source_map();
let file_pos = source_map.lookup_byte_offset(span.lo());
@@ -126,8 +299,41 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool {
.map_or(true, |src| !src.starts_with("unsafe"))
}
+// Checks if any parent {expression, statement, block, local, const, static}
+// has a safety comment
+fn block_parents_have_safety_comment(cx: &LateContext<'_>, id: hir::HirId) -> bool {
+ if let Some(node) = get_parent_node(cx.tcx, id) {
+ return match node {
+ Node::Expr(expr) => !is_branchy(expr) && span_in_body_has_safety_comment(cx, expr.span),
+ Node::Stmt(hir::Stmt {
+ kind:
+ hir::StmtKind::Local(hir::Local { span, .. })
+ | hir::StmtKind::Expr(hir::Expr { span, .. })
+ | hir::StmtKind::Semi(hir::Expr { span, .. }),
+ ..
+ })
+ | Node::Local(hir::Local { span, .. })
+ | Node::Item(hir::Item {
+ kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
+ span,
+ ..
+ }) => span_in_body_has_safety_comment(cx, *span),
+ _ => false,
+ };
+ }
+ false
+}
+
+/// Checks if an expression is "branchy", e.g. loop, match/if/etc.
+fn is_branchy(expr: &hir::Expr<'_>) -> bool {
+ matches!(
+ expr.kind,
+ hir::ExprKind::If(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..)
+ )
+}
+
/// Checks if the lines immediately preceding the block contain a safety comment.
-fn block_has_safety_comment(cx: &LateContext<'_>, block: &hir::Block<'_>) -> bool {
+fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
// This intentionally ignores text before the start of a function so something like:
// ```
// // SAFETY: reason
@@ -136,85 +342,134 @@ fn block_has_safety_comment(cx: &LateContext<'_>, block: &hir::Block<'_>) -> boo
// won't work. This is to avoid dealing with where such a comment should be place relative to
// attributes and doc comments.
- span_from_macro_expansion_has_safety_comment(cx, block.span) || span_in_body_has_safety_comment(cx, block.span)
+ matches!(
+ span_from_macro_expansion_has_safety_comment(cx, span),
+ HasSafetyComment::Yes(_)
+ ) || span_in_body_has_safety_comment(cx, span)
+}
+
+enum HasSafetyComment {
+ Yes(BytePos),
+ No,
+ Maybe,
}
/// Checks if the lines immediately preceding the item contain a safety comment.
#[allow(clippy::collapsible_match)]
-fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> bool {
- if span_from_macro_expansion_has_safety_comment(cx, item.span) {
- return true;
+fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSafetyComment {
+ match span_from_macro_expansion_has_safety_comment(cx, item.span) {
+ HasSafetyComment::Maybe => (),
+ has_safety_comment => return has_safety_comment,
}
- if item.span.ctxt() == SyntaxContext::root() {
- if let Some(parent_node) = get_parent_node(cx.tcx, item.hir_id()) {
- let comment_start = match parent_node {
- Node::Crate(parent_mod) => {
- comment_start_before_impl_in_mod(cx, parent_mod, parent_mod.spans.inner_span, item)
- },
- Node::Item(parent_item) => {
- if let ItemKind::Mod(parent_mod) = &parent_item.kind {
- comment_start_before_impl_in_mod(cx, parent_mod, parent_item.span, item)
- } else {
- // Doesn't support impls in this position. Pretend a comment was found.
- return true;
- }
- },
- Node::Stmt(stmt) => {
- if let Some(stmt_parent) = get_parent_node(cx.tcx, stmt.hir_id) {
- match stmt_parent {
- Node::Block(block) => walk_span_to_context(block.span, SyntaxContext::root()).map(Span::lo),
- _ => {
- // Doesn't support impls in this position. Pretend a comment was found.
- return true;
- },
- }
- } else {
- // Problem getting the parent node. Pretend a comment was found.
- return true;
- }
- },
- _ => {
+ if item.span.ctxt() != SyntaxContext::root() {
+ return HasSafetyComment::No;
+ }
+ if let Some(parent_node) = get_parent_node(cx.tcx, item.hir_id()) {
+ let comment_start = match parent_node {
+ Node::Crate(parent_mod) => {
+ comment_start_before_item_in_mod(cx, parent_mod, parent_mod.spans.inner_span, item)
+ },
+ Node::Item(parent_item) => {
+ if let ItemKind::Mod(parent_mod) = &parent_item.kind {
+ comment_start_before_item_in_mod(cx, parent_mod, parent_item.span, item)
+ } else {
// Doesn't support impls in this position. Pretend a comment was found.
- return true;
- },
- };
+ return HasSafetyComment::Maybe;
+ }
+ },
+ Node::Stmt(stmt) => {
+ if let Some(Node::Block(block)) = get_parent_node(cx.tcx, stmt.hir_id) {
+ walk_span_to_context(block.span, SyntaxContext::root()).map(Span::lo)
+ } else {
+ // Problem getting the parent node. Pretend a comment was found.
+ return HasSafetyComment::Maybe;
+ }
+ },
+ _ => {
+ // Doesn't support impls in this position. Pretend a comment was found.
+ return HasSafetyComment::Maybe;
+ },
+ };
- let source_map = cx.sess().source_map();
- if let Some(comment_start) = comment_start
- && let Ok(unsafe_line) = source_map.lookup_line(item.span.lo())
- && let Ok(comment_start_line) = source_map.lookup_line(comment_start)
- && Lrc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)
- && let Some(src) = unsafe_line.sf.src.as_deref()
- {
- unsafe_line.sf.lines(|lines| {
- comment_start_line.line < unsafe_line.line && text_has_safety_comment(
+ let source_map = cx.sess().source_map();
+ if let Some(comment_start) = comment_start
+ && let Ok(unsafe_line) = source_map.lookup_line(item.span.lo())
+ && let Ok(comment_start_line) = source_map.lookup_line(comment_start)
+ && 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(),
- )
- })
- } else {
- // Problem getting source text. Pretend a comment was found.
- true
- }
- } else {
- // No parent node. Pretend a comment was found.
- true
+ ) {
+ Some(b) => HasSafetyComment::Yes(b),
+ None => HasSafetyComment::No,
+ }
+ }
+ });
+ }
+ }
+ HasSafetyComment::Maybe
+}
+
+/// Checks if the lines immediately preceding the item contain a safety comment.
+#[allow(clippy::collapsible_match)]
+fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> HasSafetyComment {
+ match span_from_macro_expansion_has_safety_comment(cx, span) {
+ HasSafetyComment::Maybe => (),
+ has_safety_comment => return has_safety_comment,
+ }
+
+ if span.ctxt() != SyntaxContext::root() {
+ return HasSafetyComment::No;
+ }
+
+ if let Some(parent_node) = get_parent_node(cx.tcx, hir_id) {
+ let comment_start = match parent_node {
+ Node::Block(block) => walk_span_to_context(block.span, SyntaxContext::root()).map(Span::lo),
+ _ => return HasSafetyComment::Maybe,
+ };
+
+ let source_map = cx.sess().source_map();
+ if let Some(comment_start) = comment_start
+ && let Ok(unsafe_line) = source_map.lookup_line(span.lo())
+ && let Ok(comment_start_line) = source_map.lookup_line(comment_start)
+ && 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,
+ }
+ }
+ });
}
- } else {
- false
}
+ HasSafetyComment::Maybe
}
-fn comment_start_before_impl_in_mod(
+fn comment_start_before_item_in_mod(
cx: &LateContext<'_>,
parent_mod: &hir::Mod<'_>,
parent_mod_span: Span,
- imple: &hir::Item<'_>,
+ item: &hir::Item<'_>,
) -> Option<BytePos> {
parent_mod.item_ids.iter().enumerate().find_map(|(idx, item_id)| {
- if *item_id == imple.item_id() {
+ if *item_id == item.item_id() {
if idx == 0 {
// mod A { /* comment */ unsafe impl T {} ... }
// ^------------------------------------------^ returns the start of this span
@@ -236,11 +491,11 @@ fn comment_start_before_impl_in_mod(
})
}
-fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
+fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span) -> HasSafetyComment {
let source_map = cx.sess().source_map();
let ctxt = span.ctxt();
if ctxt == SyntaxContext::root() {
- false
+ HasSafetyComment::Maybe
} else {
// From a macro expansion. Get the text from the start of the macro declaration to start of the
// unsafe block.
@@ -252,15 +507,22 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span
&& let Some(src) = unsafe_line.sf.src.as_deref()
{
unsafe_line.sf.lines(|lines| {
- macro_line.line < unsafe_line.line && text_has_safety_comment(
- src,
- &lines[macro_line.line + 1..=unsafe_line.line],
- unsafe_line.sf.start_pos.to_usize(),
- )
+ 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
+ }
})
} else {
// Problem getting source text. Pretend a comment was found.
- true
+ HasSafetyComment::Maybe
}
}
}
@@ -299,7 +561,7 @@ fn span_in_body_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
src,
&lines[body_line.line + 1..=unsafe_line.line],
unsafe_line.sf.start_pos.to_usize(),
- )
+ ).is_some()
})
} else {
// Problem getting source text. Pretend a comment was found.
@@ -311,30 +573,34 @@ 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) -> bool {
+fn text_has_safety_comment(src: &str, line_starts: &[BytePos], offset: usize) -> 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;
- src.get(start..end).map(|text| (start, text.trim_start()))
+ let text = src.get(start..end)?;
+ let trimmed = text.trim_start();
+ Some((start + (text.len() - trimmed.len()), trimmed))
})
.filter(|(_, text)| !text.is_empty());
let Some((line_start, line)) = lines.next() else {
- return false;
+ return None;
};
// Check for a sequence of line comments.
if line.starts_with("//") {
- let mut line = line;
+ let (mut line, mut line_start) = (line, line_start);
loop {
if line.to_ascii_uppercase().contains("SAFETY:") {
- return true;
+ return Some(BytePos(
+ u32::try_from(line_start).unwrap() + u32::try_from(offset).unwrap(),
+ ));
}
match lines.next() {
- Some((_, x)) if x.starts_with("//") => line = x,
- _ => return false,
+ Some((s, x)) if x.starts_with("//") => (line, line_start) = (x, s),
+ _ => return None,
}
}
}
@@ -343,16 +609,19 @@ 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].trim_start();
+ let src = &src[line_start..line_starts.last().unwrap().to_usize() - offset];
let mut tokens = tokenize(src);
- return src[..tokens.next().unwrap().len as usize]
+ return (src[..tokens.next().unwrap().len as usize]
.to_ascii_uppercase()
.contains("SAFETY:")
- && tokens.all(|t| t.kind == TokenKind::Whitespace);
+ && tokens.all(|t| t.kind == TokenKind::Whitespace))
+ .then_some(BytePos(
+ u32::try_from(line_start).unwrap() + u32::try_from(offset).unwrap(),
+ ));
}
match lines.next() {
Some(x) => (line_start, line) = x,
- None => return false,
+ None => return None,
}
}
}
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 130728862..a138a4baa 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
@@ -4,7 +4,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::{Closure, Expr, ExprKind, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
-use rustc_middle::ty::{GenericPredicates, PredicateKind, ProjectionPredicate, TraitPredicate};
+use rustc_middle::ty::{Clause, GenericPredicates, PredicateKind, ProjectionPredicate, TraitPredicate};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, BytePos, Span};
@@ -45,7 +45,7 @@ fn get_trait_predicates_for_trait_id<'tcx>(
let mut preds = Vec::new();
for (pred, _) in generics.predicates {
if_chain! {
- if let PredicateKind::Trait(poly_trait_pred) = pred.kind().skip_binder();
+ if let PredicateKind::Clause(Clause::Trait(poly_trait_pred)) = pred.kind().skip_binder();
let trait_pred = cx.tcx.erase_late_bound_regions(pred.kind().rebind(poly_trait_pred));
if let Some(trait_def_id) = trait_id;
if trait_def_id == trait_pred.trait_ref.def_id;
@@ -63,7 +63,7 @@ fn get_projection_pred<'tcx>(
trait_pred: TraitPredicate<'tcx>,
) -> Option<ProjectionPredicate<'tcx>> {
generics.predicates.iter().find_map(|(proj_pred, _)| {
- if let ty::PredicateKind::Projection(pred) = proj_pred.kind().skip_binder() {
+ if let ty::PredicateKind::Clause(Clause::Projection(pred)) = proj_pred.kind().skip_binder() {
let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred.kind().rebind(pred));
if projection_pred.projection_ty.substs == trait_pred.trait_ref.substs {
return Some(projection_pred);
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
index 016aacbf9..9f207d32f 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
@@ -1,4 +1,4 @@
-use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item};
+use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
use clippy_utils::{match_def_path, paths};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
@@ -7,7 +7,6 @@ use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
@@ -55,13 +54,13 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {
);
} else {
if_chain! {
- if cx.tcx.lang_items().require(LangItem::FromFrom).ok() == Some(fun_def_id);
+ if Some(fun_def_id) == cx.tcx.lang_items().from_fn();
if let [.., last_arg] = args;
if let ExprKind::Lit(spanned) = &last_arg.kind;
if let LitKind::Str(symbol, _) = spanned.node;
if symbol.is_empty();
let inner_expr_type = cx.typeck_results().expr_ty(inner_expr);
- if is_type_diagnostic_item(cx, inner_expr_type, sym::String);
+ if is_type_lang_item(cx, inner_expr_type, LangItem::String);
then {
span_lint_and_sugg(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs b/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs
index bc0dd263d..397633f53 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_self_imports.rs
@@ -57,7 +57,7 @@ impl EarlyLintPass for UnnecessarySelfImports {
format!(
"{}{};",
last_segment.ident,
- if let UseTreeKind::Simple(Some(alias), ..) = self_tree.kind { format!(" as {alias}") } else { String::new() },
+ if let UseTreeKind::Simple(Some(alias)) = self_tree.kind { format!(" as {alias}") } else { String::new() },
),
Applicability::MaybeIncorrect,
);
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 b305dae76..7355260ae 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -2,14 +2,14 @@
use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_maybe_qself, eq_pat, eq_path};
use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::{meets_msrv, msrvs, over};
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::over;
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, Mutability, Pat, PatKind, PatKind::*, DUMMY_NODE_ID};
use rustc_ast_pretty::pprust;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::DUMMY_SP;
@@ -45,14 +45,13 @@ declare_clippy_lint! {
"unnested or-patterns, e.g., `Foo(Bar) | Foo(Baz) instead of `Foo(Bar | Baz)`"
}
-#[derive(Clone, Copy)]
pub struct UnnestedOrPatterns {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl UnnestedOrPatterns {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self { msrv }
}
}
@@ -61,13 +60,13 @@ impl_lint_pass!(UnnestedOrPatterns => [UNNESTED_OR_PATTERNS]);
impl EarlyLintPass for UnnestedOrPatterns {
fn check_arm(&mut self, cx: &EarlyContext<'_>, a: &ast::Arm) {
- if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
+ if self.msrv.meets(msrvs::OR_PATTERNS) {
lint_unnested_or_patterns(cx, &a.pat);
}
}
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
- if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
+ if self.msrv.meets(msrvs::OR_PATTERNS) {
if let ast::ExprKind::Let(pat, _, _) = &e.kind {
lint_unnested_or_patterns(cx, pat);
}
@@ -75,13 +74,13 @@ impl EarlyLintPass for UnnestedOrPatterns {
}
fn check_param(&mut self, cx: &EarlyContext<'_>, p: &ast::Param) {
- if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
+ if self.msrv.meets(msrvs::OR_PATTERNS) {
lint_unnested_or_patterns(cx, &p.pat);
}
}
fn check_local(&mut self, cx: &EarlyContext<'_>, l: &ast::Local) {
- if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
+ if self.msrv.meets(msrvs::OR_PATTERNS) {
lint_unnested_or_patterns(cx, &l.pat);
}
}
@@ -292,7 +291,7 @@ fn transform_with_focus_on_idx(alternatives: &mut Vec<P<Pat>>, focus_idx: usize)
/// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern
/// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
fn extend_with_struct_pat(
- qself1: &Option<ast::QSelf>,
+ qself1: &Option<P<ast::QSelf>>,
path1: &ast::Path,
fps1: &mut [ast::PatField],
rest1: bool,
diff --git a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
index 32cd46812..7ee785804 100644
--- a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
+++ b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
@@ -39,7 +39,7 @@ impl EarlyLintPass for UnsafeNameRemoval {
fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) {
match use_tree.kind {
- UseTreeKind::Simple(Some(new_name), ..) => {
+ UseTreeKind::Simple(Some(new_name)) => {
let old_name = use_tree
.prefix
.segments
@@ -48,9 +48,9 @@ fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) {
.ident;
unsafe_to_safe_check(old_name, new_name, cx, span);
},
- UseTreeKind::Simple(None, ..) | UseTreeKind::Glob => {},
+ UseTreeKind::Simple(None) | UseTreeKind::Glob => {},
UseTreeKind::Nested(ref nested_use_tree) => {
- for &(ref use_tree, _) in nested_use_tree {
+ for (use_tree, _) in nested_use_tree {
check_use_tree(use_tree, cx, span);
}
},
diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs
index bf487c7ca..3538bef6e 100644
--- a/src/tools/clippy/clippy_lints/src/unused_async.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_async.rs
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_help;
use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
-use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, IsAsync, YieldSource};
+use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, YieldSource};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
span: Span,
hir_id: HirId,
) {
- if !span.from_expansion() && fn_kind.asyncness() == IsAsync::Async {
+ if !span.from_expansion() && fn_kind.asyncness().is_async() {
let mut visitor = AsyncFnVisitor { cx, found_await: false };
walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), hir_id);
if !visitor.found_await {
diff --git a/src/tools/clippy/clippy_lints/src/unused_peekable.rs b/src/tools/clippy/clippy_lints/src/unused_peekable.rs
index f1cebf0f9..4ee16d9a5 100644
--- a/src/tools/clippy/clippy_lints/src/unused_peekable.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_peekable.rs
@@ -3,7 +3,6 @@ use clippy_utils::ty::{match_type, peel_mid_ty_refs_is_mutable};
use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, paths, peel_ref_operators};
use rustc_ast::Mutability;
use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::lang_items::LangItem;
use rustc_hir::{Block, Expr, ExprKind, HirId, Local, Node, PatKind, PathSegment, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter::OnlyBodies;
@@ -37,7 +36,7 @@ declare_clippy_lint! {
/// // ...
/// }
/// ```
- #[clippy::version = "1.64.0"]
+ #[clippy::version = "1.65.0"]
pub UNUSED_PEEKABLE,
nursery,
"creating a peekable iterator without using any of its methods"
@@ -132,11 +131,11 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> {
// If the Peekable is passed to a function, stop
ExprKind::Call(_, args) => {
if let Some(func_did) = fn_def_id(self.cx, expr)
- && let Ok(into_iter_did) = self
+ && let Some(into_iter_did) = self
.cx
.tcx
.lang_items()
- .require(LangItem::IntoIterIntoIter)
+ .into_iter_fn()
&& func_did == into_iter_did
{
// Probably a for loop desugar, stop searching
diff --git a/src/tools/clippy/clippy_lints/src/unused_rounding.rs b/src/tools/clippy/clippy_lints/src/unused_rounding.rs
index 316493729..097568cd1 100644
--- a/src/tools/clippy/clippy_lints/src/unused_rounding.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_rounding.rs
@@ -1,5 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
-use rustc_ast::ast::{Expr, ExprKind, LitFloatType, LitKind};
+use clippy_utils::source::snippet;
+use rustc_ast::ast::{Expr, ExprKind, MethodCall};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -29,23 +30,16 @@ declare_clippy_lint! {
}
declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]);
-fn is_useless_rounding(expr: &Expr) -> Option<(&str, String)> {
- if let ExprKind::MethodCall(name_ident, receiver, _, _) = &expr.kind
+fn is_useless_rounding<'a>(cx: &EarlyContext<'_>, expr: &'a Expr) -> Option<(&'a str, String)> {
+ if let ExprKind::MethodCall(box MethodCall { seg:name_ident, receiver, .. }) = &expr.kind
&& let method_name = name_ident.ident.name.as_str()
&& (method_name == "ceil" || method_name == "round" || method_name == "floor")
- && let ExprKind::Lit(spanned) = &receiver.kind
- && let LitKind::Float(symbol, ty) = spanned.kind {
- let f = symbol.as_str().parse::<f64>().unwrap();
- let f_str = symbol.to_string() + if let LitFloatType::Suffixed(ty) = ty {
- ty.name_str()
- } else {
- ""
- };
- if f.fract() == 0.0 {
- Some((method_name, f_str))
- } else {
- None
- }
+ && let ExprKind::Lit(token_lit) = &receiver.kind
+ && token_lit.is_semantic_float()
+ && let Ok(f) = token_lit.symbol.as_str().replace('_', "").parse::<f64>() {
+ (f.fract() == 0.0).then(||
+ (method_name, snippet(cx, receiver.span, "..").to_string())
+ )
} else {
None
}
@@ -53,7 +47,7 @@ fn is_useless_rounding(expr: &Expr) -> Option<(&str, String)> {
impl EarlyLintPass for UnusedRounding {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
- if let Some((method_name, float)) = is_useless_rounding(expr) {
+ if let Some((method_name, float)) = is_useless_rounding(cx, expr) {
span_lint_and_sugg(
cx,
UNUSED_ROUNDING,
diff --git a/src/tools/clippy/clippy_lints/src/unused_unit.rs b/src/tools/clippy/clippy_lints/src/unused_unit.rs
index cd1d90e86..cad8da18c 100644
--- a/src/tools/clippy/clippy_lints/src/unused_unit.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_unit.rs
@@ -1,8 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::{position_before_rarrow, snippet_opt};
use if_chain::if_chain;
-use rustc_ast::ast;
-use rustc_ast::visit::FnKind;
+use rustc_ast::{ast, visit::FnKind, ClosureBinder};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -43,6 +42,11 @@ impl EarlyLintPass for UnusedUnit {
if let ast::TyKind::Tup(ref vals) = ty.kind;
if vals.is_empty() && !ty.span.from_expansion() && get_def(span) == get_def(ty.span);
then {
+ // implicit types in closure signatures are forbidden when `for<...>` is present
+ if let FnKind::Closure(&ClosureBinder::For { .. }, ..) = kind {
+ return;
+ }
+
lint_unneeded_unit_return(cx, ty, span);
}
}
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index c6cdf3f85..4c755d812 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_from_proc_macro;
+use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::ty::same_type_and_consts;
-use clippy_utils::{is_from_proc_macro, meets_msrv, msrvs};
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
@@ -14,7 +15,6 @@ use rustc_hir::{
};
use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
-use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span;
@@ -30,7 +30,6 @@ declare_clippy_lint! {
///
/// ### Known problems
/// - Unaddressed false negative in fn bodies of trait implementations
- /// - False positive with associated types in traits (#4140)
///
/// ### Example
/// ```rust
@@ -58,13 +57,13 @@ declare_clippy_lint! {
#[derive(Default)]
pub struct UseSelf {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
stack: Vec<StackItem>,
}
impl UseSelf {
#[must_use]
- pub fn new(msrv: Option<RustcVersion>) -> Self {
+ pub fn new(msrv: Msrv) -> Self {
Self {
msrv,
..Self::default()
@@ -103,6 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
if parameters.as_ref().map_or(true, |params| {
!params.parenthesized && !params.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
});
+ if !item.span.from_expansion();
if !is_from_proc_macro(cx, item); // expensive, should be last check
then {
StackItem::Check {
@@ -199,7 +199,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) {
if_chain! {
if !hir_ty.span.from_expansion();
- if meets_msrv(self.msrv, msrvs::TYPE_ALIAS_ENUM_VARIANTS);
+ if self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS);
if let Some(&StackItem::Check {
impl_id,
in_body,
@@ -228,30 +228,19 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
if_chain! {
if !expr.span.from_expansion();
- if meets_msrv(self.msrv, msrvs::TYPE_ALIAS_ENUM_VARIANTS);
+ if self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS);
if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last();
if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id);
then {} else { return; }
}
match expr.kind {
- ExprKind::Struct(QPath::Resolved(_, path), ..) => match path.res {
- Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => (),
- Res::Def(DefKind::Variant, _) => lint_path_to_variant(cx, path),
- _ => span_lint(cx, path.span),
- },
- // tuple struct instantiation (`Foo(arg)` or `Enum::Foo(arg)`)
+ ExprKind::Struct(QPath::Resolved(_, path), ..) => check_path(cx, path),
ExprKind::Call(fun, _) => {
if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind {
- if let Res::Def(DefKind::Ctor(ctor_of, _), ..) = path.res {
- match ctor_of {
- CtorOf::Variant => lint_path_to_variant(cx, path),
- CtorOf::Struct => span_lint(cx, path.span),
- }
- }
+ check_path(cx, path);
}
},
- // unit enum variants (`Enum::A`)
- ExprKind::Path(QPath::Resolved(_, path)) => lint_path_to_variant(cx, path),
+ ExprKind::Path(QPath::Resolved(_, path)) => check_path(cx, path),
_ => (),
}
}
@@ -259,7 +248,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {
if_chain! {
if !pat.span.from_expansion();
- if meets_msrv(self.msrv, msrvs::TYPE_ALIAS_ENUM_VARIANTS);
+ if self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS);
if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last();
// get the path from the pattern
if let PatKind::Path(QPath::Resolved(_, path))
@@ -267,15 +256,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
| PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind;
if cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id);
then {
- match path.res {
- Res::Def(DefKind::Ctor(ctor_of, _), ..) => match ctor_of {
- CtorOf::Variant => lint_path_to_variant(cx, path),
- CtorOf::Struct => span_lint(cx, path.span),
- },
- Res::Def(DefKind::Variant, ..) => lint_path_to_variant(cx, path),
- Res::Def(DefKind::Struct, ..) => span_lint(cx, path.span),
- _ => ()
- }
+ check_path(cx, path);
}
}
}
@@ -313,6 +294,16 @@ fn span_lint(cx: &LateContext<'_>, span: Span) {
);
}
+fn check_path(cx: &LateContext<'_>, path: &Path<'_>) {
+ match path.res {
+ Res::Def(DefKind::Ctor(CtorOf::Variant, _) | DefKind::Variant, ..) => {
+ lint_path_to_variant(cx, path);
+ },
+ Res::Def(DefKind::Ctor(CtorOf::Struct, _) | DefKind::Struct, ..) => span_lint(cx, path.span),
+ _ => (),
+ }
+}
+
fn lint_path_to_variant(cx: &LateContext<'_>, path: &Path<'_>) {
if let [.., self_seg, _variant] = path.segments {
let span = path
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 1f69db1cb..3743d5d97 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -5,7 +5,7 @@ use clippy_utils::ty::{is_type_diagnostic_item, same_type_and_consts};
use clippy_utils::{get_parent_expr, is_trait_method, match_def_path, paths};
use if_chain::if_chain;
use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, HirId, LangItem, MatchSource};
+use rustc_hir::{Expr, ExprKind, HirId, MatchSource};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -153,7 +153,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
}
if_chain! {
- if cx.tcx.lang_items().require(LangItem::FromFrom).ok() == Some(def_id);
+ if Some(def_id) == cx.tcx.lang_items().from_fn();
if same_type_and_consts(a, b);
then {
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index 668123e4d..b6dc8cd7a 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -53,11 +53,11 @@ impl DisallowedPath {
path
}
- pub fn reason(&self) -> Option<&str> {
+ pub fn reason(&self) -> Option<String> {
match self {
Self::WithReason {
reason: Some(reason), ..
- } => Some(reason),
+ } => Some(format!("{reason} (from clippy.toml)")),
_ => None,
}
}
@@ -213,7 +213,7 @@ define_Conf! {
///
/// Suppress lints whenever the suggested change would cause breakage for other crates.
(avoid_breaking_exported_api: bool = true),
- /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP.
+ /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION.
///
/// The minimum rust version that the project supports
(msrv: Option<String> = None),
@@ -335,6 +335,12 @@ define_Conf! {
///
/// Enables verbose mode. Triggers if there is more than one uppercase char next to each other
(upper_case_acronyms_aggressive: bool = false),
+ /// Lint: MANUAL_LET_ELSE.
+ ///
+ /// Whether the matches should be considered by the lint, and whether there should
+ /// be filtering for common types.
+ (matches_for_let_else: crate::manual_let_else::MatchLintBehaviour =
+ crate::manual_let_else::MatchLintBehaviour::WellKnownTypes),
/// Lint: _CARGO_COMMON_METADATA.
///
/// For internal testing only, ignores the current `publish` settings in the Cargo manifest.
@@ -373,23 +379,40 @@ define_Conf! {
(max_include_file_size: u64 = 1_000_000),
/// Lint: EXPECT_USED.
///
- /// Whether `expect` should be allowed in test functions
+ /// Whether `expect` should be allowed within `#[cfg(test)]`
(allow_expect_in_tests: bool = false),
/// Lint: UNWRAP_USED.
///
- /// Whether `unwrap` should be allowed in test functions
+ /// Whether `unwrap` should be allowed in test cfg
(allow_unwrap_in_tests: bool = false),
/// Lint: DBG_MACRO.
///
/// Whether `dbg!` should be allowed in test functions
(allow_dbg_in_tests: bool = false),
- /// Lint: RESULT_LARGE_ERR
+ /// Lint: PRINT_STDOUT, PRINT_STDERR.
+ ///
+ /// Whether print macros (ex. `println!`) should be allowed in test functions
+ (allow_print_in_tests: bool = false),
+ /// Lint: RESULT_LARGE_ERR.
///
/// The maximum size of the `Err`-variant in a `Result` returned from a function
(large_error_threshold: u64 = 128),
+ /// Lint: MUTABLE_KEY.
+ ///
+ /// A list of paths to types that should be treated like `Arc`, i.e. ignored but
+ /// for the generic parameters for determining interior mutability
+ (ignore_interior_mutability: Vec<String> = Vec::from(["bytes::Bytes".into()])),
+ /// Lint: UNINLINED_FORMAT_ARGS.
+ ///
+ /// Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)`
+ (allow_mixed_uninlined_format_args: bool = true),
}
/// Search for the configuration file.
+///
+/// # Errors
+///
+/// Returns any unexpected filesystem error encountered when searching for the config file
pub fn lookup_conf_file() -> io::Result<Option<PathBuf>> {
/// Possible filename to search for.
const CONFIG_FILE_NAMES: [&str; 2] = [".clippy.toml", "clippy.toml"];
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 096b60157..4b33d492a 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
@@ -2,7 +2,7 @@ use clippy_utils::consts::{constant_simple, Constant};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
use clippy_utils::ty::match_type;
-use clippy_utils::{def_path_res, is_expn_of, match_def_path, paths};
+use clippy_utils::{def_path_def_ids, is_expn_of, match_def_path, paths};
use if_chain::if_chain;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
}
for &module in &[&paths::KW_MODULE, &paths::SYM_MODULE] {
- if let Some(def_id) = def_path_res(cx, module, None).opt_def_id() {
+ for def_id in def_path_def_ids(cx, module) {
for item in cx.tcx.module_children(def_id).iter() {
if_chain! {
if let Res::Def(DefKind::Const, item_def_id) = item.res;
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 25532dd4e..680935f23 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
@@ -3,7 +3,7 @@ use clippy_utils::def_path_res;
use clippy_utils::diagnostics::span_lint;
use if_chain::if_chain;
use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def::DefKind;
use rustc_hir::Item;
use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
@@ -63,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
// This is not a complete resolver for paths. It works on all the paths currently used in the paths
// module. That's all it does and all it needs to do.
pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
- if def_path_res(cx, path, None) != Res::Err {
+ if !def_path_res(cx, path).is_empty() {
return true;
}
@@ -79,22 +79,22 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
SimplifiedTypeGen::StrSimplifiedType,
]
.iter()
- .flat_map(|&ty| cx.tcx.incoherent_impls(ty));
- for item_def_id in lang_items.items().iter().flatten().chain(incoherent_impls) {
- let lang_item_path = cx.get_def_path(*item_def_id);
+ .flat_map(|&ty| cx.tcx.incoherent_impls(ty).iter().copied());
+ for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) {
+ let lang_item_path = cx.get_def_path(item_def_id);
if path_syms.starts_with(&lang_item_path) {
if let [item] = &path_syms[lang_item_path.len()..] {
if matches!(
- cx.tcx.def_kind(*item_def_id),
+ cx.tcx.def_kind(item_def_id),
DefKind::Mod | DefKind::Enum | DefKind::Trait
) {
- for child in cx.tcx.module_children(*item_def_id) {
+ for child in cx.tcx.module_children(item_def_id) {
if child.ident.name == *item {
return true;
}
}
} else {
- for child in cx.tcx.associated_item_def_ids(*item_def_id) {
+ for child in cx.tcx.associated_item_def_ids(item_def_id) {
if cx.tcx.item_name(*child) == *item {
return true;
}
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 0dac64376..786d9608c 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
@@ -256,7 +256,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
}
}
-pub(super) fn is_lint_ref_type<'tcx>(cx: &LateContext<'tcx>, ty: &hir::Ty<'_>) -> bool {
+pub(super) fn is_lint_ref_type(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
if let TyKind::Rptr(
_,
MutTy {
@@ -330,7 +330,7 @@ struct LintCollector<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for LintCollector<'a, 'tcx> {
type NestedFilter = nested_filter::All;
- fn visit_path(&mut self, path: &'tcx Path<'_>, _: HirId) {
+ fn visit_path(&mut self, path: &Path<'_>, _: HirId) {
if path.segments.len() == 1 {
self.output.insert(path.segments[0].ident.name);
}
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 d06a616e4..857abe77e 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
@@ -1019,7 +1019,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for ApplicabilityResolver<'a, 'hir> {
self.cx.tcx.hir()
}
- fn visit_path(&mut self, path: &'hir hir::Path<'hir>, _id: hir::HirId) {
+ fn visit_path(&mut self, path: &hir::Path<'hir>, _id: hir::HirId) {
for (index, enum_value) in paths::APPLICABILITY_VALUES.iter().enumerate() {
if match_path(path, enum_value) {
self.add_new_index(index);
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 1e994e3f2..9876a8a76 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
@@ -41,7 +41,7 @@ impl LateLintPass<'_> for MsrvAttrImpl {
.type_of(f.did)
.walk()
.filter(|t| matches!(t.unpack(), GenericArgKind::Type(_)))
- .any(|t| match_type(cx, t.expect_ty(), &paths::RUSTC_VERSION))
+ .any(|t| match_type(cx, t.expect_ty(), &paths::MSRV))
});
if !items.iter().any(|item| item.ident.name == sym!(enter_lint_attrs));
then {
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 4cf76f536..393988dba 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
@@ -1,19 +1,19 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{def_path_res, is_lint_allowed, match_any_def_paths, peel_hir_expr_refs};
+use clippy_utils::{def_path_def_ids, is_lint_allowed, match_any_def_paths, peel_hir_expr_refs};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Namespace, Res};
+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::ty::{self, AssocKind, DefIdTree, Ty};
+use rustc_middle::ty::{self, DefIdTree, Ty};
use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::symbol::{Ident, Symbol};
+use rustc_span::symbol::Symbol;
use rustc_span::Span;
use std::str;
@@ -91,7 +91,7 @@ impl UnnecessaryDefPath {
#[allow(clippy::too_many_lines)]
fn check_call(&mut self, cx: &LateContext<'_>, func: &Expr<'_>, args: &[Expr<'_>], span: Span) {
enum Item {
- LangItem(Symbol),
+ LangItem(&'static str),
DiagnosticItem(Symbol),
}
static PATHS: &[&[&str]] = &[
@@ -110,7 +110,7 @@ impl UnnecessaryDefPath {
// Extract the path to the matched type
if let Some(segments) = path_to_matched_type(cx, item_arg);
let segments: Vec<&str> = segments.iter().map(|sym| &**sym).collect();
- if let Some(def_id) = inherent_def_path_res(cx, &segments[..]);
+ if let Some(def_id) = def_path_def_ids(cx, &segments[..]).next();
then {
// Check if the target item is a diagnostic item or LangItem.
#[rustfmt::skip]
@@ -133,11 +133,11 @@ impl UnnecessaryDefPath {
let has_ctor = match cx.tcx.def_kind(def_id) {
DefKind::Struct => {
let variant = cx.tcx.adt_def(def_id).non_enum_variant();
- variant.ctor_def_id.is_some() && variant.fields.iter().all(|f| f.vis.is_public())
+ variant.ctor.is_some() && variant.fields.iter().all(|f| f.vis.is_public())
},
DefKind::Variant => {
let variant = cx.tcx.adt_def(cx.tcx.parent(def_id)).variant_with_id(def_id);
- variant.ctor_def_id.is_some() && variant.fields.iter().all(|f| f.vis.is_public())
+ variant.ctor.is_some() && variant.fields.iter().all(|f| f.vis.is_public())
},
_ => false,
};
@@ -152,7 +152,7 @@ impl UnnecessaryDefPath {
has_ctor,
),
(0, Item::LangItem(item)) => (
- format!("{cx_snip}.tcx.lang_items().require(LangItem::{item}).ok() == Some({def_snip})"),
+ format!("{cx_snip}.tcx.lang_items().get(LangItem::{item}) == Some({def_snip})"),
has_ctor,
),
// match_trait_method
@@ -184,7 +184,7 @@ impl UnnecessaryDefPath {
(3, Item::LangItem(item)) => (
format!(
"path_res({cx_snip}, {def_snip}).opt_def_id()\
- .map_or(false, |id| {cx_snip}.tcx.lang_items().require(LangItem::{item}).ok() == Some(id))",
+ .map_or(false, |id| {cx_snip}.tcx.lang_items().get(LangItem::{item}) == Some(id))",
),
false,
),
@@ -209,7 +209,7 @@ impl UnnecessaryDefPath {
fn check_array(&mut self, cx: &LateContext<'_>, elements: &[Expr<'_>], span: Span) {
let Some(path) = path_from_array(elements) else { return };
- if let Some(def_id) = inherent_def_path_res(cx, &path.iter().map(AsRef::as_ref).collect::<Vec<_>>()) {
+ for def_id in def_path_def_ids(cx, &path.iter().map(AsRef::as_ref).collect::<Vec<_>>()) {
self.array_def_ids.insert((def_id, span));
}
}
@@ -246,7 +246,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
fn read_mir_alloc_def_path<'tcx>(cx: &LateContext<'tcx>, alloc: &'tcx Allocation, ty: Ty<'_>) -> Option<Vec<String>> {
let (alloc, ty) = if let ty::Ref(_, ty, Mutability::Not) = *ty.kind() {
- let &alloc = alloc.provenance().values().next()?;
+ let &alloc = alloc.provenance().ptrs().values().next()?;
if let GlobalAlloc::Memory(alloc) = cx.tcx.global_alloc(alloc) {
(alloc.inner(), ty)
} else {
@@ -262,6 +262,7 @@ fn read_mir_alloc_def_path<'tcx>(cx: &LateContext<'tcx>, alloc: &'tcx Allocation
{
alloc
.provenance()
+ .ptrs()
.values()
.map(|&alloc| {
if let GlobalAlloc::Memory(alloc) = cx.tcx.global_alloc(alloc) {
@@ -293,50 +294,9 @@ fn path_from_array(exprs: &[Expr<'_>]) -> Option<Vec<String>> {
.collect()
}
-// def_path_res will match field names before anything else, but for this we want to match
-// inherent functions first.
-fn inherent_def_path_res(cx: &LateContext<'_>, segments: &[&str]) -> Option<DefId> {
- def_path_res(cx, segments, None).opt_def_id().map(|def_id| {
- if cx.tcx.def_kind(def_id) == DefKind::Field {
- let method_name = *segments.last().unwrap();
- cx.tcx
- .def_key(def_id)
- .parent
- .and_then(|parent_idx| {
- cx.tcx
- .inherent_impls(DefId {
- index: parent_idx,
- krate: def_id.krate,
- })
- .iter()
- .find_map(|impl_id| {
- cx.tcx.associated_items(*impl_id).find_by_name_and_kind(
- cx.tcx,
- Ident::from_str(method_name),
- AssocKind::Fn,
- *impl_id,
- )
- })
- })
- .map_or(def_id, |item| item.def_id)
- } else {
- def_id
- }
- })
-}
-
-fn get_lang_item_name(cx: &LateContext<'_>, def_id: DefId) -> Option<Symbol> {
- if let Some(lang_item) = cx.tcx.lang_items().items().iter().position(|id| *id == Some(def_id)) {
- let lang_items = def_path_res(cx, &["rustc_hir", "lang_items", "LangItem"], Some(Namespace::TypeNS)).def_id();
- let item_name = cx
- .tcx
- .adt_def(lang_items)
- .variants()
- .iter()
- .nth(lang_item)
- .unwrap()
- .name;
- Some(item_name)
+fn get_lang_item_name(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static str> {
+ if let Some((lang_item, _)) = cx.tcx.lang_items().iter().find(|(_, id)| *id == def_id) {
+ Some(lang_item.variant_name())
} else {
None
}
diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
index be9834447..e4d1ee195 100644
--- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
@@ -176,7 +176,8 @@ impl LateLintPass<'_> for WildcardImports {
format!("{import_source_snippet}::{imports_string}")
};
- let (lint, message) = if let Res::Def(DefKind::Enum, _) = use_path.res {
+ // Glob imports always have a single resolution.
+ let (lint, message) = if let Res::Def(DefKind::Enum, _) = use_path.res[0] {
(ENUM_GLOB_USE, "usage of wildcard import for enum variants")
} else {
(WILDCARD_IMPORTS, "usage of wildcard import")
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index 36574198f..6b321765b 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -1,6 +1,7 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn, MacroCall};
use clippy_utils::source::{expand_past_previous_comma, snippet_opt};
+use clippy_utils::{is_in_cfg_test, is_in_test_function};
use rustc_ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, HirIdMap, Impl, Item, ItemKind};
@@ -232,6 +233,16 @@ declare_clippy_lint! {
#[derive(Default)]
pub struct Write {
in_debug_impl: bool,
+ allow_print_in_tests: bool,
+}
+
+impl Write {
+ pub fn new(allow_print_in_tests: bool) -> Self {
+ Self {
+ allow_print_in_tests,
+ ..Default::default()
+ }
+ }
}
impl_lint_pass!(Write => [
@@ -271,13 +282,15 @@ impl<'tcx> LateLintPass<'tcx> for Write {
.as_ref()
.map_or(false, |crate_name| crate_name == "build_script_build");
+ let allowed_in_tests = self.allow_print_in_tests
+ && (is_in_test_function(cx.tcx, expr.hir_id) || is_in_cfg_test(cx.tcx, expr.hir_id));
match diag_name {
- sym::print_macro | sym::println_macro => {
+ sym::print_macro | sym::println_macro if !allowed_in_tests => {
if !is_build_script {
span_lint(cx, PRINT_STDOUT, macro_call.span, &format!("use of `{name}!`"));
}
},
- sym::eprint_macro | sym::eprintln_macro => {
+ sym::eprint_macro | sym::eprintln_macro if !allowed_in_tests => {
span_lint(cx, PRINT_STDERR, macro_call.span, &format!("use of `{name}!`"));
},
sym::write_macro | sym::writeln_macro => {},
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index 83fee7bb3..fb9f4740e 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.66"
+version = "0.1.67"
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 013399756..49e5f283d 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -75,11 +75,11 @@ pub fn eq_field_pat(l: &PatField, r: &PatField) -> bool {
&& over(&l.attrs, &r.attrs, eq_attr)
}
-pub fn eq_qself(l: &QSelf, r: &QSelf) -> bool {
+pub fn eq_qself(l: &P<QSelf>, r: &P<QSelf>) -> bool {
l.position == r.position && eq_ty(&l.ty, &r.ty)
}
-pub fn eq_maybe_qself(l: &Option<QSelf>, r: &Option<QSelf>) -> bool {
+pub fn eq_maybe_qself(l: &Option<P<QSelf>>, r: &Option<P<QSelf>>) -> bool {
match (l, r) {
(Some(l), Some(r)) => eq_qself(l, r),
(None, None) => true,
@@ -147,12 +147,23 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(Array(l), Array(r)) | (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)),
(Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value),
(Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)),
- (MethodCall(lc, ls, la, _), MethodCall(rc, rs, ra, _)) => {
- eq_path_seg(lc, rc) && eq_expr(ls, rs) && over(la, ra, |l, r| eq_expr(l, r))
- },
+ (
+ MethodCall(box ast::MethodCall {
+ seg: ls,
+ receiver: lr,
+ args: la,
+ ..
+ }),
+ MethodCall(box ast::MethodCall {
+ seg: rs,
+ receiver: rr,
+ args: ra,
+ ..
+ }),
+ ) => eq_path_seg(ls, rs) && eq_expr(lr, rr) && over(la, ra, |l, r| eq_expr(l, r)),
(Binary(lo, ll, lr), Binary(ro, rl, rr)) => lo.node == ro.node && eq_expr(ll, rl) && eq_expr(lr, rr),
(Unary(lo, l), Unary(ro, r)) => mem::discriminant(lo) == mem::discriminant(ro) && eq_expr(l, r),
- (Lit(l), Lit(r)) => l.kind == r.kind,
+ (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),
(If(lc, lt, le), If(rc, rt, re)) => eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le, re),
@@ -160,7 +171,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(ForLoop(lp, li, lt, ll), ForLoop(rp, ri, rt, rl)) => {
eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt)
},
- (Loop(lt, ll), Loop(rt, rl)) => eq_label(ll, rl) && eq_block(lt, rt),
+ (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll, rl) && eq_block(lt, rt),
(Block(lb, ll), Block(rb, rl)) => eq_label(ll, rl) && eq_block(lb, rb),
(TryBlock(l), TryBlock(r)) => eq_block(l, r),
(Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l, r),
@@ -170,7 +181,26 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
(Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
(Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm),
- (Closure(lb, lc, la, lm, lf, le, _), Closure(rb, rc, ra, rm, rf, re, _)) => {
+ (
+ Closure(box ast::Closure {
+ binder: lb,
+ capture_clause: lc,
+ asyncness: la,
+ movability: lm,
+ fn_decl: lf,
+ body: le,
+ ..
+ }),
+ Closure(box ast::Closure {
+ binder: rb,
+ capture_clause: rc,
+ asyncness: ra,
+ movability: rm,
+ fn_decl: rf,
+ body: re,
+ ..
+ }),
+ ) => {
eq_closure_binder(lb, rb)
&& lc == rc
&& la.is_async() == ra.is_async()
@@ -366,7 +396,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
&& over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
},
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
- (MacroDef(l), MacroDef(r)) => l.macro_rules == r.macro_rules && eq_mac_args(&l.body, &r.body),
+ (MacroDef(l), MacroDef(r)) => l.macro_rules == r.macro_rules && eq_delim_args(&l.body, &r.body),
_ => false,
}
}
@@ -536,7 +566,7 @@ pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool {
use UseTreeKind::*;
match (l, r) {
(Glob, Glob) => true,
- (Simple(l, _, _), Simple(r, _, _)) => both(l, r, |l, r| eq_id(*l, *r)),
+ (Simple(l), Simple(r)) => both(l, r, |l, r| eq_id(*l, *r)),
(Nested(l), Nested(r)) => over(l, r, |(l, _), (r, _)| eq_use_tree(l, r)),
_ => false,
}
@@ -687,7 +717,7 @@ pub fn eq_assoc_constraint(l: &AssocConstraint, r: &AssocConstraint) -> bool {
}
pub fn eq_mac_call(l: &MacCall, r: &MacCall) -> bool {
- eq_path(&l.path, &r.path) && eq_mac_args(&l.args, &r.args)
+ eq_path(&l.path, &r.path) && eq_delim_args(&l.args, &r.args)
}
pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool {
@@ -695,18 +725,22 @@ pub fn eq_attr(l: &Attribute, r: &Attribute) -> bool {
l.style == r.style
&& match (&l.kind, &r.kind) {
(DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2,
- (Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_mac_args(&l.item.args, &r.item.args),
+ (Normal(l), Normal(r)) => eq_path(&l.item.path, &r.item.path) && eq_attr_args(&l.item.args, &r.item.args),
_ => false,
}
}
-pub fn eq_mac_args(l: &MacArgs, r: &MacArgs) -> bool {
- use MacArgs::*;
+pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool {
+ use AttrArgs::*;
match (l, r) {
(Empty, Empty) => true,
- (Delimited(_, ld, lts), Delimited(_, rd, rts)) => ld == rd && lts.eq_unspanned(rts),
- (Eq(_, MacArgsEq::Ast(le)), Eq(_, MacArgsEq::Ast(re))) => eq_expr(le, re),
- (Eq(_, MacArgsEq::Hir(ll)), Eq(_, MacArgsEq::Hir(rl))) => ll.kind == rl.kind,
+ (Delimited(la), Delimited(ra)) => eq_delim_args(la, ra),
+ (Eq(_, AttrArgsEq::Ast(le)), Eq(_, AttrArgsEq::Ast(re))) => eq_expr(le, re),
+ (Eq(_, AttrArgsEq::Hir(ll)), Eq(_, AttrArgsEq::Hir(rl))) => ll.kind == rl.kind,
_ => false,
}
}
+
+pub fn eq_delim_args(l: &DelimArgs, r: &DelimArgs) -> bool {
+ l.delim == r.delim && l.tokens.eq_unspanned(&r.tokens)
+}
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index cd8575c90..7987a233b 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -125,19 +125,19 @@ fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'
}
}
-pub fn get_unique_inner_attr(sess: &Session, attrs: &[ast::Attribute], name: &'static str) -> Option<ast::Attribute> {
- let mut unique_attr = None;
+pub fn get_unique_attr<'a>(
+ sess: &'a Session,
+ attrs: &'a [ast::Attribute],
+ name: &'static str,
+) -> Option<&'a ast::Attribute> {
+ let mut unique_attr: Option<&ast::Attribute> = None;
for attr in get_attr(sess, attrs, name) {
- match attr.style {
- ast::AttrStyle::Inner if unique_attr.is_none() => unique_attr = Some(attr.clone()),
- ast::AttrStyle::Inner => {
- sess.struct_span_err(attr.span, &format!("`{name}` is defined multiple times"))
- .span_note(unique_attr.as_ref().unwrap().span, "first definition found here")
- .emit();
- },
- ast::AttrStyle::Outer => {
- sess.span_err(attr.span, format!("`{name}` cannot be an outer attribute"));
- },
+ if let Some(duplicate) = unique_attr {
+ sess.struct_span_err(attr.span, &format!("`{name}` is defined multiple times"))
+ .span_note(duplicate.span, "first definition found here")
+ .emit();
+ } else {
+ unique_attr = Some(attr);
}
}
unique_attr
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 07e4ef6a2..315aea9aa 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -51,8 +51,8 @@ pub enum Constant {
impl PartialEq for Constant {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
- (&Self::Str(ref ls), &Self::Str(ref rs)) => ls == rs,
- (&Self::Binary(ref l), &Self::Binary(ref r)) => l == r,
+ (Self::Str(ls), Self::Str(rs)) => ls == rs,
+ (Self::Binary(l), Self::Binary(r)) => l == r,
(&Self::Char(l), &Self::Char(r)) => l == r,
(&Self::Int(l), &Self::Int(r)) => l == r,
(&Self::F64(l), &Self::F64(r)) => {
@@ -69,8 +69,8 @@ impl PartialEq for Constant {
},
(&Self::Bool(l), &Self::Bool(r)) => l == r,
(&Self::Vec(ref l), &Self::Vec(ref r)) | (&Self::Tuple(ref l), &Self::Tuple(ref r)) => l == r,
- (&Self::Repeat(ref lv, ref ls), &Self::Repeat(ref rv, ref rs)) => ls == rs && lv == rv,
- (&Self::Ref(ref lb), &Self::Ref(ref rb)) => *lb == *rb,
+ (Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => ls == rs && lv == rv,
+ (Self::Ref(lb), Self::Ref(rb)) => *lb == *rb,
// TODO: are there inter-type equalities?
_ => false,
}
@@ -126,8 +126,8 @@ impl Hash for Constant {
impl Constant {
pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self) -> Option<Ordering> {
match (left, right) {
- (&Self::Str(ref ls), &Self::Str(ref rs)) => Some(ls.cmp(rs)),
- (&Self::Char(ref l), &Self::Char(ref r)) => Some(l.cmp(r)),
+ (Self::Str(ls), Self::Str(rs)) => Some(ls.cmp(rs)),
+ (Self::Char(l), Self::Char(r)) => Some(l.cmp(r)),
(&Self::Int(l), &Self::Int(r)) => match *cmp_type.kind() {
ty::Int(int_ty) => Some(sext(tcx, l, int_ty).cmp(&sext(tcx, r, int_ty))),
ty::Uint(_) => Some(l.cmp(&r)),
@@ -135,8 +135,8 @@ impl Constant {
},
(&Self::F64(l), &Self::F64(r)) => l.partial_cmp(&r),
(&Self::F32(l), &Self::F32(r)) => l.partial_cmp(&r),
- (&Self::Bool(ref l), &Self::Bool(ref r)) => Some(l.cmp(r)),
- (&Self::Tuple(ref l), &Self::Tuple(ref r)) if l.len() == r.len() => match *cmp_type.kind() {
+ (Self::Bool(l), Self::Bool(r)) => Some(l.cmp(r)),
+ (Self::Tuple(l), Self::Tuple(r)) if l.len() == r.len() => match *cmp_type.kind() {
ty::Tuple(tys) if tys.len() == l.len() => l
.iter()
.zip(r)
@@ -146,17 +146,16 @@ impl Constant {
.unwrap_or_else(|| Some(l.len().cmp(&r.len()))),
_ => None,
},
- (&Self::Vec(ref l), &Self::Vec(ref r)) => {
- let cmp_type = match *cmp_type.kind() {
- ty::Array(ty, _) | ty::Slice(ty) => ty,
- _ => return None,
+ (Self::Vec(l), Self::Vec(r)) => {
+ let (ty::Array(cmp_type, _) | ty::Slice(cmp_type)) = *cmp_type.kind() else {
+ return None
};
iter::zip(l, r)
.map(|(li, ri)| Self::partial_cmp(tcx, cmp_type, li, ri))
.find(|r| r.map_or(true, |o| o != Ordering::Equal))
.unwrap_or_else(|| Some(l.len().cmp(&r.len())))
},
- (&Self::Repeat(ref lv, ref ls), &Self::Repeat(ref rv, ref rs)) => {
+ (Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => {
match Self::partial_cmp(
tcx,
match *cmp_type.kind() {
@@ -170,7 +169,7 @@ impl Constant {
x => x,
}
},
- (&Self::Ref(ref lb), &Self::Ref(ref rb)) => Self::partial_cmp(
+ (Self::Ref(lb), Self::Ref(rb)) => Self::partial_cmp(
tcx,
match *cmp_type.kind() {
ty::Ref(_, ty, _) => ty,
@@ -401,10 +400,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
use self::Constant::{Int, F32, F64};
match *o {
Int(value) => {
- let ity = match *ty.kind() {
- ty::Int(ity) => ity,
- _ => return None,
- };
+ let ty::Int(ity) = *ty.kind() else { return None };
// sign extend
let value = sext(self.lcx.tcx, value, ity);
let value = value.checked_neg()?;
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index 78f93755b..16b160b6f 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -72,8 +72,8 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult
/// |
/// = help: consider using `f64::NAN` if you would like a constant representing NaN
/// ```
-pub fn span_lint_and_help<'a, T: LintContext>(
- cx: &'a T,
+pub fn span_lint_and_help<T: LintContext>(
+ cx: &T,
lint: &'static Lint,
span: impl Into<MultiSpan>,
msg: &str,
@@ -114,8 +114,8 @@ pub fn span_lint_and_help<'a, T: LintContext>(
/// 10 | forget(&SomeStruct);
/// | ^^^^^^^^^^^
/// ```
-pub fn span_lint_and_note<'a, T: LintContext>(
- cx: &'a T,
+pub fn span_lint_and_note<T: LintContext>(
+ cx: &T,
lint: &'static Lint,
span: impl Into<MultiSpan>,
msg: &str,
@@ -192,8 +192,8 @@ pub fn span_lint_hir_and_then(
/// = note: `-D fold-any` implied by `-D warnings`
/// ```
#[cfg_attr(feature = "internal", allow(clippy::collapsible_span_lint_calls))]
-pub fn span_lint_and_sugg<'a, T: LintContext>(
- cx: &'a T,
+pub fn span_lint_and_sugg<T: LintContext>(
+ cx: &T,
lint: &'static Lint,
sp: Span,
msg: &str,
diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
index 95b3e651e..967119369 100644
--- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
+++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
@@ -73,7 +73,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg:
.flat_map(|v| v.fields.iter())
.any(|x| matches!(cx.tcx.type_of(x.did).peel_refs().kind(), ty::Param(_)))
&& all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() {
- PredicateKind::Trait(pred) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker,
+ PredicateKind::Clause(ty::Clause::Trait(pred)) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker,
_ => true,
})
&& subs.types().all(|x| matches!(x.peel_refs().kind(), ty::Param(_)))
@@ -91,6 +91,16 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg:
}
}
+fn res_has_significant_drop(res: Res, cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
+ if let Res::Def(DefKind::Ctor(..) | DefKind::Variant, _) | Res::SelfCtor(_) = res {
+ cx.typeck_results()
+ .expr_ty(e)
+ .has_significant_drop(cx.tcx, cx.param_env)
+ } else {
+ false
+ }
+}
+
#[expect(clippy::too_many_lines)]
fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessSuggestion {
struct V<'cx, 'tcx> {
@@ -113,13 +123,8 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
},
args,
) => match self.cx.qpath_res(path, hir_id) {
- Res::Def(DefKind::Ctor(..) | DefKind::Variant, _) | Res::SelfCtor(_) => {
- if self
- .cx
- .typeck_results()
- .expr_ty(e)
- .has_significant_drop(self.cx.tcx, self.cx.param_env)
- {
+ res @ (Res::Def(DefKind::Ctor(..) | DefKind::Variant, _) | Res::SelfCtor(_)) => {
+ if res_has_significant_drop(res, self.cx, e) {
self.eagerness = ForceNoChange;
return;
}
@@ -147,6 +152,12 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
self.eagerness |= NoChange;
return;
},
+ ExprKind::Path(ref path) => {
+ if res_has_significant_drop(self.cx.qpath_res(path, e.hir_id), self.cx, e) {
+ self.eagerness = ForceNoChange;
+ return;
+ }
+ },
ExprKind::MethodCall(name, ..) => {
self.eagerness |= self
.cx
@@ -206,7 +217,6 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
| ExprKind::Match(..)
| ExprKind::Closure { .. }
| ExprKind::Field(..)
- | ExprKind::Path(_)
| ExprKind::AddrOf(..)
| ExprKind::Struct(..)
| ExprKind::Repeat(..)
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index cf24ec8b6..07fb6af91 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -7,8 +7,8 @@ use rustc_hir::def::Res;
use rustc_hir::HirIdMap;
use rustc_hir::{
ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
- GenericArgs, Guard, HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path,
- PathSegment, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
+ GenericArgs, Guard, HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
+ PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
};
use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::LateContext;
@@ -113,7 +113,7 @@ impl HirEqInterExpr<'_, '_, '_> {
}
}
- // eq_pat adds the HirIds to the locals map. We therefor call it last to make sure that
+ // eq_pat adds the HirIds to the locals map. We therefore call it last to make sure that
// these only get added if the init and type is equal.
both(&l.init, &r.init, |l, r| self.eq_expr(l, r))
&& both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r))
@@ -131,13 +131,10 @@ impl HirEqInterExpr<'_, '_, '_> {
([], None, [], None) => {
// For empty blocks, check to see if the tokens are equal. This will catch the case where a macro
// expanded to nothing, or the cfg attribute was used.
- let (left, right) = match (
+ let (Some(left), Some(right)) = (
snippet_opt(self.inner.cx, left.span),
snippet_opt(self.inner.cx, right.span),
- ) {
- (Some(left), Some(right)) => (left, right),
- _ => return true,
- };
+ ) else { return true };
let mut left_pos = 0;
let left = tokenize(&left)
.map(|t| {
@@ -269,7 +266,7 @@ impl HirEqInterExpr<'_, '_, '_> {
(&ExprKind::Let(l), &ExprKind::Let(r)) => {
self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init)
},
- (&ExprKind::Lit(ref l), &ExprKind::Lit(ref r)) => l.node == r.node,
+ (ExprKind::Lit(l), ExprKind::Lit(r)) => l.node == r.node,
(&ExprKind::Loop(lb, ref ll, ref lls, _), &ExprKind::Loop(rb, ref rl, ref rls, _)) => {
lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
},
@@ -294,8 +291,8 @@ impl HirEqInterExpr<'_, '_, '_> {
(&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
self.eq_expr(le, re) && self.eq_array_length(ll, rl)
},
- (&ExprKind::Ret(ref l), &ExprKind::Ret(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
- (&ExprKind::Path(ref l), &ExprKind::Path(ref r)) => self.eq_qpath(l, r),
+ (ExprKind::Ret(l), ExprKind::Ret(r)) => both(l, r, |l, r| self.eq_expr(l, r)),
+ (ExprKind::Path(l), ExprKind::Path(r)) => self.eq_qpath(l, r),
(&ExprKind::Struct(l_path, lf, ref lo), &ExprKind::Struct(r_path, rf, ref ro)) => {
self.eq_qpath(l_path, r_path)
&& both(lo, ro, |l, r| self.eq_expr(l, r))
@@ -340,7 +337,7 @@ impl HirEqInterExpr<'_, '_, '_> {
}
fn eq_lifetime(left: &Lifetime, right: &Lifetime) -> bool {
- left.name == right.name
+ left.res == right.res
}
fn eq_pat_field(&mut self, left: &PatField<'_>, right: &PatField<'_>) -> bool {
@@ -365,7 +362,7 @@ impl HirEqInterExpr<'_, '_, '_> {
}
eq
},
- (&PatKind::Path(ref l), &PatKind::Path(ref r)) => self.eq_qpath(l, r),
+ (PatKind::Path(l), PatKind::Path(r)) => self.eq_qpath(l, r),
(&PatKind::Lit(l), &PatKind::Lit(r)) => self.eq_expr(l, r),
(&PatKind::Tuple(l, ls), &PatKind::Tuple(r, rs)) => ls == rs && over(l, r, |l, r| self.eq_pat(l, r)),
(&PatKind::Range(ref ls, ref le, li), &PatKind::Range(ref rs, ref re, ri)) => {
@@ -432,13 +429,11 @@ impl HirEqInterExpr<'_, '_, '_> {
match (&left.kind, &right.kind) {
(&TyKind::Slice(l_vec), &TyKind::Slice(r_vec)) => self.eq_ty(l_vec, r_vec),
(&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_array_length(ll, rl),
- (&TyKind::Ptr(ref l_mut), &TyKind::Ptr(ref r_mut)) => {
- l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty)
- },
- (&TyKind::Rptr(_, ref l_rmut), &TyKind::Rptr(_, ref r_rmut)) => {
+ (TyKind::Ptr(l_mut), TyKind::Ptr(r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty),
+ (TyKind::Rptr(_, l_rmut), TyKind::Rptr(_, r_rmut)) => {
l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(l_rmut.ty, r_rmut.ty)
},
- (&TyKind::Path(ref l), &TyKind::Path(ref r)) => self.eq_qpath(l, r),
+ (TyKind::Path(l), TyKind::Path(r)) => self.eq_qpath(l, r),
(&TyKind::Tup(l), &TyKind::Tup(r)) => over(l, r, |l, r| self.eq_ty(l, r)),
(&TyKind::Infer, &TyKind::Infer) => true,
_ => false,
@@ -930,16 +925,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
}
pub fn hash_lifetime(&mut self, lifetime: &Lifetime) {
- std::mem::discriminant(&lifetime.name).hash(&mut self.s);
- if let LifetimeName::Param(param_id, ref name) = lifetime.name {
- std::mem::discriminant(name).hash(&mut self.s);
+ lifetime.ident.name.hash(&mut self.s);
+ std::mem::discriminant(&lifetime.res).hash(&mut self.s);
+ if let LifetimeName::Param(param_id) = lifetime.res {
param_id.hash(&mut self.s);
- match name {
- ParamName::Plain(ref ident) => {
- ident.name.hash(&mut self.s);
- },
- ParamName::Fresh | ParamName::Error => {},
- }
}
}
@@ -1033,6 +1022,14 @@ pub fn hash_stmt(cx: &LateContext<'_>, s: &Stmt<'_>) -> u64 {
h.finish()
}
+pub fn is_bool(ty: &Ty<'_>) -> bool {
+ if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind {
+ matches!(path.res, Res::PrimTy(PrimTy::Bool))
+ } else {
+ false
+ }
+}
+
pub fn hash_expr(cx: &LateContext<'_>, e: &Expr<'_>) -> u64 {
let mut h = SpanlessHash::new(cx);
h.hash_expr(e);
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 3ebfc5e00..90192f46c 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -66,7 +66,7 @@ pub mod visitors;
pub use self::attrs::*;
pub use self::check_proc_macro::{is_from_proc_macro, is_span_if, is_span_match};
pub use self::hir_utils::{
- both, count_eq, eq_expr_value, hash_expr, hash_stmt, over, HirEqInterExpr, SpanlessEq, SpanlessHash,
+ both, count_eq, eq_expr_value, hash_expr, hash_stmt, is_bool, over, HirEqInterExpr, SpanlessEq, SpanlessHash,
};
use core::ops::ControlFlow;
@@ -80,17 +80,16 @@ use rustc_ast::ast::{self, LitKind};
use rustc_ast::Attribute;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::unhash::UnhashMap;
-use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Namespace, Res};
-use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::hir_id::{HirIdMap, HirIdSet};
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk};
use rustc_hir::{
- def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness, Destination, Expr,
- ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource,
- Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind,
- TraitRef, TyKind, UnOp,
+ self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness, Destination,
+ Expr, ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, IsAsync, 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};
@@ -106,50 +105,28 @@ use rustc_middle::ty::{
layout::IntegerExt, BorrowKind, ClosureKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeVisitable, UpvarCapture,
};
use rustc_middle::ty::{FloatTy, IntTy, UintTy};
-use rustc_semver::RustcVersion;
-use rustc_session::Session;
use rustc_span::hygiene::{ExpnKind, MacroKind};
-use rustc_span::source_map::original_sp;
use rustc_span::source_map::SourceMap;
use rustc_span::sym;
-use rustc_span::symbol::{kw, Symbol};
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::symbol::{kw, Ident, Symbol};
+use rustc_span::Span;
use rustc_target::abi::Integer;
use crate::consts::{constant, Constant};
use crate::ty::{can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type, ty_is_fn_once_param};
use crate::visitors::for_each_expr;
-pub fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option<Span>) -> Option<RustcVersion> {
- if let Ok(version) = RustcVersion::parse(msrv) {
- return Some(version);
- } else if let Some(sess) = sess {
- if let Some(span) = span {
- sess.span_err(span, format!("`{msrv}` is not a valid Rust version"));
- }
- }
- None
-}
-
-pub fn meets_msrv(msrv: Option<RustcVersion>, lint_msrv: RustcVersion) -> bool {
- msrv.map_or(true, |msrv| msrv.meets(lint_msrv))
-}
-
#[macro_export]
macro_rules! extract_msrv_attr {
($context:ident) => {
fn enter_lint_attrs(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
let sess = rustc_lint::LintContext::sess(cx);
- match $crate::get_unique_inner_attr(sess, attrs, "msrv") {
- Some(msrv_attr) => {
- if let Some(msrv) = msrv_attr.value_str() {
- self.msrv = $crate::parse_msrv(&msrv.to_string(), Some(sess), Some(msrv_attr.span));
- } else {
- sess.span_err(msrv_attr.span, "bad clippy attribute");
- }
- },
- _ => (),
- }
+ self.msrv.enter_lint_attrs(sess, attrs);
+ }
+
+ fn exit_lint_attrs(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
+ let sess = rustc_lint::LintContext::sess(cx);
+ self.msrv.exit_lint_attrs(sess, attrs);
}
};
}
@@ -247,7 +224,7 @@ pub fn in_constant(cx: &LateContext<'_>, id: HirId) -> bool {
/// For example, use this to check whether a function call or a pattern is `Some(..)`.
pub fn is_res_lang_ctor(cx: &LateContext<'_>, res: Res, lang_item: LangItem) -> bool {
if let Res::Def(DefKind::Ctor(..), id) = res
- && let Ok(lang_id) = cx.tcx.lang_items().require(lang_item)
+ && let Some(lang_id) = cx.tcx.lang_items().get(lang_item)
&& let Some(id) = cx.tcx.opt_parent(id)
{
id == lang_id
@@ -303,7 +280,7 @@ pub fn is_lang_item_or_ctor(cx: &LateContext<'_>, did: DefId, item: LangItem) ->
_ => did,
};
- cx.tcx.lang_items().require(item).map_or(false, |id| id == did)
+ cx.tcx.lang_items().get(item) == Some(did)
}
pub fn is_unit_expr(expr: &Expr<'_>) -> bool {
@@ -435,6 +412,12 @@ pub fn is_expr_path_def_path(cx: &LateContext<'_>, expr: &Expr<'_>, segments: &[
}
/// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
+/// it matches the given lang item.
+pub fn is_path_lang_item<'tcx>(cx: &LateContext<'_>, maybe_path: &impl MaybePath<'tcx>, lang_item: LangItem) -> bool {
+ path_def_id(cx, maybe_path).map_or(false, |id| cx.tcx.lang_items().get(lang_item) == Some(id))
+}
+
+/// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
/// it matches the given diagnostic item.
pub fn is_path_diagnostic_item<'tcx>(
cx: &LateContext<'_>,
@@ -525,125 +508,177 @@ pub fn path_def_id<'tcx>(cx: &LateContext<'_>, maybe_path: &impl MaybePath<'tcx>
path_res(cx, maybe_path).opt_def_id()
}
-fn find_primitive<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<Item = DefId> + 'tcx {
- let single = |ty| tcx.incoherent_impls(ty).iter().copied();
- let empty = || [].iter().copied();
- match name {
- "bool" => single(BoolSimplifiedType),
- "char" => single(CharSimplifiedType),
- "str" => single(StrSimplifiedType),
- "array" => single(ArraySimplifiedType),
- "slice" => single(SliceSimplifiedType),
+fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<Item = DefId> + 'tcx {
+ let ty = match name {
+ "bool" => BoolSimplifiedType,
+ "char" => CharSimplifiedType,
+ "str" => StrSimplifiedType,
+ "array" => ArraySimplifiedType,
+ "slice" => SliceSimplifiedType,
// FIXME: rustdoc documents these two using just `pointer`.
//
// Maybe this is something we should do here too.
- "const_ptr" => single(PtrSimplifiedType(Mutability::Not)),
- "mut_ptr" => single(PtrSimplifiedType(Mutability::Mut)),
- "isize" => single(IntSimplifiedType(IntTy::Isize)),
- "i8" => single(IntSimplifiedType(IntTy::I8)),
- "i16" => single(IntSimplifiedType(IntTy::I16)),
- "i32" => single(IntSimplifiedType(IntTy::I32)),
- "i64" => single(IntSimplifiedType(IntTy::I64)),
- "i128" => single(IntSimplifiedType(IntTy::I128)),
- "usize" => single(UintSimplifiedType(UintTy::Usize)),
- "u8" => single(UintSimplifiedType(UintTy::U8)),
- "u16" => single(UintSimplifiedType(UintTy::U16)),
- "u32" => single(UintSimplifiedType(UintTy::U32)),
- "u64" => single(UintSimplifiedType(UintTy::U64)),
- "u128" => single(UintSimplifiedType(UintTy::U128)),
- "f32" => single(FloatSimplifiedType(FloatTy::F32)),
- "f64" => single(FloatSimplifiedType(FloatTy::F64)),
- _ => empty(),
- }
-}
-
-/// Resolves a def path like `std::vec::Vec`. `namespace_hint` can be supplied to disambiguate
-/// between `std::vec` the module and `std::vec` the macro
-///
-/// This function is expensive and should be used sparingly.
-pub fn def_path_res(cx: &LateContext<'_>, path: &[&str], namespace_hint: Option<Namespace>) -> Res {
- fn item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str, matches_ns: impl Fn(Res) -> bool) -> Option<Res> {
- match tcx.def_kind(def_id) {
- DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx
- .module_children(def_id)
- .iter()
- .find(|item| item.ident.name.as_str() == name && matches_ns(item.res.expect_non_local()))
- .map(|child| child.res.expect_non_local()),
- DefKind::Impl => tcx
- .associated_item_def_ids(def_id)
- .iter()
- .copied()
- .find(|assoc_def_id| tcx.item_name(*assoc_def_id).as_str() == name)
- .map(|assoc_def_id| Res::Def(tcx.def_kind(assoc_def_id), assoc_def_id)),
- DefKind::Struct | DefKind::Union => tcx
- .adt_def(def_id)
- .non_enum_variant()
- .fields
- .iter()
- .find(|f| f.name.as_str() == name)
- .map(|f| Res::Def(DefKind::Field, f.did)),
- _ => None,
+ "const_ptr" => PtrSimplifiedType(Mutability::Not),
+ "mut_ptr" => PtrSimplifiedType(Mutability::Mut),
+ "isize" => IntSimplifiedType(IntTy::Isize),
+ "i8" => IntSimplifiedType(IntTy::I8),
+ "i16" => IntSimplifiedType(IntTy::I16),
+ "i32" => IntSimplifiedType(IntTy::I32),
+ "i64" => IntSimplifiedType(IntTy::I64),
+ "i128" => IntSimplifiedType(IntTy::I128),
+ "usize" => UintSimplifiedType(UintTy::Usize),
+ "u8" => UintSimplifiedType(UintTy::U8),
+ "u16" => UintSimplifiedType(UintTy::U16),
+ "u32" => UintSimplifiedType(UintTy::U32),
+ "u64" => UintSimplifiedType(UintTy::U64),
+ "u128" => UintSimplifiedType(UintTy::U128),
+ "f32" => FloatSimplifiedType(FloatTy::F32),
+ "f64" => FloatSimplifiedType(FloatTy::F64),
+ _ => return [].iter().copied(),
+ };
+
+ tcx.incoherent_impls(ty).iter().copied()
+}
+
+fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Res> {
+ match tcx.def_kind(def_id) {
+ DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx
+ .module_children(def_id)
+ .iter()
+ .filter(|item| item.ident.name == name)
+ .map(|child| child.res.expect_non_local())
+ .collect(),
+ DefKind::Impl => tcx
+ .associated_item_def_ids(def_id)
+ .iter()
+ .copied()
+ .filter(|assoc_def_id| tcx.item_name(*assoc_def_id) == name)
+ .map(|assoc_def_id| Res::Def(tcx.def_kind(assoc_def_id), assoc_def_id))
+ .collect(),
+ _ => Vec::new(),
+ }
+}
+
+fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symbol) -> Vec<Res> {
+ let hir = tcx.hir();
+
+ let root_mod;
+ let item_kind = match hir.find_by_def_id(local_id) {
+ Some(Node::Crate(r#mod)) => {
+ root_mod = ItemKind::Mod(r#mod);
+ &root_mod
+ },
+ Some(Node::Item(item)) => &item.kind,
+ _ => return Vec::new(),
+ };
+
+ let res = |ident: Ident, owner_id: OwnerId| {
+ if ident.name == name {
+ let def_id = owner_id.to_def_id();
+ Some(Res::Def(tcx.def_kind(def_id), def_id))
+ } else {
+ None
}
+ };
+
+ match item_kind {
+ ItemKind::Mod(r#mod) => r#mod
+ .item_ids
+ .iter()
+ .filter_map(|&item_id| res(hir.item(item_id).ident, item_id.owner_id))
+ .collect(),
+ ItemKind::Impl(r#impl) => r#impl
+ .items
+ .iter()
+ .filter_map(|&ImplItemRef { ident, id, .. }| res(ident, id.owner_id))
+ .collect(),
+ ItemKind::Trait(.., trait_item_refs) => trait_item_refs
+ .iter()
+ .filter_map(|&TraitItemRef { ident, id, .. }| res(ident, id.owner_id))
+ .collect(),
+ _ => Vec::new(),
}
+}
- fn find_crate(tcx: TyCtxt<'_>, name: &str) -> Option<DefId> {
+fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Res> {
+ if let Some(local_id) = def_id.as_local() {
+ local_item_children_by_name(tcx, local_id, name)
+ } else {
+ non_local_item_children_by_name(tcx, def_id, name)
+ }
+}
+
+/// Resolves a def path like `std::vec::Vec`.
+///
+/// Can return multiple resolutions when there are multiple versions of the same crate, e.g.
+/// `memchr::memchr` could return the functions from both memchr 1.0 and memchr 2.0.
+///
+/// Also returns multiple results when there are mulitple paths under the same name e.g. `std::vec`
+/// would have both a [`DefKind::Mod`] and [`DefKind::Macro`].
+///
+/// This function is expensive and should be used sparingly.
+pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Vec<Res> {
+ fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> impl Iterator<Item = DefId> + '_ {
tcx.crates(())
.iter()
.copied()
- .find(|&num| tcx.crate_name(num).as_str() == name)
+ .filter(move |&num| tcx.crate_name(num) == name)
.map(CrateNum::as_def_id)
}
- let (base, path) = match *path {
+ let tcx = cx.tcx;
+
+ let (base, mut path) = match *path {
[primitive] => {
- return PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy);
+ return vec![PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy)];
},
[base, ref path @ ..] => (base, path),
- _ => return Res::Err,
+ _ => return Vec::new(),
};
- let tcx = cx.tcx;
- let starts = find_primitive(tcx, base)
- .chain(find_crate(tcx, base))
+
+ let base_sym = Symbol::intern(base);
+
+ let local_crate = if tcx.crate_name(LOCAL_CRATE) == base_sym {
+ Some(LOCAL_CRATE.as_def_id())
+ } else {
+ None
+ };
+
+ let starts = find_primitive_impls(tcx, base)
+ .chain(find_crates(tcx, base_sym))
+ .chain(local_crate)
.map(|id| Res::Def(tcx.def_kind(id), id));
- for first in starts {
- let last = path
- .iter()
- .copied()
- .enumerate()
- // for each segment, find the child item
- .try_fold(first, |res, (idx, segment)| {
- let matches_ns = |res: Res| {
- // If at the last segment in the path, respect the namespace hint
- if idx == path.len() - 1 {
- match namespace_hint {
- Some(ns) => res.matches_ns(ns),
- None => true,
- }
- } else {
- res.matches_ns(Namespace::TypeNS)
- }
- };
-
- let def_id = res.def_id();
- if let Some(item) = item_child_by_name(tcx, def_id, segment, matches_ns) {
- Some(item)
- } else if matches!(res, Res::Def(DefKind::Enum | DefKind::Struct, _)) {
- // it is not a child item so check inherent impl items
- tcx.inherent_impls(def_id)
- .iter()
- .find_map(|&impl_def_id| item_child_by_name(tcx, impl_def_id, segment, matches_ns))
- } else {
- None
- }
- });
+ let mut resolutions: Vec<Res> = starts.collect();
- if let Some(last) = last {
- return last;
- }
+ while let [segment, rest @ ..] = path {
+ path = rest;
+ let segment = Symbol::intern(segment);
+
+ resolutions = resolutions
+ .into_iter()
+ .filter_map(|res| res.opt_def_id())
+ .flat_map(|def_id| {
+ // When the current def_id is e.g. `struct S`, check the impl items in
+ // `impl S { ... }`
+ let inherent_impl_children = tcx
+ .inherent_impls(def_id)
+ .iter()
+ .flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment));
+
+ let direct_children = item_children_by_name(tcx, def_id, segment);
+
+ inherent_impl_children.chain(direct_children)
+ })
+ .collect();
}
- Res::Err
+ resolutions
+}
+
+/// Resolves a def path like `std::vec::Vec` to its [`DefId`]s, see [`def_path_res`].
+pub fn def_path_def_ids(cx: &LateContext<'_>, path: &[&str]) -> impl Iterator<Item = DefId> {
+ def_path_res(cx, path).into_iter().filter_map(|res| res.opt_def_id())
}
/// Convenience function to get the `DefId` of a trait by path.
@@ -651,10 +686,10 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str], namespace_hint: Option<
///
/// This function is expensive and should be used sparingly.
pub fn get_trait_def_id(cx: &LateContext<'_>, path: &[&str]) -> Option<DefId> {
- match def_path_res(cx, path, Some(Namespace::TypeNS)) {
+ def_path_res(cx, path).into_iter().find_map(|res| match res {
Res::Def(DefKind::Trait | DefKind::TraitAlias, trait_id) => Some(trait_id),
_ => None,
- }
+ })
}
/// Gets the `hir::TraitRef` of the trait the given method is implemented for.
@@ -760,7 +795,6 @@ pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -
/// constructor from the std library
fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool {
let std_types_symbols = &[
- sym::String,
sym::Vec,
sym::VecDeque,
sym::LinkedList,
@@ -775,9 +809,9 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<
if method.ident.name == sym::new {
if let Some(impl_did) = cx.tcx.impl_of_method(def_id) {
if let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() {
- return std_types_symbols
- .iter()
- .any(|&symbol| cx.tcx.is_diagnostic_item(symbol, adt.did()));
+ return std_types_symbols.iter().any(|&symbol| {
+ cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string()
+ });
}
}
}
@@ -834,7 +868,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &
ExprKind::Lit(hir::Lit {
node: LitKind::Str(ref sym, _),
..
- }) => return sym.is_empty() && is_path_diagnostic_item(cx, ty, sym::String),
+ }) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String),
ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec),
ExprKind::Repeat(_, ArrayLen::Body(len)) => {
if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(len.body).value.kind &&
@@ -954,7 +988,7 @@ impl std::ops::BitOrAssign for CaptureKind {
/// Note as this will walk up to parent expressions until the capture can be determined it should
/// only be used while making a closure somewhere a value is consumed. e.g. a block, match arm, or
/// function argument (other than a receiver).
-pub fn capture_local_usage<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>) -> CaptureKind {
+pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind {
fn pat_capture_kind(cx: &LateContext<'_>, pat: &Pat<'_>) -> CaptureKind {
let mut capture = CaptureKind::Ref(Mutability::Not);
pat.each_binding_or_first(&mut |_, id, span, _| match cx
@@ -1251,23 +1285,6 @@ pub fn contains_return(expr: &hir::Expr<'_>) -> bool {
.is_some()
}
-/// Extends the span to the beginning of the spans line, incl. whitespaces.
-///
-/// ```rust
-/// let x = ();
-/// // ^^
-/// // will be converted to
-/// let x = ();
-/// // ^^^^^^^^^^^^^^
-/// ```
-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]);
- span.with_lo(line_start)
-}
-
/// Gets the parent node, if any.
pub fn get_parent_node(tcx: TyCtxt<'_>, id: HirId) -> Option<Node<'_>> {
tcx.hir().parent_iter(id).next().map(|(_, node)| node)
@@ -1740,6 +1757,10 @@ pub fn has_attr(attrs: &[ast::Attribute], symbol: Symbol) -> bool {
attrs.iter().any(|attr| attr.has_name(symbol))
}
+pub fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {
+ has_attr(cx.tcx.hir().attrs(hir_id), sym::repr)
+}
+
pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool {
let map = &tcx.hir();
let mut prev_enclosing_node = None;
@@ -1812,7 +1833,7 @@ pub fn match_any_def_paths(cx: &LateContext<'_>, did: DefId, paths: &[&[&str]])
}
/// Checks if the given `DefId` matches the path.
-pub fn match_def_path<'tcx>(cx: &LateContext<'tcx>, did: DefId, syms: &[&str]) -> bool {
+pub fn match_def_path(cx: &LateContext<'_>, did: DefId, syms: &[&str]) -> bool {
// We should probably move to Symbols in Clippy as well rather than interning every time.
let path = cx.get_def_path(did);
syms.iter().map(|x| Symbol::intern(x)).eq(path.iter().copied())
@@ -1861,7 +1882,11 @@ 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 {
- matches!(kind, FnKind::ItemFn(_, _, header) if header.asyncness == IsAsync::Async)
+ match kind {
+ FnKind::ItemFn(_, _, header) => header.asyncness == IsAsync::Async,
+ FnKind::Method(_, sig) => sig.header.asyncness == IsAsync::Async,
+ FnKind::Closure => false,
+ }
}
/// Peels away all the compiler generated code surrounding the body of an async function,
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index 9a682fbe6..d13b34a66 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -199,12 +199,12 @@ pub fn first_node_in_macro(cx: &LateContext<'_>, node: &impl HirNode) -> Option<
pub fn is_panic(cx: &LateContext<'_>, def_id: DefId) -> bool {
let Some(name) = cx.tcx.get_diagnostic_name(def_id) else { return false };
matches!(
- name.as_str(),
- "core_panic_macro"
- | "std_panic_macro"
- | "core_panic_2015_macro"
- | "std_panic_2015_macro"
- | "core_panic_2021_macro"
+ name,
+ sym::core_panic_macro
+ | sym::std_panic_macro
+ | sym::core_panic_2015_macro
+ | sym::std_panic_2015_macro
+ | sym::core_panic_2021_macro
)
}
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 8b843732a..12a512f78 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -1,4 +1,11 @@
+use std::sync::OnceLock;
+
+use rustc_ast::Attribute;
use rustc_semver::RustcVersion;
+use rustc_session::Session;
+use rustc_span::Span;
+
+use crate::attrs::get_unique_attr;
macro_rules! msrv_aliases {
($($major:literal,$minor:literal,$patch:literal {
@@ -12,13 +19,14 @@ macro_rules! msrv_aliases {
// names may refer to stabilized feature flags or library items
msrv_aliases! {
+ 1,65,0 { LET_ELSE }
1,62,0 { BOOL_THEN_SOME }
1,58,0 { FORMAT_ARGS_CAPTURE }
1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR }
1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST }
- 1,51,0 { BORROW_AS_PTR, UNSIGNED_ABS }
+ 1,51,0 { BORROW_AS_PTR, SEEK_FROM_CURRENT, UNSIGNED_ABS }
1,50,0 { BOOL_THEN, CLAMP }
- 1,47,0 { TAU }
+ 1,47,0 { TAU, IS_ASCII_DIGIT_CONST }
1,46,0 { CONST_IF_MATCH }
1,45,0 { STR_STRIP_PREFIX }
1,43,0 { LOG2_10, LOG10_2 }
@@ -37,4 +45,99 @@ msrv_aliases! {
1,18,0 { HASH_MAP_RETAIN, HASH_SET_RETAIN }
1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }
1,16,0 { STR_REPEAT }
+ 1,55,0 { SEEK_REWIND }
+}
+
+fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option<Span>) -> Option<RustcVersion> {
+ if let Ok(version) = RustcVersion::parse(msrv) {
+ return Some(version);
+ } else if let Some(sess) = sess {
+ if let Some(span) = span {
+ sess.span_err(span, format!("`{msrv}` is not a valid Rust version"));
+ }
+ }
+ None
+}
+
+/// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]`
+#[derive(Debug, Clone, Default)]
+pub struct Msrv {
+ stack: Vec<RustcVersion>,
+}
+
+impl Msrv {
+ fn new(initial: Option<RustcVersion>) -> Self {
+ Self {
+ stack: Vec::from_iter(initial),
+ }
+ }
+
+ fn read_inner(conf_msrv: &Option<String>, sess: &Session) -> Self {
+ let cargo_msrv = std::env::var("CARGO_PKG_RUST_VERSION")
+ .ok()
+ .and_then(|v| parse_msrv(&v, None, None));
+ let clippy_msrv = conf_msrv.as_ref().and_then(|s| {
+ parse_msrv(s, None, None).or_else(|| {
+ sess.err(format!(
+ "error reading Clippy's configuration file. `{s}` is not a valid Rust version"
+ ));
+ None
+ })
+ });
+
+ // if both files have an msrv, let's compare them and emit a warning if they differ
+ if let Some(cargo_msrv) = cargo_msrv
+ && let Some(clippy_msrv) = clippy_msrv
+ && clippy_msrv != cargo_msrv
+ {
+ sess.warn(format!(
+ "the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`"
+ ));
+ }
+
+ Self::new(clippy_msrv.or(cargo_msrv))
+ }
+
+ /// Set the initial MSRV from the Clippy config file or from Cargo due to the `rust-version`
+ /// field in `Cargo.toml`
+ ///
+ /// Returns a `&'static Msrv` as `Copy` types are more easily passed to the
+ /// `register_{late,early}_pass` callbacks
+ pub fn read(conf_msrv: &Option<String>, sess: &Session) -> &'static Self {
+ static PARSED: OnceLock<Msrv> = OnceLock::new();
+
+ PARSED.get_or_init(|| Self::read_inner(conf_msrv, sess))
+ }
+
+ pub fn current(&self) -> Option<RustcVersion> {
+ self.stack.last().copied()
+ }
+
+ pub fn meets(&self, required: RustcVersion) -> bool {
+ self.current().map_or(true, |version| version.meets(required))
+ }
+
+ fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option<RustcVersion> {
+ if let Some(msrv_attr) = get_unique_attr(sess, attrs, "msrv") {
+ if let Some(msrv) = msrv_attr.value_str() {
+ return parse_msrv(&msrv.to_string(), Some(sess), Some(msrv_attr.span));
+ }
+
+ sess.span_err(msrv_attr.span, "bad clippy attribute");
+ }
+
+ None
+ }
+
+ pub fn enter_lint_attrs(&mut self, sess: &Session, attrs: &[Attribute]) {
+ if let Some(version) = Self::parse_attr(sess, attrs) {
+ self.stack.push(version);
+ }
+ }
+
+ pub fn exit_lint_attrs(&mut self, sess: &Session, attrs: &[Attribute]) {
+ if Self::parse_attr(sess, attrs).is_some() {
+ self.stack.pop();
+ }
+ }
}
diff --git a/src/tools/clippy/clippy_utils/src/numeric_literal.rs b/src/tools/clippy/clippy_utils/src/numeric_literal.rs
index c5dcd7b31..42bdfd482 100644
--- a/src/tools/clippy/clippy_utils/src/numeric_literal.rs
+++ b/src/tools/clippy/clippy_utils/src/numeric_literal.rs
@@ -1,4 +1,4 @@
-use rustc_ast::ast::{Lit, LitFloatType, LitIntType, LitKind};
+use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
use std::iter;
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
@@ -46,10 +46,6 @@ pub struct NumericLiteral<'a> {
}
impl<'a> NumericLiteral<'a> {
- pub fn from_lit(src: &'a str, lit: &Lit) -> Option<NumericLiteral<'a>> {
- NumericLiteral::from_lit_kind(src, &lit.kind)
- }
-
pub fn from_lit_kind(src: &'a str, lit_kind: &LitKind) -> Option<NumericLiteral<'a>> {
let unsigned_src = src.strip_prefix('-').map_or(src, |s| s);
if lit_kind.is_numeric()
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index bc8514734..6417f0f3c 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -60,6 +60,8 @@ pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
#[cfg(feature = "internal")]
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
pub const MEM_SWAP: [&str; 3] = ["core", "mem", "swap"];
+#[cfg(feature = "internal")]
+pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"];
pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];
pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"];
pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
@@ -72,7 +74,6 @@ pub const PEEKABLE: [&str; 5] = ["core", "iter", "adapters", "peekable", "Peekab
pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"];
#[cfg_attr(not(unix), allow(clippy::invalid_paths))]
pub const PERMISSIONS_FROM_MODE: [&str; 6] = ["std", "os", "unix", "fs", "PermissionsExt", "from_mode"];
-pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
pub const PTR_COPY: [&str; 3] = ["core", "intrinsics", "copy"];
pub const PTR_COPY_NONOVERLAPPING: [&str; 3] = ["core", "intrinsics", "copy_nonoverlapping"];
pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"];
@@ -101,8 +102,6 @@ pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"];
pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"];
pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"];
pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"];
-#[cfg(feature = "internal")]
-pub const RUSTC_VERSION: [&str; 2] = ["rustc_semver", "RustcVersion"];
pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"];
pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"];
pub const SLICE_FROM_RAW_PARTS: [&str; 4] = ["core", "slice", "raw", "from_raw_parts"];
@@ -115,6 +114,9 @@ pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"];
pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"];
pub const CONVERT_IDENTITY: [&str; 3] = ["core", "convert", "identity"];
pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"];
+pub const STD_IO_SEEK: [&str; 3] = ["std", "io", "Seek"];
+pub const STD_IO_SEEK_FROM_CURRENT: [&str; 4] = ["std", "io", "SeekFrom", "Current"];
+pub const STD_IO_SEEKFROM_START: [&str; 4] = ["std", "io", "SeekFrom", "Start"];
pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
pub const STRING_NEW: [&str; 4] = ["alloc", "string", "String", "new"];
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 45b63a4aa..480e8e55c 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
@@ -3,6 +3,7 @@
// of terminologies might not be relevant in the context of Clippy. Note that its behavior might
// differ from the time of `rustc` even if the name stays the same.
+use crate::msrvs::Msrv;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::mir::{
@@ -18,25 +19,28 @@ use std::borrow::Cow;
type McfResult = Result<(), (Span, Cow<'static, str>)>;
-pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: Option<RustcVersion>) -> McfResult {
+pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) -> McfResult {
let def_id = body.source.def_id();
let mut current = def_id;
loop {
let predicates = tcx.predicates_of(current);
for (predicate, _) in predicates.predicates {
match predicate.kind().skip_binder() {
- ty::PredicateKind::RegionOutlives(_)
- | ty::PredicateKind::TypeOutlives(_)
+ ty::PredicateKind::Clause(
+ ty::Clause::RegionOutlives(_)
+ | ty::Clause::TypeOutlives(_)
+ | ty::Clause::Projection(_)
+ | ty::Clause::Trait(..),
+ )
| ty::PredicateKind::WellFormed(_)
- | ty::PredicateKind::Projection(_)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
- | ty::PredicateKind::Trait(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {predicate:#?}"),
ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {predicate:#?}"),
ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {predicate:#?}"),
ty::PredicateKind::Coerce(_) => panic!("coerce predicate on function: {predicate:#?}"),
+ ty::PredicateKind::Ambiguous => panic!("ambiguous predicate on function: {predicate:#?}"),
}
}
match predicates.parent {
@@ -276,11 +280,11 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B
Ok(())
}
-fn check_terminator<'a, 'tcx>(
+fn check_terminator<'tcx>(
tcx: TyCtxt<'tcx>,
- body: &'a Body<'tcx>,
+ body: &Body<'tcx>,
terminator: &Terminator<'tcx>,
- msrv: Option<RustcVersion>,
+ msrv: &Msrv,
) -> McfResult {
let span = terminator.source_info.span;
match &terminator.kind {
@@ -364,7 +368,7 @@ fn check_terminator<'a, 'tcx>(
}
}
-fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: Option<RustcVersion>) -> bool {
+fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
tcx.is_const_fn(def_id)
&& tcx.lookup_const_stability(def_id).map_or(true, |const_stab| {
if let rustc_attr::StabilityLevel::Stable { since, .. } = const_stab.level {
@@ -383,15 +387,12 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: Option<RustcVersion>) -> bo
let since = rustc_span::Symbol::intern(short_version);
- crate::meets_msrv(
- msrv,
- RustcVersion::parse(since.as_str()).unwrap_or_else(|err| {
- panic!("`rustc_attr::StabilityLevel::Stable::since` is ill-formatted: `{since}`, {err:?}")
- }),
- )
+ msrv.meets(RustcVersion::parse(since.as_str()).unwrap_or_else(|err| {
+ panic!("`rustc_attr::StabilityLevel::Stable::since` is ill-formatted: `{since}`, {err:?}")
+ }))
} else {
// Unstable const fn with the feature enabled.
- msrv.is_none()
+ msrv.current().is_none()
}
})
}
diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs
index d28bd92d7..cd5dcfdac 100644
--- a/src/tools/clippy/clippy_utils/src/source.rs
+++ b/src/tools/clippy/clippy_utils/src/source.rs
@@ -2,13 +2,13 @@
#![allow(clippy::module_name_repetitions)]
-use crate::line_span;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LintContext};
+use rustc_session::Session;
use rustc_span::hygiene;
-use rustc_span::source_map::SourceMap;
-use rustc_span::{BytePos, Pos, Span, SpanData, SyntaxContext};
+use rustc_span::source_map::{original_sp, SourceMap};
+use rustc_span::{BytePos, Pos, Span, SpanData, SyntaxContext, DUMMY_SP};
use std::borrow::Cow;
/// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`.
@@ -55,6 +55,23 @@ fn first_char_in_first_line<T: LintContext>(cx: &T, span: Span) -> Option<BytePo
})
}
+/// Extends the span to the beginning of the spans line, incl. whitespaces.
+///
+/// ```rust
+/// let x = ();
+/// // ^^
+/// // will be converted to
+/// let x = ();
+/// // ^^^^^^^^^^^^^^
+/// ```
+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]);
+ span.with_lo(line_start)
+}
+
/// Returns the indentation of the line of a span
///
/// ```rust,ignore
@@ -189,10 +206,19 @@ pub fn snippet_with_applicability<'a, T: LintContext>(
default: &'a str,
applicability: &mut Applicability,
) -> Cow<'a, str> {
+ snippet_with_applicability_sess(cx.sess(), span, default, applicability)
+}
+
+fn snippet_with_applicability_sess<'a>(
+ sess: &Session,
+ span: Span,
+ default: &'a str,
+ applicability: &mut Applicability,
+) -> Cow<'a, str> {
if *applicability != Applicability::Unspecified && span.from_expansion() {
*applicability = Applicability::MaybeIncorrect;
}
- snippet_opt(cx, span).map_or_else(
+ snippet_opt_sess(sess, span).map_or_else(
|| {
if *applicability == Applicability::MachineApplicable {
*applicability = Applicability::HasPlaceholders;
@@ -210,8 +236,12 @@ pub fn snippet_with_macro_callsite<'a, T: LintContext>(cx: &T, span: Span, defau
}
/// Converts a span to a code snippet. Returns `None` if not available.
-pub fn snippet_opt<T: LintContext>(cx: &T, span: Span) -> Option<String> {
- cx.sess().source_map().span_to_snippet(span).ok()
+pub fn snippet_opt(cx: &impl LintContext, span: Span) -> Option<String> {
+ snippet_opt_sess(cx.sess(), span)
+}
+
+fn snippet_opt_sess(sess: &Session, span: Span) -> Option<String> {
+ sess.source_map().span_to_snippet(span).ok()
}
/// Converts a span (from a block) to a code snippet if available, otherwise use default.
@@ -261,8 +291,8 @@ pub fn snippet_block<'a, T: LintContext>(
/// Same as `snippet_block`, but adapts the applicability level by the rules of
/// `snippet_with_applicability`.
-pub fn snippet_block_with_applicability<'a, T: LintContext>(
- cx: &T,
+pub fn snippet_block_with_applicability<'a>(
+ cx: &impl LintContext,
span: Span,
default: &'a str,
indent_relative_to: Option<Span>,
@@ -283,7 +313,17 @@ pub fn snippet_block_with_applicability<'a, T: LintContext>(
///
/// This will also return whether or not the snippet is a macro call.
pub fn snippet_with_context<'a>(
- cx: &LateContext<'_>,
+ cx: &impl LintContext,
+ span: Span,
+ outer: SyntaxContext,
+ default: &'a str,
+ applicability: &mut Applicability,
+) -> (Cow<'a, str>, bool) {
+ snippet_with_context_sess(cx.sess(), span, outer, default, applicability)
+}
+
+fn snippet_with_context_sess<'a>(
+ sess: &Session,
span: Span,
outer: SyntaxContext,
default: &'a str,
@@ -302,7 +342,7 @@ pub fn snippet_with_context<'a>(
);
(
- snippet_with_applicability(cx, span, default, applicability),
+ snippet_with_applicability_sess(sess, span, default, applicability),
is_macro_call,
)
}
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index aad7da61a..b66604f33 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -176,25 +176,28 @@ impl<'a> Sugg<'a> {
}
/// Prepare a suggestion from an expression.
- pub fn ast(cx: &EarlyContext<'_>, expr: &ast::Expr, default: &'a str) -> Self {
+ pub fn ast(
+ cx: &EarlyContext<'_>,
+ expr: &ast::Expr,
+ default: &'a str,
+ ctxt: SyntaxContext,
+ app: &mut Applicability,
+ ) -> Self {
use rustc_ast::ast::RangeLimits;
- let snippet_without_expansion = |cx, span: Span, default| {
- if span.from_expansion() {
- snippet_with_macro_callsite(cx, span, default)
- } else {
- snippet(cx, span, default)
- }
- };
-
+ #[expect(clippy::match_wildcard_for_single_variants)]
match expr.kind {
+ _ if expr.span.ctxt() != ctxt => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0),
ast::ExprKind::AddrOf(..)
| ast::ExprKind::Box(..)
| ast::ExprKind::Closure { .. }
| ast::ExprKind::If(..)
| ast::ExprKind::Let(..)
| ast::ExprKind::Unary(..)
- | ast::ExprKind::Match(..) => Sugg::MaybeParen(snippet_without_expansion(cx, expr.span, default)),
+ | ast::ExprKind::Match(..) => match snippet_with_context(cx, expr.span, ctxt, default, app) {
+ (snip, false) => Sugg::MaybeParen(snip),
+ (snip, true) => Sugg::NonParen(snip),
+ },
ast::ExprKind::Async(..)
| ast::ExprKind::Block(..)
| ast::ExprKind::Break(..)
@@ -207,6 +210,7 @@ impl<'a> Sugg<'a> {
| ast::ExprKind::InlineAsm(..)
| ast::ExprKind::ConstBlock(..)
| ast::ExprKind::Lit(..)
+ | ast::ExprKind::IncludedBytes(..)
| ast::ExprKind::Loop(..)
| ast::ExprKind::MacCall(..)
| ast::ExprKind::MethodCall(..)
@@ -223,45 +227,49 @@ impl<'a> Sugg<'a> {
| ast::ExprKind::Array(..)
| ast::ExprKind::While(..)
| ast::ExprKind::Await(..)
- | ast::ExprKind::Err => Sugg::NonParen(snippet_without_expansion(cx, expr.span, default)),
+ | ast::ExprKind::Err => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0),
ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::HalfOpen) => Sugg::BinOp(
AssocOp::DotDot,
- lhs.as_ref()
- .map_or("".into(), |lhs| snippet_without_expansion(cx, lhs.span, default)),
- rhs.as_ref()
- .map_or("".into(), |rhs| snippet_without_expansion(cx, rhs.span, default)),
+ lhs.as_ref().map_or("".into(), |lhs| {
+ snippet_with_context(cx, lhs.span, ctxt, default, app).0
+ }),
+ rhs.as_ref().map_or("".into(), |rhs| {
+ snippet_with_context(cx, rhs.span, ctxt, default, app).0
+ }),
),
ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::Closed) => Sugg::BinOp(
AssocOp::DotDotEq,
- lhs.as_ref()
- .map_or("".into(), |lhs| snippet_without_expansion(cx, lhs.span, default)),
- rhs.as_ref()
- .map_or("".into(), |rhs| snippet_without_expansion(cx, rhs.span, default)),
+ lhs.as_ref().map_or("".into(), |lhs| {
+ snippet_with_context(cx, lhs.span, ctxt, default, app).0
+ }),
+ rhs.as_ref().map_or("".into(), |rhs| {
+ snippet_with_context(cx, rhs.span, ctxt, default, app).0
+ }),
),
ast::ExprKind::Assign(ref lhs, ref rhs, _) => Sugg::BinOp(
AssocOp::Assign,
- snippet_without_expansion(cx, lhs.span, default),
- snippet_without_expansion(cx, rhs.span, default),
+ snippet_with_context(cx, lhs.span, ctxt, default, app).0,
+ snippet_with_context(cx, rhs.span, ctxt, default, app).0,
),
ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => Sugg::BinOp(
astbinop2assignop(op),
- snippet_without_expansion(cx, lhs.span, default),
- snippet_without_expansion(cx, rhs.span, default),
+ snippet_with_context(cx, lhs.span, ctxt, default, app).0,
+ snippet_with_context(cx, rhs.span, ctxt, default, app).0,
),
ast::ExprKind::Binary(op, ref lhs, ref rhs) => Sugg::BinOp(
AssocOp::from_ast_binop(op.node),
- snippet_without_expansion(cx, lhs.span, default),
- snippet_without_expansion(cx, rhs.span, default),
+ snippet_with_context(cx, lhs.span, ctxt, default, app).0,
+ snippet_with_context(cx, rhs.span, ctxt, default, app).0,
),
ast::ExprKind::Cast(ref lhs, ref ty) => Sugg::BinOp(
AssocOp::As,
- snippet_without_expansion(cx, lhs.span, default),
- snippet_without_expansion(cx, ty.span, default),
+ snippet_with_context(cx, lhs.span, ctxt, default, app).0,
+ snippet_with_context(cx, ty.span, ctxt, default, app).0,
),
ast::ExprKind::Type(ref lhs, ref ty) => Sugg::BinOp(
AssocOp::Colon,
- snippet_without_expansion(cx, lhs.span, default),
- snippet_without_expansion(cx, ty.span, default),
+ snippet_with_context(cx, lhs.span, ctxt, default, app).0,
+ snippet_with_context(cx, ty.span, ctxt, default, app).0,
),
}
}
@@ -800,7 +808,7 @@ pub struct DerefClosure {
/// Returns `None` if no such use cases have been triggered in closure body
///
/// note: this only works on single line immutable closures with exactly one input parameter.
-pub fn deref_closure_args<'tcx>(cx: &LateContext<'_>, closure: &'tcx hir::Expr<'_>) -> Option<DerefClosure> {
+pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Option<DerefClosure> {
if let hir::ExprKind::Closure(&Closure { fn_decl, body, .. }) = closure.kind {
let closure_body = cx.tcx.hir().body(body);
// is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`)
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 4e024ce40..05c6eb7f2 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -9,19 +9,23 @@ use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety};
-use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::infer::{
+ type_variable::{TypeVariableOrigin, TypeVariableOriginKind},
+ TyCtxtInferExt,
+};
use rustc_lint::LateContext;
use rustc_middle::mir::interpret::{ConstValue, Scalar};
use rustc_middle::ty::{
- self, AdtDef, Binder, BoundRegion, DefIdTree, FnSig, IntTy, ParamEnv, Predicate, PredicateKind, ProjectionTy,
- Region, RegionKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy, VariantDef, VariantDiscr,
+ self, AdtDef, AssocKind, Binder, BoundRegion, DefIdTree, FnSig, IntTy, List, ParamEnv, Predicate, PredicateKind,
+ ProjectionTy, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy,
+ VariantDef, VariantDiscr,
};
use rustc_middle::ty::{GenericArg, GenericArgKind};
use rustc_span::symbol::Ident;
-use rustc_span::{sym, Span, Symbol};
+use rustc_span::{sym, Span, Symbol, DUMMY_SP};
use rustc_target::abi::{Size, VariantIdx};
use rustc_trait_selection::infer::InferCtxtExt;
-use rustc_trait_selection::traits::query::normalize::AtExt;
+use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
use std::iter;
use crate::{match_def_path, path_res, paths};
@@ -59,29 +63,80 @@ pub fn contains_adt_constructor<'tcx>(ty: Ty<'tcx>, adt: AdtDef<'tcx>) -> bool {
})
}
+/// Walks into `ty` and returns `true` if any inner type is an instance of the given type, or adt
+/// constructor of the same type.
+///
+/// This method also recurses into opaque type predicates, so call it with `impl Trait<U>` and `U`
+/// will also return `true`.
+pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, needle: Ty<'tcx>) -> bool {
+ fn contains_ty_adt_constructor_opaque_inner<'tcx>(
+ cx: &LateContext<'tcx>,
+ ty: Ty<'tcx>,
+ needle: Ty<'tcx>,
+ seen: &mut FxHashSet<DefId>,
+ ) -> bool {
+ ty.walk().any(|inner| match inner.unpack() {
+ GenericArgKind::Type(inner_ty) => {
+ if inner_ty == needle {
+ return true;
+ }
+
+ if inner_ty.ty_adt_def() == needle.ty_adt_def() {
+ return true;
+ }
+
+ if let ty::Opaque(def_id, _) = *inner_ty.kind() {
+ if !seen.insert(def_id) {
+ return false;
+ }
+
+ for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) {
+ match predicate.kind().skip_binder() {
+ // For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through
+ // and check substituions to find `U`.
+ ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
+ if trait_predicate
+ .trait_ref
+ .substs
+ .types()
+ .skip(1) // Skip the implicit `Self` generic parameter
+ .any(|ty| contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen))
+ {
+ return true;
+ }
+ },
+ // For `impl Trait<Assoc=U>`, it will register a predicate of `<T as Trait>::Assoc = U`,
+ // so we check the term for `U`.
+ ty::PredicateKind::Clause(ty::Clause::Projection(projection_predicate)) => {
+ if let ty::TermKind::Ty(ty) = projection_predicate.term.unpack() {
+ if contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen) {
+ return true;
+ }
+ };
+ },
+ _ => (),
+ }
+ }
+ }
+
+ false
+ },
+ GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
+ })
+ }
+
+ // A hash set to ensure that the same opaque type (`impl Trait` in RPIT or TAIT) is not
+ // visited twice.
+ let mut seen = FxHashSet::default();
+ contains_ty_adt_constructor_opaque_inner(cx, ty, needle, &mut seen)
+}
+
/// Resolves `<T as Iterator>::Item` for `T`
/// Do not invoke without first verifying that the type implements `Iterator`
pub fn get_iterator_item_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
cx.tcx
.get_diagnostic_item(sym::Iterator)
- .and_then(|iter_did| get_associated_type(cx, ty, iter_did, "Item"))
-}
-
-/// Returns the associated type `name` for `ty` as an implementation of `trait_id`.
-/// Do not invoke without first verifying that the type implements the trait.
-pub fn get_associated_type<'tcx>(
- cx: &LateContext<'tcx>,
- ty: Ty<'tcx>,
- trait_id: DefId,
- name: &str,
-) -> Option<Ty<'tcx>> {
- cx.tcx
- .associated_items(trait_id)
- .find_by_name_and_kind(cx.tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id)
- .and_then(|assoc| {
- let proj = cx.tcx.mk_projection(assoc.def_id, cx.tcx.mk_substs_trait(ty, &[]));
- cx.tcx.try_normalize_erasing_regions(cx.param_env, proj).ok()
- })
+ .and_then(|iter_did| cx.get_associated_type(ty, iter_did, "Item"))
}
/// Get the diagnostic name of a type, e.g. `sym::HashMap`. To check if a type
@@ -153,7 +208,13 @@ pub fn implements_trait<'tcx>(
trait_id: DefId,
ty_params: &[GenericArg<'tcx>],
) -> bool {
- implements_trait_with_env(cx.tcx, cx.param_env, ty, trait_id, ty_params)
+ implements_trait_with_env(
+ cx.tcx,
+ cx.param_env,
+ ty,
+ trait_id,
+ ty_params.iter().map(|&arg| Some(arg)),
+ )
}
/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
@@ -162,7 +223,7 @@ pub fn implements_trait_with_env<'tcx>(
param_env: ParamEnv<'tcx>,
ty: Ty<'tcx>,
trait_id: DefId,
- ty_params: &[GenericArg<'tcx>],
+ ty_params: impl IntoIterator<Item = Option<GenericArg<'tcx>>>,
) -> bool {
// Clippy shouldn't have infer types
assert!(!ty.needs_infer());
@@ -171,10 +232,18 @@ pub fn implements_trait_with_env<'tcx>(
if ty.has_escaping_bound_vars() {
return false;
}
- let ty_params = tcx.mk_substs(ty_params.iter());
let infcx = tcx.infer_ctxt().build();
+ let orig = TypeVariableOrigin {
+ kind: TypeVariableOriginKind::MiscVariable,
+ span: DUMMY_SP,
+ };
+ let ty_params = tcx.mk_substs(
+ ty_params
+ .into_iter()
+ .map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())),
+ );
infcx
- .type_implements_trait(trait_id, ty, ty_params, param_env)
+ .type_implements_trait(trait_id, [ty.into()].into_iter().chain(ty_params), param_env)
.must_apply_modulo_regions()
}
@@ -199,7 +268,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)),
ty::Opaque(def_id, _) => {
for (predicate, _) in cx.tcx.explicit_item_bounds(*def_id) {
- if let ty::PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder() {
+ if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() {
if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) {
return true;
}
@@ -243,7 +312,7 @@ fn is_normalizable_helper<'tcx>(
cache.insert(ty, false);
let infcx = cx.tcx.infer_ctxt().build();
let cause = rustc_middle::traits::ObligationCause::dummy();
- let result = if infcx.at(&cause, param_env).normalize(ty).is_ok() {
+ let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() {
match ty.kind() {
ty::Adt(def, substs) => def.variants().iter().all(|variant| {
variant
@@ -318,11 +387,7 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symb
/// Returns `false` if the `LangItem` is not defined.
pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool {
match ty.kind() {
- ty::Adt(adt, _) => cx
- .tcx
- .lang_items()
- .require(lang_item)
- .map_or(false, |li| li == adt.did()),
+ ty::Adt(adt, _) => cx.tcx.lang_items().get(lang_item) == Some(adt.did()),
_ => false,
}
}
@@ -622,7 +687,7 @@ fn sig_from_bounds<'tcx>(
for pred in predicates {
match pred.kind().skip_binder() {
- PredicateKind::Trait(p)
+ PredicateKind::Clause(ty::Clause::Trait(p))
if (lang_items.fn_trait() == Some(p.def_id())
|| lang_items.fn_mut_trait() == Some(p.def_id())
|| lang_items.fn_once_trait() == Some(p.def_id()))
@@ -635,7 +700,7 @@ fn sig_from_bounds<'tcx>(
}
inputs = Some(i);
},
- PredicateKind::Projection(p)
+ PredicateKind::Clause(ty::Clause::Projection(p))
if Some(p.projection_ty.item_def_id) == lang_items.fn_once_output()
&& p.projection_ty.self_ty() == ty =>
{
@@ -663,7 +728,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionTy<'tcx>) -> O
.subst_iter_copied(cx.tcx, ty.substs)
{
match pred.kind().skip_binder() {
- PredicateKind::Trait(p)
+ PredicateKind::Clause(ty::Clause::Trait(p))
if (lang_items.fn_trait() == Some(p.def_id())
|| lang_items.fn_mut_trait() == Some(p.def_id())
|| lang_items.fn_once_trait() == Some(p.def_id())) =>
@@ -676,7 +741,9 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionTy<'tcx>) -> O
}
inputs = Some(i);
},
- PredicateKind::Projection(p) if Some(p.projection_ty.item_def_id) == lang_items.fn_once_output() => {
+ PredicateKind::Clause(ty::Clause::Projection(p))
+ if Some(p.projection_ty.item_def_id) == lang_items.fn_once_output() =>
+ {
if output.is_some() {
// Multiple different fn trait impls. Is this even allowed?
return None;
@@ -705,7 +772,7 @@ impl core::ops::Add<u32> for EnumValue {
}
}
-/// Attempts to read the given constant as though it were an an enum value.
+/// Attempts to read the given constant as though it were an enum value.
#[expect(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option<EnumValue> {
if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) {
@@ -786,6 +853,42 @@ pub fn for_each_top_level_late_bound_region<B>(
ty.visit_with(&mut V { index: 0, f })
}
+pub struct AdtVariantInfo {
+ pub ind: usize,
+ pub size: u64,
+
+ /// (ind, size)
+ pub fields_size: Vec<(usize, u64)>,
+}
+
+impl AdtVariantInfo {
+ /// Returns ADT variants ordered by size
+ pub fn new<'tcx>(cx: &LateContext<'tcx>, adt: AdtDef<'tcx>, subst: &'tcx List<GenericArg<'tcx>>) -> Vec<Self> {
+ let mut variants_size = adt
+ .variants()
+ .iter()
+ .enumerate()
+ .map(|(i, variant)| {
+ let mut fields_size = variant
+ .fields
+ .iter()
+ .enumerate()
+ .map(|(i, f)| (i, approx_ty_size(cx, f.ty(cx.tcx, subst))))
+ .collect::<Vec<_>>();
+ fields_size.sort_by(|(_, a_size), (_, b_size)| (a_size.cmp(b_size)));
+
+ Self {
+ ind: i,
+ size: fields_size.iter().map(|(_, size)| size).sum(),
+ fields_size,
+ }
+ })
+ .collect::<Vec<_>>();
+ variants_size.sort_by(|a, b| (b.size.cmp(&a.size)));
+ variants_size
+ }
+}
+
/// Gets the struct or enum variant from the given `Res`
pub fn variant_of_res<'tcx>(cx: &LateContext<'tcx>, res: Res) -> Option<&'tcx VariantDef> {
match res {
@@ -815,7 +918,7 @@ pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tc
predicates
.iter()
.try_fold(false, |found, p| {
- if let PredicateKind::Trait(p) = p.kind().skip_binder()
+ if let PredicateKind::Clause(ty::Clause::Trait(p)) = p.kind().skip_binder()
&& let ty::Param(self_ty) = p.trait_ref.self_ty().kind()
&& ty.index == self_ty.index
{
@@ -880,3 +983,127 @@ pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 {
(Err(_), _) => 0,
}
}
+
+/// Makes the projection type for the named associated type in the given impl or trait impl.
+///
+/// This function is for associated types which are "known" to exist, and as such, will only return
+/// `None` when debug assertions are disabled in order to prevent ICE's. With debug assertions
+/// enabled this will check that the named associated type exists, the correct number of
+/// substitutions are given, and that the correct kinds of substitutions are given (lifetime,
+/// constant or type). This will not check if type normalization would succeed.
+pub fn make_projection<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ container_id: DefId,
+ assoc_ty: Symbol,
+ substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+) -> Option<ProjectionTy<'tcx>> {
+ fn helper<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ container_id: DefId,
+ assoc_ty: Symbol,
+ substs: SubstsRef<'tcx>,
+ ) -> Option<ProjectionTy<'tcx>> {
+ let Some(assoc_item) = tcx
+ .associated_items(container_id)
+ .find_by_name_and_kind(tcx, Ident::with_dummy_span(assoc_ty), AssocKind::Type, container_id)
+ else {
+ debug_assert!(false, "type `{assoc_ty}` not found in `{container_id:?}`");
+ return None;
+ };
+ #[cfg(debug_assertions)]
+ {
+ let generics = tcx.generics_of(assoc_item.def_id);
+ let generic_count = generics.parent_count + generics.params.len();
+ let params = generics
+ .parent
+ .map_or([].as_slice(), |id| &*tcx.generics_of(id).params)
+ .iter()
+ .chain(&generics.params)
+ .map(|x| &x.kind);
+
+ debug_assert!(
+ generic_count == substs.len(),
+ "wrong number of substs for `{:?}`: found `{}` expected `{generic_count}`.\n\
+ note: the expected parameters are: {:#?}\n\
+ the given arguments are: `{substs:#?}`",
+ assoc_item.def_id,
+ substs.len(),
+ params.map(ty::GenericParamDefKind::descr).collect::<Vec<_>>(),
+ );
+
+ if let Some((idx, (param, arg))) = params
+ .clone()
+ .zip(substs.iter().map(GenericArg::unpack))
+ .enumerate()
+ .find(|(_, (param, arg))| {
+ !matches!(
+ (param, arg),
+ (ty::GenericParamDefKind::Lifetime, GenericArgKind::Lifetime(_))
+ | (ty::GenericParamDefKind::Type { .. }, GenericArgKind::Type(_))
+ | (ty::GenericParamDefKind::Const { .. }, GenericArgKind::Const(_))
+ )
+ })
+ {
+ debug_assert!(
+ false,
+ "mismatched subst type at index {idx}: expected a {}, found `{arg:?}`\n\
+ note: the expected parameters are {:#?}\n\
+ the given arguments are {substs:#?}",
+ param.descr(),
+ params.map(ty::GenericParamDefKind::descr).collect::<Vec<_>>()
+ );
+ }
+ }
+
+ Some(ProjectionTy {
+ substs,
+ item_def_id: assoc_item.def_id,
+ })
+ }
+ helper(
+ tcx,
+ container_id,
+ assoc_ty,
+ tcx.mk_substs(substs.into_iter().map(Into::into)),
+ )
+}
+
+/// Normalizes the named associated type in the given impl or trait impl.
+///
+/// This function is for associated types which are "known" to be valid with the given
+/// substitutions, and as such, will only return `None` when debug assertions are disabled in order
+/// to prevent ICE's. With debug assertions enabled this will check that that type normalization
+/// succeeds as well as everything checked by `make_projection`.
+pub fn make_normalized_projection<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ param_env: ParamEnv<'tcx>,
+ container_id: DefId,
+ assoc_ty: Symbol,
+ substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+) -> Option<Ty<'tcx>> {
+ fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: ProjectionTy<'tcx>) -> Option<Ty<'tcx>> {
+ #[cfg(debug_assertions)]
+ if let Some((i, subst)) = ty
+ .substs
+ .iter()
+ .enumerate()
+ .find(|(_, subst)| subst.has_late_bound_regions())
+ {
+ debug_assert!(
+ false,
+ "substs contain late-bound region at index `{i}` which can't be normalized.\n\
+ use `TyCtxt::erase_late_bound_regions`\n\
+ note: subst is `{subst:#?}`",
+ );
+ return None;
+ }
+ match tcx.try_normalize_erasing_regions(param_env, tcx.mk_projection(ty.item_def_id, ty.substs)) {
+ Ok(ty) => Some(ty),
+ Err(e) => {
+ debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}");
+ None
+ },
+ }
+ }
+ helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, substs)?)
+}
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index 000fb51c0..ab3976a13 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -73,12 +73,7 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
self.update(cmt);
}
- fn fake_read(
- &mut self,
- _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>,
- _: FakeReadCause,
- _: HirId,
- ) {}
+ fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
}
pub struct ParamBindingIdCollector {
@@ -133,7 +128,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> {
}
}
- fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _: hir::HirId) {
+ fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) {
if let hir::def::Res::Local(id) = path.res {
if self.binding_ids.contains(&id) {
self.usage_found = true;
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index d4294f18f..863fb60fc 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -170,22 +170,22 @@ where
cb: F,
}
- struct WithStmtGuarg<'a, F> {
+ struct WithStmtGuard<'a, F> {
val: &'a mut RetFinder<F>,
prev_in_stmt: bool,
}
impl<F> RetFinder<F> {
- fn inside_stmt(&mut self, in_stmt: bool) -> WithStmtGuarg<'_, F> {
+ fn inside_stmt(&mut self, in_stmt: bool) -> WithStmtGuard<'_, F> {
let prev_in_stmt = std::mem::replace(&mut self.in_stmt, in_stmt);
- WithStmtGuarg {
+ WithStmtGuard {
val: self,
prev_in_stmt,
}
}
}
- impl<F> std::ops::Deref for WithStmtGuarg<'_, F> {
+ impl<F> std::ops::Deref for WithStmtGuard<'_, F> {
type Target = RetFinder<F>;
fn deref(&self) -> &Self::Target {
@@ -193,13 +193,13 @@ where
}
}
- impl<F> std::ops::DerefMut for WithStmtGuarg<'_, F> {
+ impl<F> std::ops::DerefMut for WithStmtGuard<'_, F> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.val
}
}
- impl<F> Drop for WithStmtGuarg<'_, F> {
+ impl<F> Drop for WithStmtGuard<'_, F> {
fn drop(&mut self) {
self.val.in_stmt = self.prev_in_stmt;
}
diff --git a/src/tools/clippy/declare_clippy_lint/Cargo.toml b/src/tools/clippy/declare_clippy_lint/Cargo.toml
new file mode 100644
index 000000000..082570f1f
--- /dev/null
+++ b/src/tools/clippy/declare_clippy_lint/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "declare_clippy_lint"
+version = "0.1.67"
+edition = "2021"
+publish = false
+
+[lib]
+proc-macro = true
+
+[dependencies]
+itertools = "0.10.1"
+quote = "1.0.21"
+syn = "1.0.100"
+
+[features]
+deny-warnings = []
diff --git a/src/tools/clippy/declare_clippy_lint/src/lib.rs b/src/tools/clippy/declare_clippy_lint/src/lib.rs
new file mode 100644
index 000000000..26210556d
--- /dev/null
+++ b/src/tools/clippy/declare_clippy_lint/src/lib.rs
@@ -0,0 +1,175 @@
+#![feature(let_chains)]
+#![cfg_attr(feature = "deny-warnings", deny(warnings))]
+// warn on lints, that are included in `rust-lang/rust`s bootstrap
+#![warn(rust_2018_idioms, unused_lifetimes)]
+
+use proc_macro::TokenStream;
+use quote::{format_ident, quote};
+use syn::parse::{Parse, ParseStream};
+use syn::{parse_macro_input, Attribute, Error, Ident, Lit, LitStr, Meta, Result, Token};
+
+fn parse_attr<const LEN: usize>(path: [&'static str; LEN], attr: &Attribute) -> Option<LitStr> {
+ if let Meta::NameValue(name_value) = attr.parse_meta().ok()? {
+ let path_idents = name_value.path.segments.iter().map(|segment| &segment.ident);
+
+ if itertools::equal(path_idents, path)
+ && let Lit::Str(lit) = name_value.lit
+ {
+ return Some(lit);
+ }
+ }
+
+ None
+}
+
+struct ClippyLint {
+ attrs: Vec<Attribute>,
+ explanation: String,
+ name: Ident,
+ category: Ident,
+ description: LitStr,
+}
+
+impl Parse for ClippyLint {
+ fn parse(input: ParseStream<'_>) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+
+ let mut in_code = false;
+ let mut explanation = String::new();
+ let mut version = None;
+ for attr in &attrs {
+ if let Some(lit) = parse_attr(["doc"], attr) {
+ let value = lit.value();
+ let line = value.strip_prefix(' ').unwrap_or(&value);
+
+ if line.starts_with("```") {
+ explanation += "```\n";
+ in_code = !in_code;
+ } else if !(in_code && line.starts_with("# ")) {
+ explanation += line;
+ explanation.push('\n');
+ }
+ } else if let Some(lit) = parse_attr(["clippy", "version"], attr) {
+ if let Some(duplicate) = version.replace(lit) {
+ return Err(Error::new_spanned(duplicate, "duplicate clippy::version"));
+ }
+ } else {
+ return Err(Error::new_spanned(attr, "unexpected attribute"));
+ }
+ }
+
+ input.parse::<Token![pub]>()?;
+ let name = input.parse()?;
+ input.parse::<Token![,]>()?;
+
+ let category = input.parse()?;
+ input.parse::<Token![,]>()?;
+
+ let description = input.parse()?;
+
+ Ok(Self {
+ attrs,
+ explanation,
+ name,
+ category,
+ description,
+ })
+ }
+}
+
+/// Macro used to declare a Clippy lint.
+///
+/// Every lint declaration consists of 4 parts:
+///
+/// 1. The documentation, which is used for the website and `cargo clippy --explain`
+/// 2. The `LINT_NAME`. See [lint naming][lint_naming] on lint naming conventions.
+/// 3. The `lint_level`, which is a mapping from *one* of our lint groups to `Allow`, `Warn` or
+/// `Deny`. The lint level here has nothing to do with what lint groups the lint is a part of.
+/// 4. The `description` that contains a short explanation on what's wrong with code where the
+/// lint is triggered.
+///
+/// Currently the categories `style`, `correctness`, `suspicious`, `complexity` and `perf` are
+/// enabled by default. As said in the README.md of this repository, if the lint level mapping
+/// changes, please update README.md.
+///
+/// # Example
+///
+/// ```
+/// use rustc_session::declare_tool_lint;
+///
+/// declare_clippy_lint! {
+/// /// ### What it does
+/// /// Checks for ... (describe what the lint matches).
+/// ///
+/// /// ### Why is this bad?
+/// /// Supply the reason for linting the code.
+/// ///
+/// /// ### Example
+/// /// ```rust
+/// /// Insert a short example of code that triggers the lint
+/// /// ```
+/// ///
+/// /// Use instead:
+/// /// ```rust
+/// /// Insert a short example of improved code that doesn't trigger the lint
+/// /// ```
+/// #[clippy::version = "1.65.0"]
+/// pub LINT_NAME,
+/// pedantic,
+/// "description"
+/// }
+/// ```
+/// [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
+#[proc_macro]
+pub fn declare_clippy_lint(input: TokenStream) -> TokenStream {
+ let ClippyLint {
+ attrs,
+ explanation,
+ name,
+ category,
+ description,
+ } = parse_macro_input!(input as ClippyLint);
+
+ let mut category = category.to_string();
+
+ let level = format_ident!(
+ "{}",
+ match category.as_str() {
+ "correctness" => "Deny",
+ "style" | "suspicious" | "complexity" | "perf" | "internal_warn" => "Warn",
+ "pedantic" | "restriction" | "cargo" | "nursery" | "internal" => "Allow",
+ _ => panic!("unknown category {category}"),
+ },
+ );
+
+ let info = if category == "internal_warn" {
+ None
+ } else {
+ let info_name = format_ident!("{name}_INFO");
+
+ (&mut category[0..1]).make_ascii_uppercase();
+ let category_variant = format_ident!("{category}");
+
+ Some(quote! {
+ pub(crate) static #info_name: &'static crate::LintInfo = &crate::LintInfo {
+ lint: &#name,
+ category: crate::LintCategory::#category_variant,
+ explanation: #explanation,
+ };
+ })
+ };
+
+ let output = quote! {
+ declare_tool_lint! {
+ #(#attrs)*
+ pub clippy::#name,
+ #level,
+ #description,
+ report_in_external_macro: true
+ }
+
+ #info
+ };
+
+ TokenStream::from(output)
+}
diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs
index 54c1b80c4..bd49f0960 100644
--- a/src/tools/clippy/lintcheck/src/main.rs
+++ b/src/tools/clippy/lintcheck/src/main.rs
@@ -120,8 +120,8 @@ impl ClippyWarning {
format!("$CARGO_HOME/{}", stripped.display())
} else {
format!(
- "target/lintcheck/sources/{}-{}/{}",
- crate_name, crate_version, span.file_name
+ "target/lintcheck/sources/{crate_name}-{crate_version}/{}",
+ span.file_name
)
};
@@ -322,13 +322,13 @@ impl Crate {
if config.max_jobs == 1 {
println!(
- "{}/{} {}% Linting {} {}",
- index, total_crates_to_lint, perc, &self.name, &self.version
+ "{index}/{total_crates_to_lint} {perc}% Linting {} {}",
+ &self.name, &self.version
);
} else {
println!(
- "{}/{} {}% Linting {} {} in target dir {:?}",
- index, total_crates_to_lint, perc, &self.name, &self.version, thread_index
+ "{index}/{total_crates_to_lint} {perc}% Linting {} {} in target dir {thread_index:?}",
+ &self.name, &self.version
);
}
@@ -398,8 +398,7 @@ impl Crate {
.output()
.unwrap_or_else(|error| {
panic!(
- "Encountered error:\n{:?}\ncargo_clippy_path: {}\ncrate path:{}\n",
- error,
+ "Encountered error:\n{error:?}\ncargo_clippy_path: {}\ncrate path:{}\n",
&cargo_clippy_path.display(),
&self.path.display()
);
@@ -544,34 +543,6 @@ fn gather_stats(clippy_warnings: &[ClippyWarning]) -> (String, HashMap<&String,
(stats_string, counter)
}
-/// check if the latest modification of the logfile is older than the modification date of the
-/// clippy binary, if this is true, we should clean the lintchec shared target directory and recheck
-fn lintcheck_needs_rerun(lintcheck_logs_path: &Path, paths: [&Path; 2]) -> bool {
- if !lintcheck_logs_path.exists() {
- return true;
- }
-
- let clippy_modified: std::time::SystemTime = {
- let [cargo, driver] = paths.map(|p| {
- std::fs::metadata(p)
- .expect("failed to get metadata of file")
- .modified()
- .expect("failed to get modification date")
- });
- // the oldest modification of either of the binaries
- std::cmp::max(cargo, driver)
- };
-
- let logs_modified: std::time::SystemTime = std::fs::metadata(lintcheck_logs_path)
- .expect("failed to get metadata of file")
- .modified()
- .expect("failed to get modification date");
-
- // time is represented in seconds since X
- // logs_modified 2 and clippy_modified 5 means clippy binary is older and we need to recheck
- logs_modified < clippy_modified
-}
-
#[allow(clippy::too_many_lines)]
fn main() {
// We're being executed as a `RUSTC_WRAPPER` as part of `--recursive`
@@ -594,23 +565,6 @@ fn main() {
let cargo_clippy_path = fs::canonicalize(format!("target/debug/cargo-clippy{EXE_SUFFIX}")).unwrap();
let clippy_driver_path = fs::canonicalize(format!("target/debug/clippy-driver{EXE_SUFFIX}")).unwrap();
- // if the clippy bin is newer than our logs, throw away target dirs to force clippy to
- // refresh the logs
- if lintcheck_needs_rerun(
- &config.lintcheck_results_path,
- [&cargo_clippy_path, &clippy_driver_path],
- ) {
- let shared_target_dir = "target/lintcheck/shared_target_dir";
- // if we get an Err here, the shared target dir probably does simply not exist
- if let Ok(metadata) = std::fs::metadata(shared_target_dir) {
- if metadata.is_dir() {
- println!("Clippy is newer than lint check logs, clearing lintcheck shared target dir...");
- std::fs::remove_dir_all(shared_target_dir)
- .expect("failed to remove target/lintcheck/shared_target_dir");
- }
- }
- }
-
// assert that clippy is found
assert!(
cargo_clippy_path.is_file(),
@@ -678,7 +632,7 @@ fn main() {
.unwrap();
let server = config.recursive.then(|| {
- fs::remove_dir_all("target/lintcheck/shared_target_dir/recursive").unwrap_or_default();
+ let _ = fs::remove_dir_all("target/lintcheck/shared_target_dir/recursive");
LintcheckServer::spawn(recursive_options)
});
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 748d8a317..19fee38db 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
[toolchain]
-channel = "nightly-2022-10-20"
-components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
+channel = "nightly-2022-12-01"
+components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/src/docs.rs b/src/tools/clippy/src/docs.rs
deleted file mode 100644
index c033ad294..000000000
--- a/src/tools/clippy/src/docs.rs
+++ /dev/null
@@ -1,606 +0,0 @@
-// autogenerated. Please look at /clippy_dev/src/update_lints.rs
-
-macro_rules! include_lint {
- ($file_name: expr) => {
- include_str!($file_name)
- };
-}
-
-macro_rules! docs {
- ($($lint_name: expr,)*) => {
- pub fn explain(lint: &str) {
- println!("{}", match lint {
- $(
- $lint_name => include_lint!(concat!("docs/", concat!($lint_name, ".txt"))),
- )*
- _ => "unknown lint",
- })
- }
- }
-}
-
-docs! {
- "absurd_extreme_comparisons",
- "alloc_instead_of_core",
- "allow_attributes_without_reason",
- "almost_complete_letter_range",
- "almost_swapped",
- "approx_constant",
- "arithmetic_side_effects",
- "as_conversions",
- "as_ptr_cast_mut",
- "as_underscore",
- "assertions_on_constants",
- "assertions_on_result_states",
- "assign_op_pattern",
- "async_yields_async",
- "await_holding_invalid_type",
- "await_holding_lock",
- "await_holding_refcell_ref",
- "bad_bit_mask",
- "bind_instead_of_map",
- "blanket_clippy_restriction_lints",
- "blocks_in_if_conditions",
- "bool_assert_comparison",
- "bool_comparison",
- "bool_to_int_with_if",
- "borrow_as_ptr",
- "borrow_deref_ref",
- "borrow_interior_mutable_const",
- "borrowed_box",
- "box_collection",
- "box_default",
- "boxed_local",
- "branches_sharing_code",
- "builtin_type_shadow",
- "bytes_count_to_len",
- "bytes_nth",
- "cargo_common_metadata",
- "case_sensitive_file_extension_comparisons",
- "cast_abs_to_unsigned",
- "cast_enum_constructor",
- "cast_enum_truncation",
- "cast_lossless",
- "cast_nan_to_int",
- "cast_possible_truncation",
- "cast_possible_wrap",
- "cast_precision_loss",
- "cast_ptr_alignment",
- "cast_ref_to_mut",
- "cast_sign_loss",
- "cast_slice_different_sizes",
- "cast_slice_from_raw_parts",
- "char_lit_as_u8",
- "chars_last_cmp",
- "chars_next_cmp",
- "checked_conversions",
- "clone_double_ref",
- "clone_on_copy",
- "clone_on_ref_ptr",
- "cloned_instead_of_copied",
- "cmp_nan",
- "cmp_null",
- "cmp_owned",
- "cognitive_complexity",
- "collapsible_else_if",
- "collapsible_if",
- "collapsible_match",
- "collapsible_str_replace",
- "comparison_chain",
- "comparison_to_empty",
- "copy_iterator",
- "crate_in_macro_def",
- "create_dir",
- "crosspointer_transmute",
- "dbg_macro",
- "debug_assert_with_mut_call",
- "decimal_literal_representation",
- "declare_interior_mutable_const",
- "default_instead_of_iter_empty",
- "default_numeric_fallback",
- "default_trait_access",
- "default_union_representation",
- "deprecated_cfg_attr",
- "deprecated_semver",
- "deref_addrof",
- "deref_by_slicing",
- "derivable_impls",
- "derive_hash_xor_eq",
- "derive_ord_xor_partial_ord",
- "derive_partial_eq_without_eq",
- "disallowed_macros",
- "disallowed_methods",
- "disallowed_names",
- "disallowed_script_idents",
- "disallowed_types",
- "diverging_sub_expression",
- "doc_link_with_quotes",
- "doc_markdown",
- "double_comparisons",
- "double_must_use",
- "double_neg",
- "double_parens",
- "drop_copy",
- "drop_non_drop",
- "drop_ref",
- "duplicate_mod",
- "duplicate_underscore_argument",
- "duration_subsec",
- "else_if_without_else",
- "empty_drop",
- "empty_enum",
- "empty_line_after_outer_attr",
- "empty_loop",
- "empty_structs_with_brackets",
- "enum_clike_unportable_variant",
- "enum_glob_use",
- "enum_variant_names",
- "eq_op",
- "equatable_if_let",
- "erasing_op",
- "err_expect",
- "excessive_precision",
- "exhaustive_enums",
- "exhaustive_structs",
- "exit",
- "expect_fun_call",
- "expect_used",
- "expl_impl_clone_on_copy",
- "explicit_auto_deref",
- "explicit_counter_loop",
- "explicit_deref_methods",
- "explicit_into_iter_loop",
- "explicit_iter_loop",
- "explicit_write",
- "extend_with_drain",
- "extra_unused_lifetimes",
- "fallible_impl_from",
- "field_reassign_with_default",
- "filetype_is_file",
- "filter_map_identity",
- "filter_map_next",
- "filter_next",
- "flat_map_identity",
- "flat_map_option",
- "float_arithmetic",
- "float_cmp",
- "float_cmp_const",
- "float_equality_without_abs",
- "fn_address_comparisons",
- "fn_params_excessive_bools",
- "fn_to_numeric_cast",
- "fn_to_numeric_cast_any",
- "fn_to_numeric_cast_with_truncation",
- "for_kv_map",
- "forget_copy",
- "forget_non_drop",
- "forget_ref",
- "format_in_format_args",
- "format_push_string",
- "from_iter_instead_of_collect",
- "from_over_into",
- "from_str_radix_10",
- "future_not_send",
- "get_first",
- "get_last_with_len",
- "get_unwrap",
- "identity_op",
- "if_let_mutex",
- "if_not_else",
- "if_same_then_else",
- "if_then_some_else_none",
- "ifs_same_cond",
- "implicit_clone",
- "implicit_hasher",
- "implicit_return",
- "implicit_saturating_add",
- "implicit_saturating_sub",
- "imprecise_flops",
- "inconsistent_digit_grouping",
- "inconsistent_struct_constructor",
- "index_refutable_slice",
- "indexing_slicing",
- "ineffective_bit_mask",
- "inefficient_to_string",
- "infallible_destructuring_match",
- "infinite_iter",
- "inherent_to_string",
- "inherent_to_string_shadow_display",
- "init_numbered_fields",
- "inline_always",
- "inline_asm_x86_att_syntax",
- "inline_asm_x86_intel_syntax",
- "inline_fn_without_body",
- "inspect_for_each",
- "int_plus_one",
- "integer_arithmetic",
- "integer_division",
- "into_iter_on_ref",
- "invalid_null_ptr_usage",
- "invalid_regex",
- "invalid_upcast_comparisons",
- "invalid_utf8_in_unchecked",
- "invisible_characters",
- "is_digit_ascii_radix",
- "items_after_statements",
- "iter_cloned_collect",
- "iter_count",
- "iter_kv_map",
- "iter_next_loop",
- "iter_next_slice",
- "iter_not_returning_iterator",
- "iter_nth",
- "iter_nth_zero",
- "iter_on_empty_collections",
- "iter_on_single_items",
- "iter_overeager_cloned",
- "iter_skip_next",
- "iter_with_drain",
- "iterator_step_by_zero",
- "just_underscores_and_digits",
- "large_const_arrays",
- "large_digit_groups",
- "large_enum_variant",
- "large_include_file",
- "large_stack_arrays",
- "large_types_passed_by_value",
- "len_without_is_empty",
- "len_zero",
- "let_and_return",
- "let_underscore_drop",
- "let_underscore_lock",
- "let_underscore_must_use",
- "let_unit_value",
- "linkedlist",
- "lossy_float_literal",
- "macro_use_imports",
- "main_recursion",
- "manual_assert",
- "manual_async_fn",
- "manual_bits",
- "manual_clamp",
- "manual_filter",
- "manual_filter_map",
- "manual_find",
- "manual_find_map",
- "manual_flatten",
- "manual_instant_elapsed",
- "manual_map",
- "manual_memcpy",
- "manual_non_exhaustive",
- "manual_ok_or",
- "manual_range_contains",
- "manual_rem_euclid",
- "manual_retain",
- "manual_saturating_arithmetic",
- "manual_split_once",
- "manual_str_repeat",
- "manual_string_new",
- "manual_strip",
- "manual_swap",
- "manual_unwrap_or",
- "many_single_char_names",
- "map_clone",
- "map_collect_result_unit",
- "map_entry",
- "map_err_ignore",
- "map_flatten",
- "map_identity",
- "map_unwrap_or",
- "match_as_ref",
- "match_bool",
- "match_like_matches_macro",
- "match_on_vec_items",
- "match_overlapping_arm",
- "match_ref_pats",
- "match_result_ok",
- "match_same_arms",
- "match_single_binding",
- "match_str_case_mismatch",
- "match_wild_err_arm",
- "match_wildcard_for_single_variants",
- "maybe_infinite_iter",
- "mem_forget",
- "mem_replace_option_with_none",
- "mem_replace_with_default",
- "mem_replace_with_uninit",
- "min_max",
- "mismatched_target_os",
- "mismatching_type_param_order",
- "misrefactored_assign_op",
- "missing_const_for_fn",
- "missing_docs_in_private_items",
- "missing_enforced_import_renames",
- "missing_errors_doc",
- "missing_inline_in_public_items",
- "missing_panics_doc",
- "missing_safety_doc",
- "missing_spin_loop",
- "missing_trait_methods",
- "mistyped_literal_suffixes",
- "mixed_case_hex_literals",
- "mixed_read_write_in_expression",
- "mod_module_files",
- "module_inception",
- "module_name_repetitions",
- "modulo_arithmetic",
- "modulo_one",
- "multi_assignments",
- "multiple_crate_versions",
- "multiple_inherent_impl",
- "must_use_candidate",
- "must_use_unit",
- "mut_from_ref",
- "mut_mut",
- "mut_mutex_lock",
- "mut_range_bound",
- "mutable_key_type",
- "mutex_atomic",
- "mutex_integer",
- "naive_bytecount",
- "needless_arbitrary_self_type",
- "needless_bitwise_bool",
- "needless_bool",
- "needless_borrow",
- "needless_borrowed_reference",
- "needless_collect",
- "needless_continue",
- "needless_doctest_main",
- "needless_for_each",
- "needless_late_init",
- "needless_lifetimes",
- "needless_match",
- "needless_option_as_deref",
- "needless_option_take",
- "needless_parens_on_range_literals",
- "needless_pass_by_value",
- "needless_question_mark",
- "needless_range_loop",
- "needless_return",
- "needless_splitn",
- "needless_update",
- "neg_cmp_op_on_partial_ord",
- "neg_multiply",
- "negative_feature_names",
- "never_loop",
- "new_ret_no_self",
- "new_without_default",
- "no_effect",
- "no_effect_replace",
- "no_effect_underscore_binding",
- "non_ascii_literal",
- "non_octal_unix_permissions",
- "non_send_fields_in_send_ty",
- "nonminimal_bool",
- "nonsensical_open_options",
- "nonstandard_macro_braces",
- "not_unsafe_ptr_arg_deref",
- "obfuscated_if_else",
- "octal_escapes",
- "ok_expect",
- "only_used_in_recursion",
- "op_ref",
- "option_as_ref_deref",
- "option_env_unwrap",
- "option_filter_map",
- "option_if_let_else",
- "option_map_or_none",
- "option_map_unit_fn",
- "option_option",
- "or_fun_call",
- "or_then_unwrap",
- "out_of_bounds_indexing",
- "overflow_check_conditional",
- "overly_complex_bool_expr",
- "panic",
- "panic_in_result_fn",
- "panicking_unwrap",
- "partial_pub_fields",
- "partialeq_ne_impl",
- "partialeq_to_none",
- "path_buf_push_overwrite",
- "pattern_type_mismatch",
- "possible_missing_comma",
- "precedence",
- "print_in_format_impl",
- "print_literal",
- "print_stderr",
- "print_stdout",
- "print_with_newline",
- "println_empty_string",
- "ptr_arg",
- "ptr_as_ptr",
- "ptr_eq",
- "ptr_offset_with_cast",
- "pub_use",
- "question_mark",
- "range_minus_one",
- "range_plus_one",
- "range_zip_with_len",
- "rc_buffer",
- "rc_clone_in_vec_init",
- "rc_mutex",
- "read_zero_byte_vec",
- "recursive_format_impl",
- "redundant_allocation",
- "redundant_clone",
- "redundant_closure",
- "redundant_closure_call",
- "redundant_closure_for_method_calls",
- "redundant_else",
- "redundant_feature_names",
- "redundant_field_names",
- "redundant_pattern",
- "redundant_pattern_matching",
- "redundant_pub_crate",
- "redundant_slicing",
- "redundant_static_lifetimes",
- "ref_binding_to_reference",
- "ref_option_ref",
- "repeat_once",
- "rest_pat_in_fully_bound_structs",
- "result_large_err",
- "result_map_or_into_option",
- "result_map_unit_fn",
- "result_unit_err",
- "return_self_not_must_use",
- "reversed_empty_ranges",
- "same_functions_in_if_condition",
- "same_item_push",
- "same_name_method",
- "search_is_some",
- "self_assignment",
- "self_named_constructors",
- "self_named_module_files",
- "semicolon_if_nothing_returned",
- "separated_literal_suffix",
- "serde_api_misuse",
- "shadow_reuse",
- "shadow_same",
- "shadow_unrelated",
- "short_circuit_statement",
- "should_implement_trait",
- "significant_drop_in_scrutinee",
- "similar_names",
- "single_char_add_str",
- "single_char_lifetime_names",
- "single_char_pattern",
- "single_component_path_imports",
- "single_element_loop",
- "single_match",
- "single_match_else",
- "size_of_in_element_count",
- "skip_while_next",
- "slow_vector_initialization",
- "stable_sort_primitive",
- "std_instead_of_alloc",
- "std_instead_of_core",
- "str_to_string",
- "string_add",
- "string_add_assign",
- "string_extend_chars",
- "string_from_utf8_as_bytes",
- "string_lit_as_bytes",
- "string_slice",
- "string_to_string",
- "strlen_on_c_strings",
- "struct_excessive_bools",
- "suboptimal_flops",
- "suspicious_arithmetic_impl",
- "suspicious_assignment_formatting",
- "suspicious_else_formatting",
- "suspicious_map",
- "suspicious_op_assign_impl",
- "suspicious_operation_groupings",
- "suspicious_splitn",
- "suspicious_to_owned",
- "suspicious_unary_op_formatting",
- "swap_ptr_to_ref",
- "tabs_in_doc_comments",
- "temporary_assignment",
- "to_digit_is_some",
- "to_string_in_format_args",
- "todo",
- "too_many_arguments",
- "too_many_lines",
- "toplevel_ref_arg",
- "trailing_empty_array",
- "trait_duplication_in_bounds",
- "transmute_bytes_to_str",
- "transmute_float_to_int",
- "transmute_int_to_bool",
- "transmute_int_to_char",
- "transmute_int_to_float",
- "transmute_num_to_bytes",
- "transmute_ptr_to_ptr",
- "transmute_ptr_to_ref",
- "transmute_undefined_repr",
- "transmutes_expressible_as_ptr_casts",
- "transmuting_null",
- "trim_split_whitespace",
- "trivial_regex",
- "trivially_copy_pass_by_ref",
- "try_err",
- "type_complexity",
- "type_repetition_in_bounds",
- "undocumented_unsafe_blocks",
- "undropped_manually_drops",
- "unicode_not_nfc",
- "unimplemented",
- "uninit_assumed_init",
- "uninit_vec",
- "uninlined_format_args",
- "unit_arg",
- "unit_cmp",
- "unit_hash",
- "unit_return_expecting_ord",
- "unnecessary_cast",
- "unnecessary_filter_map",
- "unnecessary_find_map",
- "unnecessary_fold",
- "unnecessary_join",
- "unnecessary_lazy_evaluations",
- "unnecessary_mut_passed",
- "unnecessary_operation",
- "unnecessary_owned_empty_strings",
- "unnecessary_self_imports",
- "unnecessary_sort_by",
- "unnecessary_to_owned",
- "unnecessary_unwrap",
- "unnecessary_wraps",
- "unneeded_field_pattern",
- "unneeded_wildcard_pattern",
- "unnested_or_patterns",
- "unreachable",
- "unreadable_literal",
- "unsafe_derive_deserialize",
- "unsafe_removed_from_name",
- "unseparated_literal_suffix",
- "unsound_collection_transmute",
- "unused_async",
- "unused_format_specs",
- "unused_io_amount",
- "unused_peekable",
- "unused_rounding",
- "unused_self",
- "unused_unit",
- "unusual_byte_groupings",
- "unwrap_in_result",
- "unwrap_or_else_default",
- "unwrap_used",
- "upper_case_acronyms",
- "use_debug",
- "use_self",
- "used_underscore_binding",
- "useless_asref",
- "useless_attribute",
- "useless_conversion",
- "useless_format",
- "useless_let_if_seq",
- "useless_transmute",
- "useless_vec",
- "vec_box",
- "vec_init_then_push",
- "vec_resize_to_zero",
- "verbose_bit_mask",
- "verbose_file_reads",
- "vtable_address_comparisons",
- "while_immutable_condition",
- "while_let_loop",
- "while_let_on_iterator",
- "wildcard_dependencies",
- "wildcard_enum_match_arm",
- "wildcard_imports",
- "wildcard_in_or_patterns",
- "write_literal",
- "write_with_newline",
- "writeln_empty_string",
- "wrong_self_convention",
- "wrong_transmute",
- "zero_divided_by_zero",
- "zero_prefixed_literal",
- "zero_ptr",
- "zero_sized_map_values",
- "zst_offset",
-
-}
diff --git a/src/tools/clippy/src/docs/absurd_extreme_comparisons.txt b/src/tools/clippy/src/docs/absurd_extreme_comparisons.txt
deleted file mode 100644
index 590bee28a..000000000
--- a/src/tools/clippy/src/docs/absurd_extreme_comparisons.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for comparisons where one side of the relation is
-either the minimum or maximum value for its type and warns if it involves a
-case that is always true or always false. Only integer and boolean types are
-checked.
-
-### Why is this bad?
-An expression like `min <= x` may misleadingly imply
-that it is possible for `x` to be less than the minimum. Expressions like
-`max < x` are probably mistakes.
-
-### Known problems
-For `usize` the size of the current compile target will
-be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such
-a comparison to detect target pointer width will trigger this lint. One can
-use `mem::sizeof` and compare its value or conditional compilation
-attributes
-like `#[cfg(target_pointer_width = "64")] ..` instead.
-
-### Example
-```
-let vec: Vec<isize> = Vec::new();
-if vec.len() <= 0 {}
-if 100 > i32::MAX {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/alloc_instead_of_core.txt b/src/tools/clippy/src/docs/alloc_instead_of_core.txt
deleted file mode 100644
index 488a36e92..000000000
--- a/src/tools/clippy/src/docs/alloc_instead_of_core.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-
-Finds items imported through `alloc` when available through `core`.
-
-### Why is this bad?
-
-Crates which have `no_std` compatibility and may optionally require alloc may wish to ensure types are
-imported from core to ensure disabling `alloc` does not cause the crate to fail to compile. This lint
-is also useful for crates migrating to become `no_std` compatible.
-
-### Example
-```
-use alloc::slice::from_ref;
-```
-Use instead:
-```
-use core::slice::from_ref;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/allow_attributes_without_reason.txt b/src/tools/clippy/src/docs/allow_attributes_without_reason.txt
deleted file mode 100644
index fcc4f49b0..000000000
--- a/src/tools/clippy/src/docs/allow_attributes_without_reason.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for attributes that allow lints without a reason.
-
-(This requires the `lint_reasons` feature)
-
-### Why is this bad?
-Allowing a lint should always have a reason. This reason should be documented to
-ensure that others understand the reasoning
-
-### Example
-```
-#![feature(lint_reasons)]
-
-#![allow(clippy::some_lint)]
-```
-
-Use instead:
-```
-#![feature(lint_reasons)]
-
-#![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/almost_complete_letter_range.txt b/src/tools/clippy/src/docs/almost_complete_letter_range.txt
deleted file mode 100644
index 01cbaf9ea..000000000
--- a/src/tools/clippy/src/docs/almost_complete_letter_range.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for ranges which almost include the entire range of letters from 'a' to 'z', but
-don't because they're a half open range.
-
-### Why is this bad?
-This (`'a'..'z'`) is almost certainly a typo meant to include all letters.
-
-### Example
-```
-let _ = 'a'..'z';
-```
-Use instead:
-```
-let _ = 'a'..='z';
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/almost_swapped.txt b/src/tools/clippy/src/docs/almost_swapped.txt
deleted file mode 100644
index cd10a8d54..000000000
--- a/src/tools/clippy/src/docs/almost_swapped.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for `foo = bar; bar = foo` sequences.
-
-### Why is this bad?
-This looks like a failed attempt to swap.
-
-### Example
-```
-a = b;
-b = a;
-```
-If swapping is intended, use `swap()` instead:
-```
-std::mem::swap(&mut a, &mut b);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/approx_constant.txt b/src/tools/clippy/src/docs/approx_constant.txt
deleted file mode 100644
index 393fa4b5e..000000000
--- a/src/tools/clippy/src/docs/approx_constant.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for floating point literals that approximate
-constants which are defined in
-[`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)
-or
-[`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),
-respectively, suggesting to use the predefined constant.
-
-### Why is this bad?
-Usually, the definition in the standard library is more
-precise than what people come up with. If you find that your definition is
-actually more precise, please [file a Rust
-issue](https://github.com/rust-lang/rust/issues).
-
-### Example
-```
-let x = 3.14;
-let y = 1_f64 / x;
-```
-Use instead:
-```
-let x = std::f32::consts::PI;
-let y = std::f64::consts::FRAC_1_PI;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/arithmetic_side_effects.txt b/src/tools/clippy/src/docs/arithmetic_side_effects.txt
deleted file mode 100644
index 4ae8bce88..000000000
--- a/src/tools/clippy/src/docs/arithmetic_side_effects.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-### What it does
-Checks any kind of arithmetic operation of any type.
-
-Operators like `+`, `-`, `*` or `<<` are usually capable of overflowing according to the [Rust
-Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),
-or can panic (`/`, `%`).
-
-Known safe built-in types like `Wrapping` or `Saturating`, floats, operations in constant
-environments, allowed types and non-constant operations that won't overflow are ignored.
-
-### Why is this bad?
-For integers, overflow will trigger a panic in debug builds or wrap the result in
-release mode; division by zero will cause a panic in either mode. As a result, it is
-desirable to explicitly call checked, wrapping or saturating arithmetic methods.
-
-#### Example
-```
-// `n` can be any number, including `i32::MAX`.
-fn foo(n: i32) -> i32 {
- n + 1
-}
-```
-
-Third-party types can also overflow or present unwanted side-effects.
-
-#### Example
-```
-use rust_decimal::Decimal;
-let _n = Decimal::MAX + Decimal::MAX;
-```
-
-### Allowed types
-Custom allowed types can be specified through the "arithmetic-side-effects-allowed" filter. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/as_conversions.txt b/src/tools/clippy/src/docs/as_conversions.txt
deleted file mode 100644
index 4af479bd8..000000000
--- a/src/tools/clippy/src/docs/as_conversions.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks for usage of `as` conversions.
-
-Note that this lint is specialized in linting *every single* use of `as`
-regardless of whether good alternatives exist or not.
-If you want more precise lints for `as`, please consider using these separate lints:
-`unnecessary_cast`, `cast_lossless/cast_possible_truncation/cast_possible_wrap/cast_precision_loss/cast_sign_loss`,
-`fn_to_numeric_cast(_with_truncation)`, `char_lit_as_u8`, `ref_to_mut` and `ptr_as_ptr`.
-There is a good explanation the reason why this lint should work in this way and how it is useful
-[in this issue](https://github.com/rust-lang/rust-clippy/issues/5122).
-
-### Why is this bad?
-`as` conversions will perform many kinds of
-conversions, including silently lossy conversions and dangerous coercions.
-There are cases when it makes sense to use `as`, so the lint is
-Allow by default.
-
-### Example
-```
-let a: u32;
-...
-f(a as u16);
-```
-
-Use instead:
-```
-f(a.try_into()?);
-
-// or
-
-f(a.try_into().expect("Unexpected u16 overflow in f"));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/as_ptr_cast_mut.txt b/src/tools/clippy/src/docs/as_ptr_cast_mut.txt
deleted file mode 100644
index 228dde996..000000000
--- a/src/tools/clippy/src/docs/as_ptr_cast_mut.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer
-
-### Why is this bad?
-Since `as_ptr` takes a `&self`, the pointer won't have write permissions unless interior
-mutability is used, making it unlikely that having it as a mutable pointer is correct.
-
-### Example
-```
-let string = String::with_capacity(1);
-let ptr = string.as_ptr() as *mut u8;
-unsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR
-```
-Use instead:
-```
-let mut string = String::with_capacity(1);
-let ptr = string.as_mut_ptr();
-unsafe { ptr.write(4) };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/as_underscore.txt b/src/tools/clippy/src/docs/as_underscore.txt
deleted file mode 100644
index 2d9b0c358..000000000
--- a/src/tools/clippy/src/docs/as_underscore.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Check for the usage of `as _` conversion using inferred type.
-
-### Why is this bad?
-The conversion might include lossy conversion and dangerous cast that might go
-undetected due to the type being inferred.
-
-The lint is allowed by default as using `_` is less wordy than always specifying the type.
-
-### Example
-```
-fn foo(n: usize) {}
-let n: u16 = 256;
-foo(n as _);
-```
-Use instead:
-```
-fn foo(n: usize) {}
-let n: u16 = 256;
-foo(n as usize);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/assertions_on_constants.txt b/src/tools/clippy/src/docs/assertions_on_constants.txt
deleted file mode 100644
index 270c1e3b6..000000000
--- a/src/tools/clippy/src/docs/assertions_on_constants.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for `assert!(true)` and `assert!(false)` calls.
-
-### Why is this bad?
-Will be optimized out by the compiler or should probably be replaced by a
-`panic!()` or `unreachable!()`
-
-### Example
-```
-assert!(false)
-assert!(true)
-const B: bool = false;
-assert!(B)
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/assertions_on_result_states.txt b/src/tools/clippy/src/docs/assertions_on_result_states.txt
deleted file mode 100644
index 0889084fd..000000000
--- a/src/tools/clippy/src/docs/assertions_on_result_states.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for `assert!(r.is_ok())` or `assert!(r.is_err())` calls.
-
-### Why is this bad?
-An assertion failure cannot output an useful message of the error.
-
-### Known problems
-The suggested replacement decreases the readability of code and log output.
-
-### Example
-```
-assert!(r.is_ok());
-assert!(r.is_err());
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/assign_op_pattern.txt b/src/tools/clippy/src/docs/assign_op_pattern.txt
deleted file mode 100644
index f355c0cc1..000000000
--- a/src/tools/clippy/src/docs/assign_op_pattern.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for `a = a op b` or `a = b commutative_op a`
-patterns.
-
-### Why is this bad?
-These can be written as the shorter `a op= b`.
-
-### Known problems
-While forbidden by the spec, `OpAssign` traits may have
-implementations that differ from the regular `Op` impl.
-
-### Example
-```
-let mut a = 5;
-let b = 0;
-// ...
-
-a = a + b;
-```
-
-Use instead:
-```
-let mut a = 5;
-let b = 0;
-// ...
-
-a += b;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/async_yields_async.txt b/src/tools/clippy/src/docs/async_yields_async.txt
deleted file mode 100644
index a40de6d2e..000000000
--- a/src/tools/clippy/src/docs/async_yields_async.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for async blocks that yield values of types
-that can themselves be awaited.
-
-### Why is this bad?
-An await is likely missing.
-
-### Example
-```
-async fn foo() {}
-
-fn bar() {
- let x = async {
- foo()
- };
-}
-```
-
-Use instead:
-```
-async fn foo() {}
-
-fn bar() {
- let x = async {
- foo().await
- };
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/await_holding_invalid_type.txt b/src/tools/clippy/src/docs/await_holding_invalid_type.txt
deleted file mode 100644
index e9c768772..000000000
--- a/src/tools/clippy/src/docs/await_holding_invalid_type.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Allows users to configure types which should not be held across `await`
-suspension points.
-
-### Why is this bad?
-There are some types which are perfectly "safe" to be used concurrently
-from a memory access perspective but will cause bugs at runtime if they
-are held in such a way.
-
-### Example
-
-```
-await-holding-invalid-types = [
- # You can specify a type name
- "CustomLockType",
- # You can (optionally) specify a reason
- { path = "OtherCustomLockType", reason = "Relies on a thread local" }
-]
-```
-
-```
-struct CustomLockType;
-struct OtherCustomLockType;
-async fn foo() {
- let _x = CustomLockType;
- let _y = OtherCustomLockType;
- baz().await; // Lint violation
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/await_holding_lock.txt b/src/tools/clippy/src/docs/await_holding_lock.txt
deleted file mode 100644
index 0f450a111..000000000
--- a/src/tools/clippy/src/docs/await_holding_lock.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-### What it does
-Checks for calls to await while holding a non-async-aware MutexGuard.
-
-### Why is this bad?
-The Mutex types found in std::sync and parking_lot
-are not designed to operate in an async context across await points.
-
-There are two potential solutions. One is to use an async-aware Mutex
-type. Many asynchronous foundation crates provide such a Mutex type. The
-other solution is to ensure the mutex is unlocked before calling await,
-either by introducing a scope or an explicit call to Drop::drop.
-
-### Known problems
-Will report false positive for explicitly dropped guards
-([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)). A workaround for this is
-to wrap the `.lock()` call in a block instead of explicitly dropping the guard.
-
-### Example
-```
-async fn foo(x: &Mutex<u32>) {
- let mut guard = x.lock().unwrap();
- *guard += 1;
- baz().await;
-}
-
-async fn bar(x: &Mutex<u32>) {
- let mut guard = x.lock().unwrap();
- *guard += 1;
- drop(guard); // explicit drop
- baz().await;
-}
-```
-
-Use instead:
-```
-async fn foo(x: &Mutex<u32>) {
- {
- let mut guard = x.lock().unwrap();
- *guard += 1;
- }
- baz().await;
-}
-
-async fn bar(x: &Mutex<u32>) {
- {
- let mut guard = x.lock().unwrap();
- *guard += 1;
- } // guard dropped here at end of scope
- baz().await;
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/await_holding_refcell_ref.txt b/src/tools/clippy/src/docs/await_holding_refcell_ref.txt
deleted file mode 100644
index 226a261b9..000000000
--- a/src/tools/clippy/src/docs/await_holding_refcell_ref.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-### What it does
-Checks for calls to await while holding a `RefCell` `Ref` or `RefMut`.
-
-### Why is this bad?
-`RefCell` refs only check for exclusive mutable access
-at runtime. Holding onto a `RefCell` ref across an `await` suspension point
-risks panics from a mutable ref shared while other refs are outstanding.
-
-### Known problems
-Will report false positive for explicitly dropped refs
-([#6353](https://github.com/rust-lang/rust-clippy/issues/6353)). A workaround for this is
-to wrap the `.borrow[_mut]()` call in a block instead of explicitly dropping the ref.
-
-### Example
-```
-async fn foo(x: &RefCell<u32>) {
- let mut y = x.borrow_mut();
- *y += 1;
- baz().await;
-}
-
-async fn bar(x: &RefCell<u32>) {
- let mut y = x.borrow_mut();
- *y += 1;
- drop(y); // explicit drop
- baz().await;
-}
-```
-
-Use instead:
-```
-async fn foo(x: &RefCell<u32>) {
- {
- let mut y = x.borrow_mut();
- *y += 1;
- }
- baz().await;
-}
-
-async fn bar(x: &RefCell<u32>) {
- {
- let mut y = x.borrow_mut();
- *y += 1;
- } // y dropped here at end of scope
- baz().await;
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bad_bit_mask.txt b/src/tools/clippy/src/docs/bad_bit_mask.txt
deleted file mode 100644
index d40024ee5..000000000
--- a/src/tools/clippy/src/docs/bad_bit_mask.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-### What it does
-Checks for incompatible bit masks in comparisons.
-
-The formula for detecting if an expression of the type `_ <bit_op> m
-<cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of
-{`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following
-table:
-
-|Comparison |Bit Op|Example |is always|Formula |
-|------------|------|-------------|---------|----------------------|
-|`==` or `!=`| `&` |`x & 2 == 3` |`false` |`c & m != c` |
-|`<` or `>=`| `&` |`x & 2 < 3` |`true` |`m < c` |
-|`>` or `<=`| `&` |`x & 1 > 1` |`false` |`m <= c` |
-|`==` or `!=`| `\|` |`x \| 1 == 0`|`false` |`c \| m != c` |
-|`<` or `>=`| `\|` |`x \| 1 < 1` |`false` |`m >= c` |
-|`<=` or `>` | `\|` |`x \| 1 > 0` |`true` |`m > c` |
-
-### Why is this bad?
-If the bits that the comparison cares about are always
-set to zero or one by the bit mask, the comparison is constant `true` or
-`false` (depending on mask, compared value, and operators).
-
-So the code is actively misleading, and the only reason someone would write
-this intentionally is to win an underhanded Rust contest or create a
-test-case for this lint.
-
-### Example
-```
-if (x & 1 == 2) { }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bind_instead_of_map.txt b/src/tools/clippy/src/docs/bind_instead_of_map.txt
deleted file mode 100644
index 148575803..000000000
--- a/src/tools/clippy/src/docs/bind_instead_of_map.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or
-`_.or_else(|x| Err(y))`.
-
-### Why is this bad?
-Readability, this can be written more concisely as
-`_.map(|x| y)` or `_.map_err(|x| y)`.
-
-### Example
-```
-let _ = opt().and_then(|s| Some(s.len()));
-let _ = res().and_then(|s| if s.len() == 42 { Ok(10) } else { Ok(20) });
-let _ = res().or_else(|s| if s.len() == 42 { Err(10) } else { Err(20) });
-```
-
-The correct use would be:
-
-```
-let _ = opt().map(|s| s.len());
-let _ = res().map(|s| if s.len() == 42 { 10 } else { 20 });
-let _ = res().map_err(|s| if s.len() == 42 { 10 } else { 20 });
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/blanket_clippy_restriction_lints.txt b/src/tools/clippy/src/docs/blanket_clippy_restriction_lints.txt
deleted file mode 100644
index 28a4ebf71..000000000
--- a/src/tools/clippy/src/docs/blanket_clippy_restriction_lints.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
-
-### Why is this bad?
-Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.
-These lints should only be enabled on a lint-by-lint basis and with careful consideration.
-
-### Example
-```
-#![deny(clippy::restriction)]
-```
-
-Use instead:
-```
-#![deny(clippy::as_conversions)]
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/blocks_in_if_conditions.txt b/src/tools/clippy/src/docs/blocks_in_if_conditions.txt
deleted file mode 100644
index 3afa14853..000000000
--- a/src/tools/clippy/src/docs/blocks_in_if_conditions.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for `if` conditions that use blocks containing an
-expression, statements or conditions that use closures with blocks.
-
-### Why is this bad?
-Style, using blocks in the condition makes it hard to read.
-
-### Examples
-```
-if { true } { /* ... */ }
-
-if { let x = somefunc(); x } { /* ... */ }
-```
-
-Use instead:
-```
-if true { /* ... */ }
-
-let res = { let x = somefunc(); x };
-if res { /* ... */ }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bool_assert_comparison.txt b/src/tools/clippy/src/docs/bool_assert_comparison.txt
deleted file mode 100644
index df7ca00cc..000000000
--- a/src/tools/clippy/src/docs/bool_assert_comparison.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-This lint warns about boolean comparisons in assert-like macros.
-
-### Why is this bad?
-It is shorter to use the equivalent.
-
-### Example
-```
-assert_eq!("a".is_empty(), false);
-assert_ne!("a".is_empty(), true);
-```
-
-Use instead:
-```
-assert!(!"a".is_empty());
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bool_comparison.txt b/src/tools/clippy/src/docs/bool_comparison.txt
deleted file mode 100644
index 0996f60ce..000000000
--- a/src/tools/clippy/src/docs/bool_comparison.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for expressions of the form `x == true`,
-`x != true` and order comparisons such as `x < true` (or vice versa) and
-suggest using the variable directly.
-
-### Why is this bad?
-Unnecessary code.
-
-### Example
-```
-if x == true {}
-if y == false {}
-```
-use `x` directly:
-```
-if x {}
-if !y {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bool_to_int_with_if.txt b/src/tools/clippy/src/docs/bool_to_int_with_if.txt
deleted file mode 100644
index 63535b454..000000000
--- a/src/tools/clippy/src/docs/bool_to_int_with_if.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Instead of using an if statement to convert a bool to an int,
-this lint suggests using a `from()` function or an `as` coercion.
-
-### Why is this bad?
-Coercion or `from()` is idiomatic way to convert bool to a number.
-Both methods are guaranteed to return 1 for true, and 0 for false.
-
-See https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E
-
-### Example
-```
-if condition {
- 1_i64
-} else {
- 0
-};
-```
-Use instead:
-```
-i64::from(condition);
-```
-or
-```
-condition as i64;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/borrow_as_ptr.txt b/src/tools/clippy/src/docs/borrow_as_ptr.txt
deleted file mode 100644
index 0be865abd..000000000
--- a/src/tools/clippy/src/docs/borrow_as_ptr.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for the usage of `&expr as *const T` or
-`&mut expr as *mut T`, and suggest using `ptr::addr_of` or
-`ptr::addr_of_mut` instead.
-
-### Why is this bad?
-This would improve readability and avoid creating a reference
-that points to an uninitialized value or unaligned place.
-Read the `ptr::addr_of` docs for more information.
-
-### Example
-```
-let val = 1;
-let p = &val as *const i32;
-
-let mut val_mut = 1;
-let p_mut = &mut val_mut as *mut i32;
-```
-Use instead:
-```
-let val = 1;
-let p = std::ptr::addr_of!(val);
-
-let mut val_mut = 1;
-let p_mut = std::ptr::addr_of_mut!(val_mut);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/borrow_deref_ref.txt b/src/tools/clippy/src/docs/borrow_deref_ref.txt
deleted file mode 100644
index 352480d3f..000000000
--- a/src/tools/clippy/src/docs/borrow_deref_ref.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for `&*(&T)`.
-
-### Why is this bad?
-Dereferencing and then borrowing a reference value has no effect in most cases.
-
-### Known problems
-False negative on such code:
-```
-let x = &12;
-let addr_x = &x as *const _ as usize;
-let addr_y = &&*x as *const _ as usize; // assert ok now, and lint triggered.
- // But if we fix it, assert will fail.
-assert_ne!(addr_x, addr_y);
-```
-
-### Example
-```
-let s = &String::new();
-
-let a: &String = &* s;
-```
-
-Use instead:
-```
-let a: &String = s;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/borrow_interior_mutable_const.txt b/src/tools/clippy/src/docs/borrow_interior_mutable_const.txt
deleted file mode 100644
index e55b6a77e..000000000
--- a/src/tools/clippy/src/docs/borrow_interior_mutable_const.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-### What it does
-Checks if `const` items which is interior mutable (e.g.,
-contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly.
-
-### Why is this bad?
-Consts are copied everywhere they are referenced, i.e.,
-every time you refer to the const a fresh instance of the `Cell` or `Mutex`
-or `AtomicXxxx` will be created, which defeats the whole purpose of using
-these types in the first place.
-
-The `const` value should be stored inside a `static` item.
-
-### Known problems
-When an enum has variants with interior mutability, use of its non
-interior mutable variants can generate false positives. See issue
-[#3962](https://github.com/rust-lang/rust-clippy/issues/3962)
-
-Types that have underlying or potential interior mutability trigger the lint whether
-the interior mutable field is used or not. See issues
-[#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
-[#3825](https://github.com/rust-lang/rust-clippy/issues/3825)
-
-### Example
-```
-use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
-const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
-
-CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
-assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
-```
-
-Use instead:
-```
-use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
-const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
-
-static STATIC_ATOM: AtomicUsize = CONST_ATOM;
-STATIC_ATOM.store(9, SeqCst);
-assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/borrowed_box.txt b/src/tools/clippy/src/docs/borrowed_box.txt
deleted file mode 100644
index d7089be66..000000000
--- a/src/tools/clippy/src/docs/borrowed_box.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for use of `&Box<T>` anywhere in the code.
-Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
-
-### Why is this bad?
-A `&Box<T>` parameter requires the function caller to box `T` first before passing it to a function.
-Using `&T` defines a concrete type for the parameter and generalizes the function, this would also
-auto-deref to `&T` at the function call site if passed a `&Box<T>`.
-
-### Example
-```
-fn foo(bar: &Box<T>) { ... }
-```
-
-Better:
-
-```
-fn foo(bar: &T) { ... }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/box_collection.txt b/src/tools/clippy/src/docs/box_collection.txt
deleted file mode 100644
index 053f24c46..000000000
--- a/src/tools/clippy/src/docs/box_collection.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for use of `Box<T>` where T is a collection such as Vec anywhere in the code.
-Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
-
-### Why is this bad?
-Collections already keeps their contents in a separate area on
-the heap. So if you `Box` them, you just add another level of indirection
-without any benefit whatsoever.
-
-### Example
-```
-struct X {
- values: Box<Vec<Foo>>,
-}
-```
-
-Better:
-
-```
-struct X {
- values: Vec<Foo>,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/box_default.txt b/src/tools/clippy/src/docs/box_default.txt
deleted file mode 100644
index 1c670c773..000000000
--- a/src/tools/clippy/src/docs/box_default.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-checks for `Box::new(T::default())`, which is better written as
-`Box::<T>::default()`.
-
-### Why is this bad?
-First, it's more complex, involving two calls instead of one.
-Second, `Box::default()` can be faster
-[in certain cases](https://nnethercote.github.io/perf-book/standard-library-types.html#box).
-
-### Example
-```
-let x: Box<String> = Box::new(Default::default());
-```
-Use instead:
-```
-let x: Box<String> = Box::default();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/boxed_local.txt b/src/tools/clippy/src/docs/boxed_local.txt
deleted file mode 100644
index 8b1febf14..000000000
--- a/src/tools/clippy/src/docs/boxed_local.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for usage of `Box<T>` where an unboxed `T` would
-work fine.
-
-### Why is this bad?
-This is an unnecessary allocation, and bad for
-performance. It is only necessary to allocate if you wish to move the box
-into something.
-
-### Example
-```
-fn foo(x: Box<u32>) {}
-```
-
-Use instead:
-```
-fn foo(x: u32) {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/branches_sharing_code.txt b/src/tools/clippy/src/docs/branches_sharing_code.txt
deleted file mode 100644
index 79be61247..000000000
--- a/src/tools/clippy/src/docs/branches_sharing_code.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks if the `if` and `else` block contain shared code that can be
-moved out of the blocks.
-
-### Why is this bad?
-Duplicate code is less maintainable.
-
-### Known problems
-* The lint doesn't check if the moved expressions modify values that are being used in
- the if condition. The suggestion can in that case modify the behavior of the program.
- See [rust-clippy#7452](https://github.com/rust-lang/rust-clippy/issues/7452)
-
-### Example
-```
-let foo = if … {
- println!("Hello World");
- 13
-} else {
- println!("Hello World");
- 42
-};
-```
-
-Use instead:
-```
-println!("Hello World");
-let foo = if … {
- 13
-} else {
- 42
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/builtin_type_shadow.txt b/src/tools/clippy/src/docs/builtin_type_shadow.txt
deleted file mode 100644
index 15b1c9df7..000000000
--- a/src/tools/clippy/src/docs/builtin_type_shadow.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Warns if a generic shadows a built-in type.
-
-### Why is this bad?
-This gives surprising type errors.
-
-### Example
-
-```
-impl<u32> Foo<u32> {
- fn impl_func(&self) -> u32 {
- 42
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bytes_count_to_len.txt b/src/tools/clippy/src/docs/bytes_count_to_len.txt
deleted file mode 100644
index ca7bf9a38..000000000
--- a/src/tools/clippy/src/docs/bytes_count_to_len.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-It checks for `str::bytes().count()` and suggests replacing it with
-`str::len()`.
-
-### Why is this bad?
-`str::bytes().count()` is longer and may not be as performant as using
-`str::len()`.
-
-### Example
-```
-"hello".bytes().count();
-String::from("hello").bytes().count();
-```
-Use instead:
-```
-"hello".len();
-String::from("hello").len();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/bytes_nth.txt b/src/tools/clippy/src/docs/bytes_nth.txt
deleted file mode 100644
index 260de3433..000000000
--- a/src/tools/clippy/src/docs/bytes_nth.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for the use of `.bytes().nth()`.
-
-### Why is this bad?
-`.as_bytes().get()` is more efficient and more
-readable.
-
-### Example
-```
-"Hello".bytes().nth(3);
-```
-
-Use instead:
-```
-"Hello".as_bytes().get(3);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cargo_common_metadata.txt b/src/tools/clippy/src/docs/cargo_common_metadata.txt
deleted file mode 100644
index 1998647a9..000000000
--- a/src/tools/clippy/src/docs/cargo_common_metadata.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-### What it does
-Checks to see if all common metadata is defined in
-`Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata
-
-### Why is this bad?
-It will be more difficult for users to discover the
-purpose of the crate, and key information related to it.
-
-### Example
-```
-[package]
-name = "clippy"
-version = "0.0.212"
-repository = "https://github.com/rust-lang/rust-clippy"
-readme = "README.md"
-license = "MIT OR Apache-2.0"
-keywords = ["clippy", "lint", "plugin"]
-categories = ["development-tools", "development-tools::cargo-plugins"]
-```
-
-Should include a description field like:
-
-```
-[package]
-name = "clippy"
-version = "0.0.212"
-description = "A bunch of helpful lints to avoid common pitfalls in Rust"
-repository = "https://github.com/rust-lang/rust-clippy"
-readme = "README.md"
-license = "MIT OR Apache-2.0"
-keywords = ["clippy", "lint", "plugin"]
-categories = ["development-tools", "development-tools::cargo-plugins"]
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/case_sensitive_file_extension_comparisons.txt b/src/tools/clippy/src/docs/case_sensitive_file_extension_comparisons.txt
deleted file mode 100644
index 8e6e18ed4..000000000
--- a/src/tools/clippy/src/docs/case_sensitive_file_extension_comparisons.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for calls to `ends_with` with possible file extensions
-and suggests to use a case-insensitive approach instead.
-
-### Why is this bad?
-`ends_with` is case-sensitive and may not detect files with a valid extension.
-
-### Example
-```
-fn is_rust_file(filename: &str) -> bool {
- filename.ends_with(".rs")
-}
-```
-Use instead:
-```
-fn is_rust_file(filename: &str) -> bool {
- let filename = std::path::Path::new(filename);
- filename.extension()
- .map_or(false, |ext| ext.eq_ignore_ascii_case("rs"))
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_abs_to_unsigned.txt b/src/tools/clippy/src/docs/cast_abs_to_unsigned.txt
deleted file mode 100644
index c5d8ee034..000000000
--- a/src/tools/clippy/src/docs/cast_abs_to_unsigned.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for uses of the `abs()` method that cast the result to unsigned.
-
-### Why is this bad?
-The `unsigned_abs()` method avoids panic when called on the MIN value.
-
-### Example
-```
-let x: i32 = -42;
-let y: u32 = x.abs() as u32;
-```
-Use instead:
-```
-let x: i32 = -42;
-let y: u32 = x.unsigned_abs();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_enum_constructor.txt b/src/tools/clippy/src/docs/cast_enum_constructor.txt
deleted file mode 100644
index 675c03a42..000000000
--- a/src/tools/clippy/src/docs/cast_enum_constructor.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-### What it does
-Checks for casts from an enum tuple constructor to an integer.
-
-### Why is this bad?
-The cast is easily confused with casting a c-like enum value to an integer.
-
-### Example
-```
-enum E { X(i32) };
-let _ = E::X as usize;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_enum_truncation.txt b/src/tools/clippy/src/docs/cast_enum_truncation.txt
deleted file mode 100644
index abe32a829..000000000
--- a/src/tools/clippy/src/docs/cast_enum_truncation.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for casts from an enum type to an integral type which will definitely truncate the
-value.
-
-### Why is this bad?
-The resulting integral value will not match the value of the variant it came from.
-
-### Example
-```
-enum E { X = 256 };
-let _ = E::X as u8;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_lossless.txt b/src/tools/clippy/src/docs/cast_lossless.txt
deleted file mode 100644
index c3a61dd47..000000000
--- a/src/tools/clippy/src/docs/cast_lossless.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for casts between numerical types that may
-be replaced by safe conversion functions.
-
-### Why is this bad?
-Rust's `as` keyword will perform many kinds of
-conversions, including silently lossy conversions. Conversion functions such
-as `i32::from` will only perform lossless conversions. Using the conversion
-functions prevents conversions from turning into silent lossy conversions if
-the types of the input expressions ever change, and make it easier for
-people reading the code to know that the conversion is lossless.
-
-### Example
-```
-fn as_u64(x: u8) -> u64 {
- x as u64
-}
-```
-
-Using `::from` would look like this:
-
-```
-fn as_u64(x: u8) -> u64 {
- u64::from(x)
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_nan_to_int.txt b/src/tools/clippy/src/docs/cast_nan_to_int.txt
deleted file mode 100644
index 122f5da0c..000000000
--- a/src/tools/clippy/src/docs/cast_nan_to_int.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for a known NaN float being cast to an integer
-
-### Why is this bad?
-NaNs are cast into zero, so one could simply use this and make the
-code more readable. The lint could also hint at a programmer error.
-
-### Example
-```
-let _: (0.0_f32 / 0.0) as u64;
-```
-Use instead:
-```
-let _: = 0_u64;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_possible_truncation.txt b/src/tools/clippy/src/docs/cast_possible_truncation.txt
deleted file mode 100644
index 0b164848c..000000000
--- a/src/tools/clippy/src/docs/cast_possible_truncation.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for casts between numerical types that may
-truncate large values. This is expected behavior, so the cast is `Allow` by
-default.
-
-### Why is this bad?
-In some problem domains, it is good practice to avoid
-truncation. This lint can be activated to help assess where additional
-checks could be beneficial.
-
-### Example
-```
-fn as_u8(x: u64) -> u8 {
- x as u8
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_possible_wrap.txt b/src/tools/clippy/src/docs/cast_possible_wrap.txt
deleted file mode 100644
index f883fc9cf..000000000
--- a/src/tools/clippy/src/docs/cast_possible_wrap.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for casts from an unsigned type to a signed type of
-the same size. Performing such a cast is a 'no-op' for the compiler,
-i.e., nothing is changed at the bit level, and the binary representation of
-the value is reinterpreted. This can cause wrapping if the value is too big
-for the target signed type. However, the cast works as defined, so this lint
-is `Allow` by default.
-
-### Why is this bad?
-While such a cast is not bad in itself, the results can
-be surprising when this is not the intended behavior, as demonstrated by the
-example below.
-
-### Example
-```
-u32::MAX as i32; // will yield a value of `-1`
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_precision_loss.txt b/src/tools/clippy/src/docs/cast_precision_loss.txt
deleted file mode 100644
index f915d9f8a..000000000
--- a/src/tools/clippy/src/docs/cast_precision_loss.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for casts from any numerical to a float type where
-the receiving type cannot store all values from the original type without
-rounding errors. This possible rounding is to be expected, so this lint is
-`Allow` by default.
-
-Basically, this warns on casting any integer with 32 or more bits to `f32`
-or any 64-bit integer to `f64`.
-
-### Why is this bad?
-It's not bad at all. But in some applications it can be
-helpful to know where precision loss can take place. This lint can help find
-those places in the code.
-
-### Example
-```
-let x = u64::MAX;
-x as f64;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_ptr_alignment.txt b/src/tools/clippy/src/docs/cast_ptr_alignment.txt
deleted file mode 100644
index 6a6d4dcaa..000000000
--- a/src/tools/clippy/src/docs/cast_ptr_alignment.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for casts, using `as` or `pointer::cast`,
-from a less-strictly-aligned pointer to a more-strictly-aligned pointer
-
-### Why is this bad?
-Dereferencing the resulting pointer may be undefined
-behavior.
-
-### Known problems
-Using `std::ptr::read_unaligned` and `std::ptr::write_unaligned` or similar
-on the resulting pointer is fine. Is over-zealous: Casts with manual alignment checks or casts like
-u64-> u8 -> u16 can be fine. Miri is able to do a more in-depth analysis.
-
-### Example
-```
-let _ = (&1u8 as *const u8) as *const u16;
-let _ = (&mut 1u8 as *mut u8) as *mut u16;
-
-(&1u8 as *const u8).cast::<u16>();
-(&mut 1u8 as *mut u8).cast::<u16>();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_ref_to_mut.txt b/src/tools/clippy/src/docs/cast_ref_to_mut.txt
deleted file mode 100644
index fb5b4dbb6..000000000
--- a/src/tools/clippy/src/docs/cast_ref_to_mut.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for casts of `&T` to `&mut T` anywhere in the code.
-
-### Why is this bad?
-It’s basically guaranteed to be undefined behavior.
-`UnsafeCell` is the only way to obtain aliasable data that is considered
-mutable.
-
-### Example
-```
-fn x(r: &i32) {
- unsafe {
- *(r as *const _ as *mut _) += 1;
- }
-}
-```
-
-Instead consider using interior mutability types.
-
-```
-use std::cell::UnsafeCell;
-
-fn x(r: &UnsafeCell<i32>) {
- unsafe {
- *r.get() += 1;
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_sign_loss.txt b/src/tools/clippy/src/docs/cast_sign_loss.txt
deleted file mode 100644
index d64fe1b07..000000000
--- a/src/tools/clippy/src/docs/cast_sign_loss.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for casts from a signed to an unsigned numerical
-type. In this case, negative values wrap around to large positive values,
-which can be quite surprising in practice. However, as the cast works as
-defined, this lint is `Allow` by default.
-
-### Why is this bad?
-Possibly surprising results. You can activate this lint
-as a one-time check to see where numerical wrapping can arise.
-
-### Example
-```
-let y: i8 = -1;
-y as u128; // will return 18446744073709551615
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_slice_different_sizes.txt b/src/tools/clippy/src/docs/cast_slice_different_sizes.txt
deleted file mode 100644
index c01ef0ba9..000000000
--- a/src/tools/clippy/src/docs/cast_slice_different_sizes.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-### What it does
-Checks for `as` casts between raw pointers to slices with differently sized elements.
-
-### Why is this bad?
-The produced raw pointer to a slice does not update its length metadata. The produced
-pointer will point to a different number of bytes than the original pointer because the
-length metadata of a raw slice pointer is in elements rather than bytes.
-Producing a slice reference from the raw pointer will either create a slice with
-less data (which can be surprising) or create a slice with more data and cause Undefined Behavior.
-
-### Example
-// Missing data
-```
-let a = [1_i32, 2, 3, 4];
-let p = &a as *const [i32] as *const [u8];
-unsafe {
- println!("{:?}", &*p);
-}
-```
-// Undefined Behavior (note: also potential alignment issues)
-```
-let a = [1_u8, 2, 3, 4];
-let p = &a as *const [u8] as *const [u32];
-unsafe {
- println!("{:?}", &*p);
-}
-```
-Instead use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length
-```
-let a = [1_i32, 2, 3, 4];
-let old_ptr = &a as *const [i32];
-// The data pointer is cast to a pointer to the target `u8` not `[u8]`
-// The length comes from the known length of 4 i32s times the 4 bytes per i32
-let new_ptr = core::ptr::slice_from_raw_parts(old_ptr as *const u8, 16);
-unsafe {
- println!("{:?}", &*new_ptr);
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cast_slice_from_raw_parts.txt b/src/tools/clippy/src/docs/cast_slice_from_raw_parts.txt
deleted file mode 100644
index b58c73976..000000000
--- a/src/tools/clippy/src/docs/cast_slice_from_raw_parts.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for a raw slice being cast to a slice pointer
-
-### Why is this bad?
-This can result in multiple `&mut` references to the same location when only a pointer is
-required.
-`ptr::slice_from_raw_parts` is a safe alternative that doesn't require
-the same [safety requirements] to be upheld.
-
-### Example
-```
-let _: *const [u8] = std::slice::from_raw_parts(ptr, len) as *const _;
-let _: *mut [u8] = std::slice::from_raw_parts_mut(ptr, len) as *mut _;
-```
-Use instead:
-```
-let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, len);
-let _: *mut [u8] = std::ptr::slice_from_raw_parts_mut(ptr, len);
-```
-[safety requirements]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/char_lit_as_u8.txt b/src/tools/clippy/src/docs/char_lit_as_u8.txt
deleted file mode 100644
index 00d60b9a4..000000000
--- a/src/tools/clippy/src/docs/char_lit_as_u8.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for expressions where a character literal is cast
-to `u8` and suggests using a byte literal instead.
-
-### Why is this bad?
-In general, casting values to smaller types is
-error-prone and should be avoided where possible. In the particular case of
-converting a character literal to u8, it is easy to avoid by just using a
-byte literal instead. As an added bonus, `b'a'` is even slightly shorter
-than `'a' as u8`.
-
-### Example
-```
-'x' as u8
-```
-
-A better version, using the byte literal:
-
-```
-b'x'
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/chars_last_cmp.txt b/src/tools/clippy/src/docs/chars_last_cmp.txt
deleted file mode 100644
index 4c1d88389..000000000
--- a/src/tools/clippy/src/docs/chars_last_cmp.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for usage of `_.chars().last()` or
-`_.chars().next_back()` on a `str` to check if it ends with a given char.
-
-### Why is this bad?
-Readability, this can be written more concisely as
-`_.ends_with(_)`.
-
-### Example
-```
-name.chars().last() == Some('_') || name.chars().next_back() == Some('-');
-```
-
-Use instead:
-```
-name.ends_with('_') || name.ends_with('-');
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/chars_next_cmp.txt b/src/tools/clippy/src/docs/chars_next_cmp.txt
deleted file mode 100644
index 77cbce2de..000000000
--- a/src/tools/clippy/src/docs/chars_next_cmp.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for usage of `.chars().next()` on a `str` to check
-if it starts with a given char.
-
-### Why is this bad?
-Readability, this can be written more concisely as
-`_.starts_with(_)`.
-
-### Example
-```
-let name = "foo";
-if name.chars().next() == Some('_') {};
-```
-
-Use instead:
-```
-let name = "foo";
-if name.starts_with('_') {};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/checked_conversions.txt b/src/tools/clippy/src/docs/checked_conversions.txt
deleted file mode 100644
index 536b01294..000000000
--- a/src/tools/clippy/src/docs/checked_conversions.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for explicit bounds checking when casting.
-
-### Why is this bad?
-Reduces the readability of statements & is error prone.
-
-### Example
-```
-foo <= i32::MAX as u32;
-```
-
-Use instead:
-```
-i32::try_from(foo).is_ok();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/clone_double_ref.txt b/src/tools/clippy/src/docs/clone_double_ref.txt
deleted file mode 100644
index 2729635bd..000000000
--- a/src/tools/clippy/src/docs/clone_double_ref.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usage of `.clone()` on an `&&T`.
-
-### Why is this bad?
-Cloning an `&&T` copies the inner `&T`, instead of
-cloning the underlying `T`.
-
-### Example
-```
-fn main() {
- let x = vec![1];
- let y = &&x;
- let z = y.clone();
- println!("{:p} {:p}", *y, z); // prints out the same pointer
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/clone_on_copy.txt b/src/tools/clippy/src/docs/clone_on_copy.txt
deleted file mode 100644
index 99a0bdb4c..000000000
--- a/src/tools/clippy/src/docs/clone_on_copy.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-### What it does
-Checks for usage of `.clone()` on a `Copy` type.
-
-### Why is this bad?
-The only reason `Copy` types implement `Clone` is for
-generics, not for using the `clone` method on a concrete type.
-
-### Example
-```
-42u64.clone();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/clone_on_ref_ptr.txt b/src/tools/clippy/src/docs/clone_on_ref_ptr.txt
deleted file mode 100644
index 2d83f8fef..000000000
--- a/src/tools/clippy/src/docs/clone_on_ref_ptr.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for usage of `.clone()` on a ref-counted pointer,
-(`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified
-function syntax instead (e.g., `Rc::clone(foo)`).
-
-### Why is this bad?
-Calling '.clone()' on an Rc, Arc, or Weak
-can obscure the fact that only the pointer is being cloned, not the underlying
-data.
-
-### Example
-```
-let x = Rc::new(1);
-
-x.clone();
-```
-
-Use instead:
-```
-Rc::clone(&x);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cloned_instead_of_copied.txt b/src/tools/clippy/src/docs/cloned_instead_of_copied.txt
deleted file mode 100644
index 2f2014d5f..000000000
--- a/src/tools/clippy/src/docs/cloned_instead_of_copied.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usages of `cloned()` on an `Iterator` or `Option` where
-`copied()` could be used instead.
-
-### Why is this bad?
-`copied()` is better because it guarantees that the type being cloned
-implements `Copy`.
-
-### Example
-```
-[1, 2, 3].iter().cloned();
-```
-Use instead:
-```
-[1, 2, 3].iter().copied();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cmp_nan.txt b/src/tools/clippy/src/docs/cmp_nan.txt
deleted file mode 100644
index e2ad04d93..000000000
--- a/src/tools/clippy/src/docs/cmp_nan.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for comparisons to NaN.
-
-### Why is this bad?
-NaN does not compare meaningfully to anything – not
-even itself – so those comparisons are simply wrong.
-
-### Example
-```
-if x == f32::NAN { }
-```
-
-Use instead:
-```
-if x.is_nan() { }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cmp_null.txt b/src/tools/clippy/src/docs/cmp_null.txt
deleted file mode 100644
index 02fd15124..000000000
--- a/src/tools/clippy/src/docs/cmp_null.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-This lint checks for equality comparisons with `ptr::null`
-
-### Why is this bad?
-It's easier and more readable to use the inherent
-`.is_null()`
-method instead
-
-### Example
-```
-use std::ptr;
-
-if x == ptr::null {
- // ..
-}
-```
-
-Use instead:
-```
-if x.is_null() {
- // ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cmp_owned.txt b/src/tools/clippy/src/docs/cmp_owned.txt
deleted file mode 100644
index f8d4956ff..000000000
--- a/src/tools/clippy/src/docs/cmp_owned.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for conversions to owned values just for the sake
-of a comparison.
-
-### Why is this bad?
-The comparison can operate on a reference, so creating
-an owned value effectively throws it away directly afterwards, which is
-needlessly consuming code and heap space.
-
-### Example
-```
-if x.to_owned() == y {}
-```
-
-Use instead:
-```
-if x == y {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/cognitive_complexity.txt b/src/tools/clippy/src/docs/cognitive_complexity.txt
deleted file mode 100644
index fdd75f647..000000000
--- a/src/tools/clippy/src/docs/cognitive_complexity.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for methods with high cognitive complexity.
-
-### Why is this bad?
-Methods of high cognitive complexity tend to be hard to
-both read and maintain. Also LLVM will tend to optimize small methods better.
-
-### Known problems
-Sometimes it's hard to find a way to reduce the
-complexity.
-
-### Example
-You'll see it when you get the warning. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/collapsible_else_if.txt b/src/tools/clippy/src/docs/collapsible_else_if.txt
deleted file mode 100644
index 4ddfca177..000000000
--- a/src/tools/clippy/src/docs/collapsible_else_if.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for collapsible `else { if ... }` expressions
-that can be collapsed to `else if ...`.
-
-### Why is this bad?
-Each `if`-statement adds one level of nesting, which
-makes code look more complex than it really is.
-
-### Example
-```
-
-if x {
- …
-} else {
- if y {
- …
- }
-}
-```
-
-Should be written:
-
-```
-if x {
- …
-} else if y {
- …
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/collapsible_if.txt b/src/tools/clippy/src/docs/collapsible_if.txt
deleted file mode 100644
index e1264ee06..000000000
--- a/src/tools/clippy/src/docs/collapsible_if.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for nested `if` statements which can be collapsed
-by `&&`-combining their conditions.
-
-### Why is this bad?
-Each `if`-statement adds one level of nesting, which
-makes code look more complex than it really is.
-
-### Example
-```
-if x {
- if y {
- // …
- }
-}
-```
-
-Use instead:
-```
-if x && y {
- // …
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/collapsible_match.txt b/src/tools/clippy/src/docs/collapsible_match.txt
deleted file mode 100644
index 0d59594a0..000000000
--- a/src/tools/clippy/src/docs/collapsible_match.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-### What it does
-Finds nested `match` or `if let` expressions where the patterns may be "collapsed" together
-without adding any branches.
-
-Note that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only
-cases where merging would most likely make the code more readable.
-
-### Why is this bad?
-It is unnecessarily verbose and complex.
-
-### Example
-```
-fn func(opt: Option<Result<u64, String>>) {
- let n = match opt {
- Some(n) => match n {
- Ok(n) => n,
- _ => return,
- }
- None => return,
- };
-}
-```
-Use instead:
-```
-fn func(opt: Option<Result<u64, String>>) {
- let n = match opt {
- Some(Ok(n)) => n,
- _ => return,
- };
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/collapsible_str_replace.txt b/src/tools/clippy/src/docs/collapsible_str_replace.txt
deleted file mode 100644
index c24c25a30..000000000
--- a/src/tools/clippy/src/docs/collapsible_str_replace.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for consecutive calls to `str::replace` (2 or more)
-that can be collapsed into a single call.
-
-### Why is this bad?
-Consecutive `str::replace` calls scan the string multiple times
-with repetitive code.
-
-### Example
-```
-let hello = "hesuo worpd"
- .replace('s', "l")
- .replace("u", "l")
- .replace('p', "l");
-```
-Use instead:
-```
-let hello = "hesuo worpd".replace(&['s', 'u', 'p'], "l");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/comparison_chain.txt b/src/tools/clippy/src/docs/comparison_chain.txt
deleted file mode 100644
index 43b09f31f..000000000
--- a/src/tools/clippy/src/docs/comparison_chain.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-### What it does
-Checks comparison chains written with `if` that can be
-rewritten with `match` and `cmp`.
-
-### Why is this bad?
-`if` is not guaranteed to be exhaustive and conditionals can get
-repetitive
-
-### Known problems
-The match statement may be slower due to the compiler
-not inlining the call to cmp. See issue [#5354](https://github.com/rust-lang/rust-clippy/issues/5354)
-
-### Example
-```
-fn f(x: u8, y: u8) {
- if x > y {
- a()
- } else if x < y {
- b()
- } else {
- c()
- }
-}
-```
-
-Use instead:
-```
-use std::cmp::Ordering;
-fn f(x: u8, y: u8) {
- match x.cmp(&y) {
- Ordering::Greater => a(),
- Ordering::Less => b(),
- Ordering::Equal => c()
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/comparison_to_empty.txt b/src/tools/clippy/src/docs/comparison_to_empty.txt
deleted file mode 100644
index db6f74fe2..000000000
--- a/src/tools/clippy/src/docs/comparison_to_empty.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-### What it does
-Checks for comparing to an empty slice such as `""` or `[]`,
-and suggests using `.is_empty()` where applicable.
-
-### Why is this bad?
-Some structures can answer `.is_empty()` much faster
-than checking for equality. So it is good to get into the habit of using
-`.is_empty()`, and having it is cheap.
-Besides, it makes the intent clearer than a manual comparison in some contexts.
-
-### Example
-
-```
-if s == "" {
- ..
-}
-
-if arr == [] {
- ..
-}
-```
-Use instead:
-```
-if s.is_empty() {
- ..
-}
-
-if arr.is_empty() {
- ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/copy_iterator.txt b/src/tools/clippy/src/docs/copy_iterator.txt
deleted file mode 100644
index 5f9a2a015..000000000
--- a/src/tools/clippy/src/docs/copy_iterator.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for types that implement `Copy` as well as
-`Iterator`.
-
-### Why is this bad?
-Implicit copies can be confusing when working with
-iterator combinators.
-
-### Example
-```
-#[derive(Copy, Clone)]
-struct Countdown(u8);
-
-impl Iterator for Countdown {
- // ...
-}
-
-let a: Vec<_> = my_iterator.take(1).collect();
-let b: Vec<_> = my_iterator.collect();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/crate_in_macro_def.txt b/src/tools/clippy/src/docs/crate_in_macro_def.txt
deleted file mode 100644
index 047e986de..000000000
--- a/src/tools/clippy/src/docs/crate_in_macro_def.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-### What it does
-Checks for use of `crate` as opposed to `$crate` in a macro definition.
-
-### Why is this bad?
-`crate` refers to the macro call's crate, whereas `$crate` refers to the macro definition's
-crate. Rarely is the former intended. See:
-https://doc.rust-lang.org/reference/macros-by-example.html#hygiene
-
-### Example
-```
-#[macro_export]
-macro_rules! print_message {
- () => {
- println!("{}", crate::MESSAGE);
- };
-}
-pub const MESSAGE: &str = "Hello!";
-```
-Use instead:
-```
-#[macro_export]
-macro_rules! print_message {
- () => {
- println!("{}", $crate::MESSAGE);
- };
-}
-pub const MESSAGE: &str = "Hello!";
-```
-
-Note that if the use of `crate` is intentional, an `allow` attribute can be applied to the
-macro definition, e.g.:
-```
-#[allow(clippy::crate_in_macro_def)]
-macro_rules! ok { ... crate::foo ... }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/create_dir.txt b/src/tools/clippy/src/docs/create_dir.txt
deleted file mode 100644
index e4e793768..000000000
--- a/src/tools/clippy/src/docs/create_dir.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
-
-### Why is this bad?
-Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`.
-
-### Example
-```
-std::fs::create_dir("foo");
-```
-
-Use instead:
-```
-std::fs::create_dir_all("foo");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/crosspointer_transmute.txt b/src/tools/clippy/src/docs/crosspointer_transmute.txt
deleted file mode 100644
index 49dea1549..000000000
--- a/src/tools/clippy/src/docs/crosspointer_transmute.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for transmutes between a type `T` and `*T`.
-
-### Why is this bad?
-It's easy to mistakenly transmute between a type and a
-pointer to that type.
-
-### Example
-```
-core::intrinsics::transmute(t) // where the result type is the same as
- // `*t` or `&t`'s
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/dbg_macro.txt b/src/tools/clippy/src/docs/dbg_macro.txt
deleted file mode 100644
index 3e1a9a043..000000000
--- a/src/tools/clippy/src/docs/dbg_macro.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usage of dbg!() macro.
-
-### Why is this bad?
-`dbg!` macro is intended as a debugging tool. It
-should not be in version control.
-
-### Example
-```
-dbg!(true)
-```
-
-Use instead:
-```
-true
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/debug_assert_with_mut_call.txt b/src/tools/clippy/src/docs/debug_assert_with_mut_call.txt
deleted file mode 100644
index 2c44abe1f..000000000
--- a/src/tools/clippy/src/docs/debug_assert_with_mut_call.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for function/method calls with a mutable
-parameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros.
-
-### Why is this bad?
-In release builds `debug_assert!` macros are optimized out by the
-compiler.
-Therefore mutating something in a `debug_assert!` macro results in different behavior
-between a release and debug build.
-
-### Example
-```
-debug_assert_eq!(vec![3].pop(), Some(3));
-
-// or
-
-debug_assert!(takes_a_mut_parameter(&mut x));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/decimal_literal_representation.txt b/src/tools/clippy/src/docs/decimal_literal_representation.txt
deleted file mode 100644
index daca9bbb3..000000000
--- a/src/tools/clippy/src/docs/decimal_literal_representation.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Warns if there is a better representation for a numeric literal.
-
-### Why is this bad?
-Especially for big powers of 2 a hexadecimal representation is more
-readable than a decimal representation.
-
-### Example
-```
-`255` => `0xFF`
-`65_535` => `0xFFFF`
-`4_042_322_160` => `0xF0F0_F0F0`
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/declare_interior_mutable_const.txt b/src/tools/clippy/src/docs/declare_interior_mutable_const.txt
deleted file mode 100644
index 2801b5ccf..000000000
--- a/src/tools/clippy/src/docs/declare_interior_mutable_const.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-### What it does
-Checks for declaration of `const` items which is interior
-mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.).
-
-### Why is this bad?
-Consts are copied everywhere they are referenced, i.e.,
-every time you refer to the const a fresh instance of the `Cell` or `Mutex`
-or `AtomicXxxx` will be created, which defeats the whole purpose of using
-these types in the first place.
-
-The `const` should better be replaced by a `static` item if a global
-variable is wanted, or replaced by a `const fn` if a constructor is wanted.
-
-### Known problems
-A "non-constant" const item is a legacy way to supply an
-initialized value to downstream `static` items (e.g., the
-`std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,
-and this lint should be suppressed.
-
-Even though the lint avoids triggering on a constant whose type has enums that have variants
-with interior mutability, and its value uses non interior mutable variants (see
-[#3962](https://github.com/rust-lang/rust-clippy/issues/3962) and
-[#3825](https://github.com/rust-lang/rust-clippy/issues/3825) for examples);
-it complains about associated constants without default values only based on its types;
-which might not be preferable.
-There're other enums plus associated constants cases that the lint cannot handle.
-
-Types that have underlying or potential interior mutability trigger the lint whether
-the interior mutable field is used or not. See issues
-[#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
-
-### Example
-```
-use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
-
-const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
-CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
-assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
-```
-
-Use instead:
-```
-static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15);
-STATIC_ATOM.store(9, SeqCst);
-assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/default_instead_of_iter_empty.txt b/src/tools/clippy/src/docs/default_instead_of_iter_empty.txt
deleted file mode 100644
index b63ef3d18..000000000
--- a/src/tools/clippy/src/docs/default_instead_of_iter_empty.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-It checks for `std::iter::Empty::default()` and suggests replacing it with
-`std::iter::empty()`.
-### Why is this bad?
-`std::iter::empty()` is the more idiomatic way.
-### Example
-```
-let _ = std::iter::Empty::<usize>::default();
-let iter: std::iter::Empty<usize> = std::iter::Empty::default();
-```
-Use instead:
-```
-let _ = std::iter::empty::<usize>();
-let iter: std::iter::Empty<usize> = std::iter::empty();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/default_numeric_fallback.txt b/src/tools/clippy/src/docs/default_numeric_fallback.txt
deleted file mode 100644
index 15076a0a6..000000000
--- a/src/tools/clippy/src/docs/default_numeric_fallback.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type
-inference.
-
-Default numeric fallback means that if numeric types have not yet been bound to concrete
-types at the end of type inference, then integer type is bound to `i32`, and similarly
-floating type is bound to `f64`.
-
-See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback.
-
-### Why is this bad?
-For those who are very careful about types, default numeric fallback
-can be a pitfall that cause unexpected runtime behavior.
-
-### Known problems
-This lint can only be allowed at the function level or above.
-
-### Example
-```
-let i = 10;
-let f = 1.23;
-```
-
-Use instead:
-```
-let i = 10i32;
-let f = 1.23f64;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/default_trait_access.txt b/src/tools/clippy/src/docs/default_trait_access.txt
deleted file mode 100644
index e69298969..000000000
--- a/src/tools/clippy/src/docs/default_trait_access.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for literal calls to `Default::default()`.
-
-### Why is this bad?
-It's easier for the reader if the name of the type is used, rather than the
-generic `Default`.
-
-### Example
-```
-let s: String = Default::default();
-```
-
-Use instead:
-```
-let s = String::default();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/default_union_representation.txt b/src/tools/clippy/src/docs/default_union_representation.txt
deleted file mode 100644
index f79ff9760..000000000
--- a/src/tools/clippy/src/docs/default_union_representation.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-### What it does
-Displays a warning when a union is declared with the default representation (without a `#[repr(C)]` attribute).
-
-### Why is this bad?
-Unions in Rust have unspecified layout by default, despite many people thinking that they
-lay out each field at the start of the union (like C does). That is, there are no guarantees
-about the offset of the fields for unions with multiple non-ZST fields without an explicitly
-specified layout. These cases may lead to undefined behavior in unsafe blocks.
-
-### Example
-```
-union Foo {
- a: i32,
- b: u32,
-}
-
-fn main() {
- let _x: u32 = unsafe {
- Foo { a: 0_i32 }.b // Undefined behavior: `b` is allowed to be padding
- };
-}
-```
-Use instead:
-```
-#[repr(C)]
-union Foo {
- a: i32,
- b: u32,
-}
-
-fn main() {
- let _x: u32 = unsafe {
- Foo { a: 0_i32 }.b // Now defined behavior, this is just an i32 -> u32 transmute
- };
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/deprecated_cfg_attr.txt b/src/tools/clippy/src/docs/deprecated_cfg_attr.txt
deleted file mode 100644
index 9f264887a..000000000
--- a/src/tools/clippy/src/docs/deprecated_cfg_attr.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
-with `#[rustfmt::skip]`.
-
-### Why is this bad?
-Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
-are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
-
-### Known problems
-This lint doesn't detect crate level inner attributes, because they get
-processed before the PreExpansionPass lints get executed. See
-[#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
-
-### Example
-```
-#[cfg_attr(rustfmt, rustfmt_skip)]
-fn main() { }
-```
-
-Use instead:
-```
-#[rustfmt::skip]
-fn main() { }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/deprecated_semver.txt b/src/tools/clippy/src/docs/deprecated_semver.txt
deleted file mode 100644
index c9574a99b..000000000
--- a/src/tools/clippy/src/docs/deprecated_semver.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for `#[deprecated]` annotations with a `since`
-field that is not a valid semantic version.
-
-### Why is this bad?
-For checking the version of the deprecation, it must be
-a valid semver. Failing that, the contained information is useless.
-
-### Example
-```
-#[deprecated(since = "forever")]
-fn something_else() { /* ... */ }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/deref_addrof.txt b/src/tools/clippy/src/docs/deref_addrof.txt
deleted file mode 100644
index fa711b924..000000000
--- a/src/tools/clippy/src/docs/deref_addrof.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for usage of `*&` and `*&mut` in expressions.
-
-### Why is this bad?
-Immediately dereferencing a reference is no-op and
-makes the code less clear.
-
-### Known problems
-Multiple dereference/addrof pairs are not handled so
-the suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect.
-
-### Example
-```
-let a = f(*&mut b);
-let c = *&d;
-```
-
-Use instead:
-```
-let a = f(b);
-let c = d;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/deref_by_slicing.txt b/src/tools/clippy/src/docs/deref_by_slicing.txt
deleted file mode 100644
index 4dad24ac0..000000000
--- a/src/tools/clippy/src/docs/deref_by_slicing.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for slicing expressions which are equivalent to dereferencing the
-value.
-
-### Why is this bad?
-Some people may prefer to dereference rather than slice.
-
-### Example
-```
-let vec = vec![1, 2, 3];
-let slice = &vec[..];
-```
-Use instead:
-```
-let vec = vec![1, 2, 3];
-let slice = &*vec;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/derivable_impls.txt b/src/tools/clippy/src/docs/derivable_impls.txt
deleted file mode 100644
index 5cee43956..000000000
--- a/src/tools/clippy/src/docs/derivable_impls.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-### What it does
-Detects manual `std::default::Default` implementations that are identical to a derived implementation.
-
-### Why is this bad?
-It is less concise.
-
-### Example
-```
-struct Foo {
- bar: bool
-}
-
-impl Default for Foo {
- fn default() -> Self {
- Self {
- bar: false
- }
- }
-}
-```
-
-Use instead:
-```
-#[derive(Default)]
-struct Foo {
- bar: bool
-}
-```
-
-### Known problems
-Derive macros [sometimes use incorrect bounds](https://github.com/rust-lang/rust/issues/26925)
-in generic types and the user defined `impl` may be more generalized or
-specialized than what derive will produce. This lint can't detect the manual `impl`
-has exactly equal bounds, and therefore this lint is disabled for types with
-generic parameters. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/derive_hash_xor_eq.txt b/src/tools/clippy/src/docs/derive_hash_xor_eq.txt
deleted file mode 100644
index fbf623d5a..000000000
--- a/src/tools/clippy/src/docs/derive_hash_xor_eq.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for deriving `Hash` but implementing `PartialEq`
-explicitly or vice versa.
-
-### Why is this bad?
-The implementation of these traits must agree (for
-example for use with `HashMap`) so it’s probably a bad idea to use a
-default-generated `Hash` implementation with an explicitly defined
-`PartialEq`. In particular, the following must hold for any type:
-
-```
-k1 == k2 ⇒ hash(k1) == hash(k2)
-```
-
-### Example
-```
-#[derive(Hash)]
-struct Foo;
-
-impl PartialEq for Foo {
- ...
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/derive_ord_xor_partial_ord.txt b/src/tools/clippy/src/docs/derive_ord_xor_partial_ord.txt
deleted file mode 100644
index f2107a5f6..000000000
--- a/src/tools/clippy/src/docs/derive_ord_xor_partial_ord.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-### What it does
-Checks for deriving `Ord` but implementing `PartialOrd`
-explicitly or vice versa.
-
-### Why is this bad?
-The implementation of these traits must agree (for
-example for use with `sort`) so it’s probably a bad idea to use a
-default-generated `Ord` implementation with an explicitly defined
-`PartialOrd`. In particular, the following must hold for any type
-implementing `Ord`:
-
-```
-k1.cmp(&k2) == k1.partial_cmp(&k2).unwrap()
-```
-
-### Example
-```
-#[derive(Ord, PartialEq, Eq)]
-struct Foo;
-
-impl PartialOrd for Foo {
- ...
-}
-```
-Use instead:
-```
-#[derive(PartialEq, Eq)]
-struct Foo;
-
-impl PartialOrd for Foo {
- fn partial_cmp(&self, other: &Foo) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl Ord for Foo {
- ...
-}
-```
-or, if you don't need a custom ordering:
-```
-#[derive(Ord, PartialOrd, PartialEq, Eq)]
-struct Foo;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/derive_partial_eq_without_eq.txt b/src/tools/clippy/src/docs/derive_partial_eq_without_eq.txt
deleted file mode 100644
index 932fabad6..000000000
--- a/src/tools/clippy/src/docs/derive_partial_eq_without_eq.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for types that derive `PartialEq` and could implement `Eq`.
-
-### Why is this bad?
-If a type `T` derives `PartialEq` and all of its members implement `Eq`,
-then `T` can always implement `Eq`. Implementing `Eq` allows `T` to be used
-in APIs that require `Eq` types. It also allows structs containing `T` to derive
-`Eq` themselves.
-
-### Example
-```
-#[derive(PartialEq)]
-struct Foo {
- i_am_eq: i32,
- i_am_eq_too: Vec<String>,
-}
-```
-Use instead:
-```
-#[derive(PartialEq, Eq)]
-struct Foo {
- i_am_eq: i32,
- i_am_eq_too: Vec<String>,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/disallowed_macros.txt b/src/tools/clippy/src/docs/disallowed_macros.txt
deleted file mode 100644
index 96fa15afa..000000000
--- a/src/tools/clippy/src/docs/disallowed_macros.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-### What it does
-Denies the configured macros in clippy.toml
-
-Note: Even though this lint is warn-by-default, it will only trigger if
-macros are defined in the clippy.toml file.
-
-### Why is this bad?
-Some macros are undesirable in certain contexts, and it's beneficial to
-lint for them as needed.
-
-### Example
-An example clippy.toml configuration:
-```
-disallowed-macros = [
- # Can use a string as the path of the disallowed macro.
- "std::print",
- # Can also use an inline table with a `path` key.
- { path = "std::println" },
- # When using an inline table, can add a `reason` for why the macro
- # is disallowed.
- { path = "serde::Serialize", reason = "no serializing" },
-]
-```
-```
-use serde::Serialize;
-
-// Example code where clippy issues a warning
-println!("warns");
-
-// The diagnostic will contain the message "no serializing"
-#[derive(Serialize)]
-struct Data {
- name: String,
- value: usize,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/disallowed_methods.txt b/src/tools/clippy/src/docs/disallowed_methods.txt
deleted file mode 100644
index d8ad5b6a6..000000000
--- a/src/tools/clippy/src/docs/disallowed_methods.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-### What it does
-Denies the configured methods and functions in clippy.toml
-
-Note: Even though this lint is warn-by-default, it will only trigger if
-methods are defined in the clippy.toml file.
-
-### Why is this bad?
-Some methods are undesirable in certain contexts, and it's beneficial to
-lint for them as needed.
-
-### Example
-An example clippy.toml configuration:
-```
-disallowed-methods = [
- # Can use a string as the path of the disallowed method.
- "std::boxed::Box::new",
- # Can also use an inline table with a `path` key.
- { path = "std::time::Instant::now" },
- # When using an inline table, can add a `reason` for why the method
- # is disallowed.
- { path = "std::vec::Vec::leak", reason = "no leaking memory" },
-]
-```
-
-```
-// Example code where clippy issues a warning
-let xs = vec![1, 2, 3, 4];
-xs.leak(); // Vec::leak is disallowed in the config.
-// The diagnostic contains the message "no leaking memory".
-
-let _now = Instant::now(); // Instant::now is disallowed in the config.
-
-let _box = Box::new(3); // Box::new is disallowed in the config.
-```
-
-Use instead:
-```
-// Example code which does not raise clippy warning
-let mut xs = Vec::new(); // Vec::new is _not_ disallowed in the config.
-xs.push(123); // Vec::push is _not_ disallowed in the config.
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/disallowed_names.txt b/src/tools/clippy/src/docs/disallowed_names.txt
deleted file mode 100644
index f4aaee9c7..000000000
--- a/src/tools/clippy/src/docs/disallowed_names.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for usage of disallowed names for variables, such
-as `foo`.
-
-### Why is this bad?
-These names are usually placeholder names and should be
-avoided.
-
-### Example
-```
-let foo = 3.14;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/disallowed_script_idents.txt b/src/tools/clippy/src/docs/disallowed_script_idents.txt
deleted file mode 100644
index 2151b7a20..000000000
--- a/src/tools/clippy/src/docs/disallowed_script_idents.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks for usage of unicode scripts other than those explicitly allowed
-by the lint config.
-
-This lint doesn't take into account non-text scripts such as `Unknown` and `Linear_A`.
-It also ignores the `Common` script type.
-While configuring, be sure to use official script name [aliases] from
-[the list of supported scripts][supported_scripts].
-
-See also: [`non_ascii_idents`].
-
-[aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases
-[supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html
-
-### Why is this bad?
-It may be not desired to have many different scripts for
-identifiers in the codebase.
-
-Note that if you only want to allow plain English, you might want to use
-built-in [`non_ascii_idents`] lint instead.
-
-[`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents
-
-### Example
-```
-// Assuming that `clippy.toml` contains the following line:
-// allowed-locales = ["Latin", "Cyrillic"]
-let counter = 10; // OK, latin is allowed.
-let Ñчётчик = 10; // OK, cyrillic is allowed.
-let zähler = 10; // OK, it's still latin.
-let カウンタ = 10; // Will spawn the lint.
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/disallowed_types.txt b/src/tools/clippy/src/docs/disallowed_types.txt
deleted file mode 100644
index 2bcbcddee..000000000
--- a/src/tools/clippy/src/docs/disallowed_types.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-### What it does
-Denies the configured types in clippy.toml.
-
-Note: Even though this lint is warn-by-default, it will only trigger if
-types are defined in the clippy.toml file.
-
-### Why is this bad?
-Some types are undesirable in certain contexts.
-
-### Example:
-An example clippy.toml configuration:
-```
-disallowed-types = [
- # Can use a string as the path of the disallowed type.
- "std::collections::BTreeMap",
- # Can also use an inline table with a `path` key.
- { path = "std::net::TcpListener" },
- # When using an inline table, can add a `reason` for why the type
- # is disallowed.
- { path = "std::net::Ipv4Addr", reason = "no IPv4 allowed" },
-]
-```
-
-```
-use std::collections::BTreeMap;
-// or its use
-let x = std::collections::BTreeMap::new();
-```
-Use instead:
-```
-// A similar type that is allowed by the config
-use std::collections::HashMap;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/diverging_sub_expression.txt b/src/tools/clippy/src/docs/diverging_sub_expression.txt
deleted file mode 100644
index 194362218..000000000
--- a/src/tools/clippy/src/docs/diverging_sub_expression.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for diverging calls that are not match arms or
-statements.
-
-### Why is this bad?
-It is often confusing to read. In addition, the
-sub-expression evaluation order for Rust is not well documented.
-
-### Known problems
-Someone might want to use `some_bool || panic!()` as a
-shorthand.
-
-### Example
-```
-let a = b() || panic!() || c();
-// `c()` is dead, `panic!()` is only called if `b()` returns `false`
-let x = (a, b, c, panic!());
-// can simply be replaced by `panic!()`
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/doc_link_with_quotes.txt b/src/tools/clippy/src/docs/doc_link_with_quotes.txt
deleted file mode 100644
index 107c8ac11..000000000
--- a/src/tools/clippy/src/docs/doc_link_with_quotes.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Detects the syntax `['foo']` in documentation comments (notice quotes instead of backticks)
-outside of code blocks
-### Why is this bad?
-It is likely a typo when defining an intra-doc link
-
-### Example
-```
-/// See also: ['foo']
-fn bar() {}
-```
-Use instead:
-```
-/// See also: [`foo`]
-fn bar() {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/doc_markdown.txt b/src/tools/clippy/src/docs/doc_markdown.txt
deleted file mode 100644
index 94f54c587..000000000
--- a/src/tools/clippy/src/docs/doc_markdown.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-### What it does
-Checks for the presence of `_`, `::` or camel-case words
-outside ticks in documentation.
-
-### Why is this bad?
-*Rustdoc* supports markdown formatting, `_`, `::` and
-camel-case probably indicates some code which should be included between
-ticks. `_` can also be used for emphasis in markdown, this lint tries to
-consider that.
-
-### Known problems
-Lots of bad docs won’t be fixed, what the lint checks
-for is limited, and there are still false positives. HTML elements and their
-content are not linted.
-
-In addition, when writing documentation comments, including `[]` brackets
-inside a link text would trip the parser. Therefore, documenting link with
-`[`SmallVec<[T; INLINE_CAPACITY]>`]` and then [`SmallVec<[T; INLINE_CAPACITY]>`]: SmallVec
-would fail.
-
-### Examples
-```
-/// Do something with the foo_bar parameter. See also
-/// that::other::module::foo.
-// ^ `foo_bar` and `that::other::module::foo` should be ticked.
-fn doit(foo_bar: usize) {}
-```
-
-```
-// Link text with `[]` brackets should be written as following:
-/// Consume the array and return the inner
-/// [`SmallVec<[T; INLINE_CAPACITY]>`][SmallVec].
-/// [SmallVec]: SmallVec
-fn main() {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/double_comparisons.txt b/src/tools/clippy/src/docs/double_comparisons.txt
deleted file mode 100644
index 7dc681877..000000000
--- a/src/tools/clippy/src/docs/double_comparisons.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for double comparisons that could be simplified to a single expression.
-
-
-### Why is this bad?
-Readability.
-
-### Example
-```
-if x == y || x < y {}
-```
-
-Use instead:
-
-```
-if x <= y {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/double_must_use.txt b/src/tools/clippy/src/docs/double_must_use.txt
deleted file mode 100644
index 0017d10d4..000000000
--- a/src/tools/clippy/src/docs/double_must_use.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for a `#[must_use]` attribute without
-further information on functions and methods that return a type already
-marked as `#[must_use]`.
-
-### Why is this bad?
-The attribute isn't needed. Not using the result
-will already be reported. Alternatively, one can add some text to the
-attribute to improve the lint message.
-
-### Examples
-```
-#[must_use]
-fn double_must_use() -> Result<(), ()> {
- unimplemented!();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/double_neg.txt b/src/tools/clippy/src/docs/double_neg.txt
deleted file mode 100644
index a07f67496..000000000
--- a/src/tools/clippy/src/docs/double_neg.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Detects expressions of the form `--x`.
-
-### Why is this bad?
-It can mislead C/C++ programmers to think `x` was
-decremented.
-
-### Example
-```
-let mut x = 3;
---x;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/double_parens.txt b/src/tools/clippy/src/docs/double_parens.txt
deleted file mode 100644
index 260d7dd57..000000000
--- a/src/tools/clippy/src/docs/double_parens.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for unnecessary double parentheses.
-
-### Why is this bad?
-This makes code harder to read and might indicate a
-mistake.
-
-### Example
-```
-fn simple_double_parens() -> i32 {
- ((0))
-}
-
-foo((0));
-```
-
-Use instead:
-```
-fn simple_no_parens() -> i32 {
- 0
-}
-
-foo(0);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/drop_copy.txt b/src/tools/clippy/src/docs/drop_copy.txt
deleted file mode 100644
index f917ca8ed..000000000
--- a/src/tools/clippy/src/docs/drop_copy.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for calls to `std::mem::drop` with a value
-that derives the Copy trait
-
-### Why is this bad?
-Calling `std::mem::drop` [does nothing for types that
-implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
-value will be copied and moved into the function on invocation.
-
-### Example
-```
-let x: i32 = 42; // i32 implements Copy
-std::mem::drop(x) // A copy of x is passed to the function, leaving the
- // original unaffected
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/drop_non_drop.txt b/src/tools/clippy/src/docs/drop_non_drop.txt
deleted file mode 100644
index ee1e3a6c2..000000000
--- a/src/tools/clippy/src/docs/drop_non_drop.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for calls to `std::mem::drop` with a value that does not implement `Drop`.
-
-### Why is this bad?
-Calling `std::mem::drop` is no different than dropping such a type. A different value may
-have been intended.
-
-### Example
-```
-struct Foo;
-let x = Foo;
-std::mem::drop(x);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/drop_ref.txt b/src/tools/clippy/src/docs/drop_ref.txt
deleted file mode 100644
index c4f7adf0c..000000000
--- a/src/tools/clippy/src/docs/drop_ref.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for calls to `std::mem::drop` with a reference
-instead of an owned value.
-
-### Why is this bad?
-Calling `drop` on a reference will only drop the
-reference itself, which is a no-op. It will not call the `drop` method (from
-the `Drop` trait implementation) on the underlying referenced value, which
-is likely what was intended.
-
-### Example
-```
-let mut lock_guard = mutex.lock();
-std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex
-// still locked
-operation_that_requires_mutex_to_be_unlocked();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/duplicate_mod.txt b/src/tools/clippy/src/docs/duplicate_mod.txt
deleted file mode 100644
index 709a9aba0..000000000
--- a/src/tools/clippy/src/docs/duplicate_mod.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-### What it does
-Checks for files that are included as modules multiple times.
-
-### Why is this bad?
-Loading a file as a module more than once causes it to be compiled
-multiple times, taking longer and putting duplicate content into the
-module tree.
-
-### Example
-```
-// lib.rs
-mod a;
-mod b;
-```
-```
-// a.rs
-#[path = "./b.rs"]
-mod b;
-```
-
-Use instead:
-
-```
-// lib.rs
-mod a;
-mod b;
-```
-```
-// a.rs
-use crate::b;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/duplicate_underscore_argument.txt b/src/tools/clippy/src/docs/duplicate_underscore_argument.txt
deleted file mode 100644
index a8fcd6a9f..000000000
--- a/src/tools/clippy/src/docs/duplicate_underscore_argument.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for function arguments having the similar names
-differing by an underscore.
-
-### Why is this bad?
-It affects code readability.
-
-### Example
-```
-fn foo(a: i32, _a: i32) {}
-```
-
-Use instead:
-```
-fn bar(a: i32, _b: i32) {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/duration_subsec.txt b/src/tools/clippy/src/docs/duration_subsec.txt
deleted file mode 100644
index e7e0ca887..000000000
--- a/src/tools/clippy/src/docs/duration_subsec.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for calculation of subsecond microseconds or milliseconds
-from other `Duration` methods.
-
-### Why is this bad?
-It's more concise to call `Duration::subsec_micros()` or
-`Duration::subsec_millis()` than to calculate them.
-
-### Example
-```
-let micros = duration.subsec_nanos() / 1_000;
-let millis = duration.subsec_nanos() / 1_000_000;
-```
-
-Use instead:
-```
-let micros = duration.subsec_micros();
-let millis = duration.subsec_millis();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/else_if_without_else.txt b/src/tools/clippy/src/docs/else_if_without_else.txt
deleted file mode 100644
index 33f5d0f91..000000000
--- a/src/tools/clippy/src/docs/else_if_without_else.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for usage of if expressions with an `else if` branch,
-but without a final `else` branch.
-
-### Why is this bad?
-Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10).
-
-### Example
-```
-if x.is_positive() {
- a();
-} else if x.is_negative() {
- b();
-}
-```
-
-Use instead:
-
-```
-if x.is_positive() {
- a();
-} else if x.is_negative() {
- b();
-} else {
- // We don't care about zero.
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/empty_drop.txt b/src/tools/clippy/src/docs/empty_drop.txt
deleted file mode 100644
index d0c0c24a9..000000000
--- a/src/tools/clippy/src/docs/empty_drop.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for empty `Drop` implementations.
-
-### Why is this bad?
-Empty `Drop` implementations have no effect when dropping an instance of the type. They are
-most likely useless. However, an empty `Drop` implementation prevents a type from being
-destructured, which might be the intention behind adding the implementation as a marker.
-
-### Example
-```
-struct S;
-
-impl Drop for S {
- fn drop(&mut self) {}
-}
-```
-Use instead:
-```
-struct S;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/empty_enum.txt b/src/tools/clippy/src/docs/empty_enum.txt
deleted file mode 100644
index f7b41c41e..000000000
--- a/src/tools/clippy/src/docs/empty_enum.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for `enum`s with no variants.
-
-As of this writing, the `never_type` is still a
-nightly-only experimental API. Therefore, this lint is only triggered
-if the `never_type` is enabled.
-
-### Why is this bad?
-If you want to introduce a type which
-can't be instantiated, you should use `!` (the primitive type "never"),
-or a wrapper around it, because `!` has more extensive
-compiler support (type inference, etc...) and wrappers
-around it are the conventional way to define an uninhabited type.
-For further information visit [never type documentation](https://doc.rust-lang.org/std/primitive.never.html)
-
-
-### Example
-```
-enum Test {}
-```
-
-Use instead:
-```
-#![feature(never_type)]
-
-struct Test(!);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/empty_line_after_outer_attr.txt b/src/tools/clippy/src/docs/empty_line_after_outer_attr.txt
deleted file mode 100644
index c85242bbe..000000000
--- a/src/tools/clippy/src/docs/empty_line_after_outer_attr.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-### What it does
-Checks for empty lines after outer attributes
-
-### Why is this bad?
-Most likely the attribute was meant to be an inner attribute using a '!'.
-If it was meant to be an outer attribute, then the following item
-should not be separated by empty lines.
-
-### Known problems
-Can cause false positives.
-
-From the clippy side it's difficult to detect empty lines between an attributes and the
-following item because empty lines and comments are not part of the AST. The parsing
-currently works for basic cases but is not perfect.
-
-### Example
-```
-#[allow(dead_code)]
-
-fn not_quite_good_code() { }
-```
-
-Use instead:
-```
-// Good (as inner attribute)
-#![allow(dead_code)]
-
-fn this_is_fine() { }
-
-// or
-
-// Good (as outer attribute)
-#[allow(dead_code)]
-fn this_is_fine_too() { }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/empty_loop.txt b/src/tools/clippy/src/docs/empty_loop.txt
deleted file mode 100644
index fea49a74d..000000000
--- a/src/tools/clippy/src/docs/empty_loop.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for empty `loop` expressions.
-
-### Why is this bad?
-These busy loops burn CPU cycles without doing
-anything. It is _almost always_ a better idea to `panic!` than to have
-a busy loop.
-
-If panicking isn't possible, think of the environment and either:
- - block on something
- - sleep the thread for some microseconds
- - yield or pause the thread
-
-For `std` targets, this can be done with
-[`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)
-or [`std::thread::yield_now`](https://doc.rust-lang.org/std/thread/fn.yield_now.html).
-
-For `no_std` targets, doing this is more complicated, especially because
-`#[panic_handler]`s can't panic. To stop/pause the thread, you will
-probably need to invoke some target-specific intrinsic. Examples include:
- - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html)
- - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html)
-
-### Example
-```
-loop {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/empty_structs_with_brackets.txt b/src/tools/clippy/src/docs/empty_structs_with_brackets.txt
deleted file mode 100644
index ab5e35ae2..000000000
--- a/src/tools/clippy/src/docs/empty_structs_with_brackets.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Finds structs without fields (a so-called "empty struct") that are declared with brackets.
-
-### Why is this bad?
-Empty brackets after a struct declaration can be omitted.
-
-### Example
-```
-struct Cookie {}
-```
-Use instead:
-```
-struct Cookie;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/enum_clike_unportable_variant.txt b/src/tools/clippy/src/docs/enum_clike_unportable_variant.txt
deleted file mode 100644
index d30a973a5..000000000
--- a/src/tools/clippy/src/docs/enum_clike_unportable_variant.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for C-like enumerations that are
-`repr(isize/usize)` and have values that don't fit into an `i32`.
-
-### Why is this bad?
-This will truncate the variant value on 32 bit
-architectures, but works fine on 64 bit.
-
-### Example
-```
-#[repr(usize)]
-enum NonPortable {
- X = 0x1_0000_0000,
- Y = 0,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/enum_glob_use.txt b/src/tools/clippy/src/docs/enum_glob_use.txt
deleted file mode 100644
index 3776822c3..000000000
--- a/src/tools/clippy/src/docs/enum_glob_use.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for `use Enum::*`.
-
-### Why is this bad?
-It is usually better style to use the prefixed name of
-an enumeration variant, rather than importing variants.
-
-### Known problems
-Old-style enumerations that prefix the variants are
-still around.
-
-### Example
-```
-use std::cmp::Ordering::*;
-
-foo(Less);
-```
-
-Use instead:
-```
-use std::cmp::Ordering;
-
-foo(Ordering::Less)
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/enum_variant_names.txt b/src/tools/clippy/src/docs/enum_variant_names.txt
deleted file mode 100644
index e726925ed..000000000
--- a/src/tools/clippy/src/docs/enum_variant_names.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-### What it does
-Detects enumeration variants that are prefixed or suffixed
-by the same characters.
-
-### Why is this bad?
-Enumeration variant names should specify their variant,
-not repeat the enumeration name.
-
-### Limitations
-Characters with no casing will be considered when comparing prefixes/suffixes
-This applies to numbers and non-ascii characters without casing
-e.g. `Foo1` and `Foo2` is considered to have different prefixes
-(the prefixes are `Foo1` and `Foo2` respectively), as also `Bar螃`, `Bar蟹`
-
-### Example
-```
-enum Cake {
- BlackForestCake,
- HummingbirdCake,
- BattenbergCake,
-}
-```
-Use instead:
-```
-enum Cake {
- BlackForest,
- Hummingbird,
- Battenberg,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/eq_op.txt b/src/tools/clippy/src/docs/eq_op.txt
deleted file mode 100644
index 2d75a0ec5..000000000
--- a/src/tools/clippy/src/docs/eq_op.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for equal operands to comparison, logical and
-bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
-`||`, `&`, `|`, `^`, `-` and `/`).
-
-### Why is this bad?
-This is usually just a typo or a copy and paste error.
-
-### Known problems
-False negatives: We had some false positives regarding
-calls (notably [racer](https://github.com/phildawes/racer) had one instance
-of `x.pop() && x.pop()`), so we removed matching any function or method
-calls. We may introduce a list of known pure functions in the future.
-
-### Example
-```
-if x + 1 == x + 1 {}
-
-// or
-
-assert_eq!(a, a);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/equatable_if_let.txt b/src/tools/clippy/src/docs/equatable_if_let.txt
deleted file mode 100644
index 999704695..000000000
--- a/src/tools/clippy/src/docs/equatable_if_let.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for pattern matchings that can be expressed using equality.
-
-### Why is this bad?
-
-* It reads better and has less cognitive load because equality won't cause binding.
-* It is a [Yoda condition](https://en.wikipedia.org/wiki/Yoda_conditions). Yoda conditions are widely
-criticized for increasing the cognitive load of reading the code.
-* Equality is a simple bool expression and can be merged with `&&` and `||` and
-reuse if blocks
-
-### Example
-```
-if let Some(2) = x {
- do_thing();
-}
-```
-Use instead:
-```
-if x == Some(2) {
- do_thing();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/erasing_op.txt b/src/tools/clippy/src/docs/erasing_op.txt
deleted file mode 100644
index 3d285a6d8..000000000
--- a/src/tools/clippy/src/docs/erasing_op.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for erasing operations, e.g., `x * 0`.
-
-### Why is this bad?
-The whole expression can be replaced by zero.
-This is most likely not the intended outcome and should probably be
-corrected
-
-### Example
-```
-let x = 1;
-0 / x;
-0 * x;
-x & 0;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/err_expect.txt b/src/tools/clippy/src/docs/err_expect.txt
deleted file mode 100644
index 1dc83c5ce..000000000
--- a/src/tools/clippy/src/docs/err_expect.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for `.err().expect()` calls on the `Result` type.
-
-### Why is this bad?
-`.expect_err()` can be called directly to avoid the extra type conversion from `err()`.
-
-### Example
-```
-let x: Result<u32, &str> = Ok(10);
-x.err().expect("Testing err().expect()");
-```
-Use instead:
-```
-let x: Result<u32, &str> = Ok(10);
-x.expect_err("Testing expect_err");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/excessive_precision.txt b/src/tools/clippy/src/docs/excessive_precision.txt
deleted file mode 100644
index 517879c47..000000000
--- a/src/tools/clippy/src/docs/excessive_precision.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for float literals with a precision greater
-than that supported by the underlying type.
-
-### Why is this bad?
-Rust will truncate the literal silently.
-
-### Example
-```
-let v: f32 = 0.123_456_789_9;
-println!("{}", v); // 0.123_456_789
-```
-
-Use instead:
-```
-let v: f64 = 0.123_456_789_9;
-println!("{}", v); // 0.123_456_789_9
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/exhaustive_enums.txt b/src/tools/clippy/src/docs/exhaustive_enums.txt
deleted file mode 100644
index d1032a7a2..000000000
--- a/src/tools/clippy/src/docs/exhaustive_enums.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`
-
-### Why is this bad?
-Exhaustive enums are typically fine, but a project which does
-not wish to make a stability commitment around exported enums may wish to
-disable them by default.
-
-### Example
-```
-enum Foo {
- Bar,
- Baz
-}
-```
-Use instead:
-```
-#[non_exhaustive]
-enum Foo {
- Bar,
- Baz
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/exhaustive_structs.txt b/src/tools/clippy/src/docs/exhaustive_structs.txt
deleted file mode 100644
index fd6e4f5ca..000000000
--- a/src/tools/clippy/src/docs/exhaustive_structs.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Warns on any exported `structs`s that are not tagged `#[non_exhaustive]`
-
-### Why is this bad?
-Exhaustive structs are typically fine, but a project which does
-not wish to make a stability commitment around exported structs may wish to
-disable them by default.
-
-### Example
-```
-struct Foo {
- bar: u8,
- baz: String,
-}
-```
-Use instead:
-```
-#[non_exhaustive]
-struct Foo {
- bar: u8,
- baz: String,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/exit.txt b/src/tools/clippy/src/docs/exit.txt
deleted file mode 100644
index 1e6154d43..000000000
--- a/src/tools/clippy/src/docs/exit.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-`exit()` terminates the program and doesn't provide a
-stack trace.
-
-### Why is this bad?
-Ideally a program is terminated by finishing
-the main function.
-
-### Example
-```
-std::process::exit(0)
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/expect_fun_call.txt b/src/tools/clippy/src/docs/expect_fun_call.txt
deleted file mode 100644
index d82d9aa9b..000000000
--- a/src/tools/clippy/src/docs/expect_fun_call.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`,
-etc., and suggests to use `unwrap_or_else` instead
-
-### Why is this bad?
-The function will always be called.
-
-### Known problems
-If the function has side-effects, not calling it will
-change the semantics of the program, but you shouldn't rely on that anyway.
-
-### Example
-```
-foo.expect(&format!("Err {}: {}", err_code, err_msg));
-
-// or
-
-foo.expect(format!("Err {}: {}", err_code, err_msg).as_str());
-```
-
-Use instead:
-```
-foo.unwrap_or_else(|| panic!("Err {}: {}", err_code, err_msg));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/expect_used.txt b/src/tools/clippy/src/docs/expect_used.txt
deleted file mode 100644
index 4a6981e33..000000000
--- a/src/tools/clippy/src/docs/expect_used.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s.
-
-### Why is this bad?
-Usually it is better to handle the `None` or `Err` case.
-Still, for a lot of quick-and-dirty code, `expect` is a good choice, which is why
-this lint is `Allow` by default.
-
-`result.expect()` will let the thread panic on `Err`
-values. Normally, you want to implement more sophisticated error handling,
-and propagate errors upwards with `?` operator.
-
-### Examples
-```
-option.expect("one");
-result.expect("one");
-```
-
-Use instead:
-```
-option?;
-
-// or
-
-result?;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/expl_impl_clone_on_copy.txt b/src/tools/clippy/src/docs/expl_impl_clone_on_copy.txt
deleted file mode 100644
index 391d93b67..000000000
--- a/src/tools/clippy/src/docs/expl_impl_clone_on_copy.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for explicit `Clone` implementations for `Copy`
-types.
-
-### Why is this bad?
-To avoid surprising behavior, these traits should
-agree and the behavior of `Copy` cannot be overridden. In almost all
-situations a `Copy` type should have a `Clone` implementation that does
-nothing more than copy the object, which is what `#[derive(Copy, Clone)]`
-gets you.
-
-### Example
-```
-#[derive(Copy)]
-struct Foo;
-
-impl Clone for Foo {
- // ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_auto_deref.txt b/src/tools/clippy/src/docs/explicit_auto_deref.txt
deleted file mode 100644
index 65b256317..000000000
--- a/src/tools/clippy/src/docs/explicit_auto_deref.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for dereferencing expressions which would be covered by auto-deref.
-
-### Why is this bad?
-This unnecessarily complicates the code.
-
-### Example
-```
-let x = String::new();
-let y: &str = &*x;
-```
-Use instead:
-```
-let x = String::new();
-let y: &str = &x;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_counter_loop.txt b/src/tools/clippy/src/docs/explicit_counter_loop.txt
deleted file mode 100644
index 2661a43e1..000000000
--- a/src/tools/clippy/src/docs/explicit_counter_loop.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks `for` loops over slices with an explicit counter
-and suggests the use of `.enumerate()`.
-
-### Why is this bad?
-Using `.enumerate()` makes the intent more clear,
-declutters the code and may be faster in some instances.
-
-### Example
-```
-let mut i = 0;
-for item in &v {
- bar(i, *item);
- i += 1;
-}
-```
-
-Use instead:
-```
-for (i, item) in v.iter().enumerate() { bar(i, *item); }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_deref_methods.txt b/src/tools/clippy/src/docs/explicit_deref_methods.txt
deleted file mode 100644
index e14e981c7..000000000
--- a/src/tools/clippy/src/docs/explicit_deref_methods.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for explicit `deref()` or `deref_mut()` method calls.
-
-### Why is this bad?
-Dereferencing by `&*x` or `&mut *x` is clearer and more concise,
-when not part of a method chain.
-
-### Example
-```
-use std::ops::Deref;
-let a: &mut String = &mut String::from("foo");
-let b: &str = a.deref();
-```
-
-Use instead:
-```
-let a: &mut String = &mut String::from("foo");
-let b = &*a;
-```
-
-This lint excludes:
-```
-let _ = d.unwrap().deref();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_into_iter_loop.txt b/src/tools/clippy/src/docs/explicit_into_iter_loop.txt
deleted file mode 100644
index 3931dfd69..000000000
--- a/src/tools/clippy/src/docs/explicit_into_iter_loop.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for loops on `y.into_iter()` where `y` will do, and
-suggests the latter.
-
-### Why is this bad?
-Readability.
-
-### Example
-```
-// with `y` a `Vec` or slice:
-for x in y.into_iter() {
- // ..
-}
-```
-can be rewritten to
-```
-for x in y {
- // ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_iter_loop.txt b/src/tools/clippy/src/docs/explicit_iter_loop.txt
deleted file mode 100644
index cabe72e91..000000000
--- a/src/tools/clippy/src/docs/explicit_iter_loop.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for loops on `x.iter()` where `&x` will do, and
-suggests the latter.
-
-### Why is this bad?
-Readability.
-
-### Known problems
-False negatives. We currently only warn on some known
-types.
-
-### Example
-```
-// with `y` a `Vec` or slice:
-for x in y.iter() {
- // ..
-}
-```
-
-Use instead:
-```
-for x in &y {
- // ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/explicit_write.txt b/src/tools/clippy/src/docs/explicit_write.txt
deleted file mode 100644
index eafed5d39..000000000
--- a/src/tools/clippy/src/docs/explicit_write.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for usage of `write!()` / `writeln()!` which can be
-replaced with `(e)print!()` / `(e)println!()`
-
-### Why is this bad?
-Using `(e)println! is clearer and more concise
-
-### Example
-```
-writeln!(&mut std::io::stderr(), "foo: {:?}", bar).unwrap();
-writeln!(&mut std::io::stdout(), "foo: {:?}", bar).unwrap();
-```
-
-Use instead:
-```
-eprintln!("foo: {:?}", bar);
-println!("foo: {:?}", bar);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/extend_with_drain.txt b/src/tools/clippy/src/docs/extend_with_drain.txt
deleted file mode 100644
index 2f31dcf5f..000000000
--- a/src/tools/clippy/src/docs/extend_with_drain.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for occurrences where one vector gets extended instead of append
-
-### Why is this bad?
-Using `append` instead of `extend` is more concise and faster
-
-### Example
-```
-let mut a = vec![1, 2, 3];
-let mut b = vec![4, 5, 6];
-
-a.extend(b.drain(..));
-```
-
-Use instead:
-```
-let mut a = vec![1, 2, 3];
-let mut b = vec![4, 5, 6];
-
-a.append(&mut b);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/extra_unused_lifetimes.txt b/src/tools/clippy/src/docs/extra_unused_lifetimes.txt
deleted file mode 100644
index bc1814aa4..000000000
--- a/src/tools/clippy/src/docs/extra_unused_lifetimes.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for lifetimes in generics that are never used
-anywhere else.
-
-### Why is this bad?
-The additional lifetimes make the code look more
-complicated, while there is nothing out of the ordinary going on. Removing
-them leads to more readable code.
-
-### Example
-```
-// unnecessary lifetimes
-fn unused_lifetime<'a>(x: u8) {
- // ..
-}
-```
-
-Use instead:
-```
-fn no_lifetime(x: u8) {
- // ...
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fallible_impl_from.txt b/src/tools/clippy/src/docs/fallible_impl_from.txt
deleted file mode 100644
index 588a5bb10..000000000
--- a/src/tools/clippy/src/docs/fallible_impl_from.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`
-
-### Why is this bad?
-`TryFrom` should be used if there's a possibility of failure.
-
-### Example
-```
-struct Foo(i32);
-
-impl From<String> for Foo {
- fn from(s: String) -> Self {
- Foo(s.parse().unwrap())
- }
-}
-```
-
-Use instead:
-```
-struct Foo(i32);
-
-impl TryFrom<String> for Foo {
- type Error = ();
- fn try_from(s: String) -> Result<Self, Self::Error> {
- if let Ok(parsed) = s.parse() {
- Ok(Foo(parsed))
- } else {
- Err(())
- }
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/field_reassign_with_default.txt b/src/tools/clippy/src/docs/field_reassign_with_default.txt
deleted file mode 100644
index e58b7239f..000000000
--- a/src/tools/clippy/src/docs/field_reassign_with_default.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for immediate reassignment of fields initialized
-with Default::default().
-
-### Why is this bad?
-It's more idiomatic to use the [functional update syntax](https://doc.rust-lang.org/reference/expressions/struct-expr.html#functional-update-syntax).
-
-### Known problems
-Assignments to patterns that are of tuple type are not linted.
-
-### Example
-```
-let mut a: A = Default::default();
-a.i = 42;
-```
-
-Use instead:
-```
-let a = A {
- i: 42,
- .. Default::default()
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/filetype_is_file.txt b/src/tools/clippy/src/docs/filetype_is_file.txt
deleted file mode 100644
index ad14bd62c..000000000
--- a/src/tools/clippy/src/docs/filetype_is_file.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for `FileType::is_file()`.
-
-### Why is this bad?
-When people testing a file type with `FileType::is_file`
-they are testing whether a path is something they can get bytes from. But
-`is_file` doesn't cover special file types in unix-like systems, and doesn't cover
-symlink in windows. Using `!FileType::is_dir()` is a better way to that intention.
-
-### Example
-```
-let metadata = std::fs::metadata("foo.txt")?;
-let filetype = metadata.file_type();
-
-if filetype.is_file() {
- // read file
-}
-```
-
-should be written as:
-
-```
-let metadata = std::fs::metadata("foo.txt")?;
-let filetype = metadata.file_type();
-
-if !filetype.is_dir() {
- // read file
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/filter_map_identity.txt b/src/tools/clippy/src/docs/filter_map_identity.txt
deleted file mode 100644
index 83b666f2e..000000000
--- a/src/tools/clippy/src/docs/filter_map_identity.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for usage of `filter_map(|x| x)`.
-
-### Why is this bad?
-Readability, this can be written more concisely by using `flatten`.
-
-### Example
-```
-iter.filter_map(|x| x);
-```
-Use instead:
-```
-iter.flatten();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/filter_map_next.txt b/src/tools/clippy/src/docs/filter_map_next.txt
deleted file mode 100644
index b38620b56..000000000
--- a/src/tools/clippy/src/docs/filter_map_next.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usage of `_.filter_map(_).next()`.
-
-### Why is this bad?
-Readability, this can be written more concisely as
-`_.find_map(_)`.
-
-### Example
-```
- (0..3).filter_map(|x| if x == 2 { Some(x) } else { None }).next();
-```
-Can be written as
-
-```
- (0..3).find_map(|x| if x == 2 { Some(x) } else { None });
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/filter_next.txt b/src/tools/clippy/src/docs/filter_next.txt
deleted file mode 100644
index 898a74166..000000000
--- a/src/tools/clippy/src/docs/filter_next.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usage of `_.filter(_).next()`.
-
-### Why is this bad?
-Readability, this can be written more concisely as
-`_.find(_)`.
-
-### Example
-```
-vec.iter().filter(|x| **x == 0).next();
-```
-
-Use instead:
-```
-vec.iter().find(|x| **x == 0);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/flat_map_identity.txt b/src/tools/clippy/src/docs/flat_map_identity.txt
deleted file mode 100644
index a5ee79b49..000000000
--- a/src/tools/clippy/src/docs/flat_map_identity.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for usage of `flat_map(|x| x)`.
-
-### Why is this bad?
-Readability, this can be written more concisely by using `flatten`.
-
-### Example
-```
-iter.flat_map(|x| x);
-```
-Can be written as
-```
-iter.flatten();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/flat_map_option.txt b/src/tools/clippy/src/docs/flat_map_option.txt
deleted file mode 100644
index d50b9156d..000000000
--- a/src/tools/clippy/src/docs/flat_map_option.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usages of `Iterator::flat_map()` where `filter_map()` could be
-used instead.
-
-### Why is this bad?
-When applicable, `filter_map()` is more clear since it shows that
-`Option` is used to produce 0 or 1 items.
-
-### Example
-```
-let nums: Vec<i32> = ["1", "2", "whee!"].iter().flat_map(|x| x.parse().ok()).collect();
-```
-Use instead:
-```
-let nums: Vec<i32> = ["1", "2", "whee!"].iter().filter_map(|x| x.parse().ok()).collect();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/float_arithmetic.txt b/src/tools/clippy/src/docs/float_arithmetic.txt
deleted file mode 100644
index 1f9bce5ab..000000000
--- a/src/tools/clippy/src/docs/float_arithmetic.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-### What it does
-Checks for float arithmetic.
-
-### Why is this bad?
-For some embedded systems or kernel development, it
-can be useful to rule out floating-point numbers.
-
-### Example
-```
-a + 1.0;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/float_cmp.txt b/src/tools/clippy/src/docs/float_cmp.txt
deleted file mode 100644
index c19907c90..000000000
--- a/src/tools/clippy/src/docs/float_cmp.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for (in-)equality comparisons on floating-point
-values (apart from zero), except in functions called `*eq*` (which probably
-implement equality for a type involving floats).
-
-### Why is this bad?
-Floating point calculations are usually imprecise, so
-asking if two values are *exactly* equal is asking for trouble. For a good
-guide on what to do, see [the floating point
-guide](http://www.floating-point-gui.de/errors/comparison).
-
-### Example
-```
-let x = 1.2331f64;
-let y = 1.2332f64;
-
-if y == 1.23f64 { }
-if y != x {} // where both are floats
-```
-
-Use instead:
-```
-let error_margin = f64::EPSILON; // Use an epsilon for comparison
-// Or, if Rust <= 1.42, use `std::f64::EPSILON` constant instead.
-// let error_margin = std::f64::EPSILON;
-if (y - 1.23f64).abs() < error_margin { }
-if (y - x).abs() > error_margin { }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/float_cmp_const.txt b/src/tools/clippy/src/docs/float_cmp_const.txt
deleted file mode 100644
index 9208feaac..000000000
--- a/src/tools/clippy/src/docs/float_cmp_const.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for (in-)equality comparisons on floating-point
-value and constant, except in functions called `*eq*` (which probably
-implement equality for a type involving floats).
-
-### Why is this bad?
-Floating point calculations are usually imprecise, so
-asking if two values are *exactly* equal is asking for trouble. For a good
-guide on what to do, see [the floating point
-guide](http://www.floating-point-gui.de/errors/comparison).
-
-### Example
-```
-let x: f64 = 1.0;
-const ONE: f64 = 1.00;
-
-if x == ONE { } // where both are floats
-```
-
-Use instead:
-```
-let error_margin = f64::EPSILON; // Use an epsilon for comparison
-// Or, if Rust <= 1.42, use `std::f64::EPSILON` constant instead.
-// let error_margin = std::f64::EPSILON;
-if (x - ONE).abs() < error_margin { }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/float_equality_without_abs.txt b/src/tools/clippy/src/docs/float_equality_without_abs.txt
deleted file mode 100644
index 556b574e1..000000000
--- a/src/tools/clippy/src/docs/float_equality_without_abs.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for statements of the form `(a - b) < f32::EPSILON` or
-`(a - b) < f64::EPSILON`. Notes the missing `.abs()`.
-
-### Why is this bad?
-The code without `.abs()` is more likely to have a bug.
-
-### Known problems
-If the user can ensure that b is larger than a, the `.abs()` is
-technically unnecessary. However, it will make the code more robust and doesn't have any
-large performance implications. If the abs call was deliberately left out for performance
-reasons, it is probably better to state this explicitly in the code, which then can be done
-with an allow.
-
-### Example
-```
-pub fn is_roughly_equal(a: f32, b: f32) -> bool {
- (a - b) < f32::EPSILON
-}
-```
-Use instead:
-```
-pub fn is_roughly_equal(a: f32, b: f32) -> bool {
- (a - b).abs() < f32::EPSILON
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fn_address_comparisons.txt b/src/tools/clippy/src/docs/fn_address_comparisons.txt
deleted file mode 100644
index 7d2b7b681..000000000
--- a/src/tools/clippy/src/docs/fn_address_comparisons.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for comparisons with an address of a function item.
-
-### Why is this bad?
-Function item address is not guaranteed to be unique and could vary
-between different code generation units. Furthermore different function items could have
-the same address after being merged together.
-
-### Example
-```
-type F = fn();
-fn a() {}
-let f: F = a;
-if f == a {
- // ...
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fn_params_excessive_bools.txt b/src/tools/clippy/src/docs/fn_params_excessive_bools.txt
deleted file mode 100644
index 2eae05633..000000000
--- a/src/tools/clippy/src/docs/fn_params_excessive_bools.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-### What it does
-Checks for excessive use of
-bools in function definitions.
-
-### Why is this bad?
-Calls to such functions
-are confusing and error prone, because it's
-hard to remember argument order and you have
-no type system support to back you up. Using
-two-variant enums instead of bools often makes
-API easier to use.
-
-### Example
-```
-fn f(is_round: bool, is_hot: bool) { ... }
-```
-
-Use instead:
-```
-enum Shape {
- Round,
- Spiky,
-}
-
-enum Temperature {
- Hot,
- IceCold,
-}
-
-fn f(shape: Shape, temperature: Temperature) { ... }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fn_to_numeric_cast.txt b/src/tools/clippy/src/docs/fn_to_numeric_cast.txt
deleted file mode 100644
index 1f587f6d7..000000000
--- a/src/tools/clippy/src/docs/fn_to_numeric_cast.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for casts of function pointers to something other than usize
-
-### Why is this bad?
-Casting a function pointer to anything other than usize/isize is not portable across
-architectures, because you end up losing bits if the target type is too small or end up with a
-bunch of extra bits that waste space and add more instructions to the final binary than
-strictly necessary for the problem
-
-Casting to isize also doesn't make sense since there are no signed addresses.
-
-### Example
-```
-fn fun() -> i32 { 1 }
-let _ = fun as i64;
-```
-
-Use instead:
-```
-let _ = fun as usize;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fn_to_numeric_cast_any.txt b/src/tools/clippy/src/docs/fn_to_numeric_cast_any.txt
deleted file mode 100644
index ee3c33d23..000000000
--- a/src/tools/clippy/src/docs/fn_to_numeric_cast_any.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-### What it does
-Checks for casts of a function pointer to any integer type.
-
-### Why is this bad?
-Casting a function pointer to an integer can have surprising results and can occur
-accidentally if parentheses are omitted from a function call. If you aren't doing anything
-low-level with function pointers then you can opt-out of casting functions to integers in
-order to avoid mistakes. Alternatively, you can use this lint to audit all uses of function
-pointer casts in your code.
-
-### Example
-```
-// fn1 is cast as `usize`
-fn fn1() -> u16 {
- 1
-};
-let _ = fn1 as usize;
-```
-
-Use instead:
-```
-// maybe you intended to call the function?
-fn fn2() -> u16 {
- 1
-};
-let _ = fn2() as usize;
-
-// or
-
-// maybe you intended to cast it to a function type?
-fn fn3() -> u16 {
- 1
-}
-let _ = fn3 as fn() -> u16;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/fn_to_numeric_cast_with_truncation.txt b/src/tools/clippy/src/docs/fn_to_numeric_cast_with_truncation.txt
deleted file mode 100644
index 69f12fa31..000000000
--- a/src/tools/clippy/src/docs/fn_to_numeric_cast_with_truncation.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for casts of a function pointer to a numeric type not wide enough to
-store address.
-
-### Why is this bad?
-Such a cast discards some bits of the function's address. If this is intended, it would be more
-clearly expressed by casting to usize first, then casting the usize to the intended type (with
-a comment) to perform the truncation.
-
-### Example
-```
-fn fn1() -> i16 {
- 1
-};
-let _ = fn1 as i32;
-```
-
-Use instead:
-```
-// Cast to usize first, then comment with the reason for the truncation
-fn fn1() -> i16 {
- 1
-};
-let fn_ptr = fn1 as usize;
-let fn_ptr_truncated = fn_ptr as i32;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/for_kv_map.txt b/src/tools/clippy/src/docs/for_kv_map.txt
deleted file mode 100644
index a9a2ffee9..000000000
--- a/src/tools/clippy/src/docs/for_kv_map.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for iterating a map (`HashMap` or `BTreeMap`) and
-ignoring either the keys or values.
-
-### Why is this bad?
-Readability. There are `keys` and `values` methods that
-can be used to express that don't need the values or keys.
-
-### Example
-```
-for (k, _) in &map {
- ..
-}
-```
-
-could be replaced by
-
-```
-for k in map.keys() {
- ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/forget_copy.txt b/src/tools/clippy/src/docs/forget_copy.txt
deleted file mode 100644
index 1d100912e..000000000
--- a/src/tools/clippy/src/docs/forget_copy.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for calls to `std::mem::forget` with a value that
-derives the Copy trait
-
-### Why is this bad?
-Calling `std::mem::forget` [does nothing for types that
-implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
-value will be copied and moved into the function on invocation.
-
-An alternative, but also valid, explanation is that Copy types do not
-implement
-the Drop trait, which means they have no destructors. Without a destructor,
-there
-is nothing for `std::mem::forget` to ignore.
-
-### Example
-```
-let x: i32 = 42; // i32 implements Copy
-std::mem::forget(x) // A copy of x is passed to the function, leaving the
- // original unaffected
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/forget_non_drop.txt b/src/tools/clippy/src/docs/forget_non_drop.txt
deleted file mode 100644
index 3307d654c..000000000
--- a/src/tools/clippy/src/docs/forget_non_drop.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for calls to `std::mem::forget` with a value that does not implement `Drop`.
-
-### Why is this bad?
-Calling `std::mem::forget` is no different than dropping such a type. A different value may
-have been intended.
-
-### Example
-```
-struct Foo;
-let x = Foo;
-std::mem::forget(x);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/forget_ref.txt b/src/tools/clippy/src/docs/forget_ref.txt
deleted file mode 100644
index 874fb8786..000000000
--- a/src/tools/clippy/src/docs/forget_ref.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for calls to `std::mem::forget` with a reference
-instead of an owned value.
-
-### Why is this bad?
-Calling `forget` on a reference will only forget the
-reference itself, which is a no-op. It will not forget the underlying
-referenced
-value, which is likely what was intended.
-
-### Example
-```
-let x = Box::new(1);
-std::mem::forget(&x) // Should have been forget(x), x will still be dropped
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/format_in_format_args.txt b/src/tools/clippy/src/docs/format_in_format_args.txt
deleted file mode 100644
index ac498472f..000000000
--- a/src/tools/clippy/src/docs/format_in_format_args.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Detects `format!` within the arguments of another macro that does
-formatting such as `format!` itself, `write!` or `println!`. Suggests
-inlining the `format!` call.
-
-### Why is this bad?
-The recommended code is both shorter and avoids a temporary allocation.
-
-### Example
-```
-println!("error: {}", format!("something failed at {}", Location::caller()));
-```
-Use instead:
-```
-println!("error: something failed at {}", Location::caller());
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/format_push_string.txt b/src/tools/clippy/src/docs/format_push_string.txt
deleted file mode 100644
index ca409ebc7..000000000
--- a/src/tools/clippy/src/docs/format_push_string.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Detects cases where the result of a `format!` call is
-appended to an existing `String`.
-
-### Why is this bad?
-Introduces an extra, avoidable heap allocation.
-
-### Known problems
-`format!` returns a `String` but `write!` returns a `Result`.
-Thus you are forced to ignore the `Err` variant to achieve the same API.
-
-While using `write!` in the suggested way should never fail, this isn't necessarily clear to the programmer.
-
-### Example
-```
-let mut s = String::new();
-s += &format!("0x{:X}", 1024);
-s.push_str(&format!("0x{:X}", 1024));
-```
-Use instead:
-```
-use std::fmt::Write as _; // import without risk of name clashing
-
-let mut s = String::new();
-let _ = write!(s, "0x{:X}", 1024);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/from_iter_instead_of_collect.txt b/src/tools/clippy/src/docs/from_iter_instead_of_collect.txt
deleted file mode 100644
index f3fd27597..000000000
--- a/src/tools/clippy/src/docs/from_iter_instead_of_collect.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for `from_iter()` function calls on types that implement the `FromIterator`
-trait.
-
-### Why is this bad?
-It is recommended style to use collect. See
-[FromIterator documentation](https://doc.rust-lang.org/std/iter/trait.FromIterator.html)
-
-### Example
-```
-let five_fives = std::iter::repeat(5).take(5);
-
-let v = Vec::from_iter(five_fives);
-
-assert_eq!(v, vec![5, 5, 5, 5, 5]);
-```
-Use instead:
-```
-let five_fives = std::iter::repeat(5).take(5);
-
-let v: Vec<i32> = five_fives.collect();
-
-assert_eq!(v, vec![5, 5, 5, 5, 5]);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/from_over_into.txt b/src/tools/clippy/src/docs/from_over_into.txt
deleted file mode 100644
index 0770bcc42..000000000
--- a/src/tools/clippy/src/docs/from_over_into.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead.
-
-### Why is this bad?
-According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true.
-
-### Example
-```
-struct StringWrapper(String);
-
-impl Into<StringWrapper> for String {
- fn into(self) -> StringWrapper {
- StringWrapper(self)
- }
-}
-```
-Use instead:
-```
-struct StringWrapper(String);
-
-impl From<String> for StringWrapper {
- fn from(s: String) -> StringWrapper {
- StringWrapper(s)
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/from_str_radix_10.txt b/src/tools/clippy/src/docs/from_str_radix_10.txt
deleted file mode 100644
index f6f319d3e..000000000
--- a/src/tools/clippy/src/docs/from_str_radix_10.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-
-Checks for function invocations of the form `primitive::from_str_radix(s, 10)`
-
-### Why is this bad?
-
-This specific common use case can be rewritten as `s.parse::<primitive>()`
-(and in most cases, the turbofish can be removed), which reduces code length
-and complexity.
-
-### Known problems
-
-This lint may suggest using (&<expression>).parse() instead of <expression>.parse() directly
-in some cases, which is correct but adds unnecessary complexity to the code.
-
-### Example
-```
-let input: &str = get_input();
-let num = u16::from_str_radix(input, 10)?;
-```
-Use instead:
-```
-let input: &str = get_input();
-let num: u16 = input.parse()?;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/future_not_send.txt b/src/tools/clippy/src/docs/future_not_send.txt
deleted file mode 100644
index 0aa048d27..000000000
--- a/src/tools/clippy/src/docs/future_not_send.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-This lint requires Future implementations returned from
-functions and methods to implement the `Send` marker trait. It is mostly
-used by library authors (public and internal) that target an audience where
-multithreaded executors are likely to be used for running these Futures.
-
-### Why is this bad?
-A Future implementation captures some state that it
-needs to eventually produce its final value. When targeting a multithreaded
-executor (which is the norm on non-embedded devices) this means that this
-state may need to be transported to other threads, in other words the
-whole Future needs to implement the `Send` marker trait. If it does not,
-then the resulting Future cannot be submitted to a thread pool in the
-end user’s code.
-
-Especially for generic functions it can be confusing to leave the
-discovery of this problem to the end user: the reported error location
-will be far from its cause and can in many cases not even be fixed without
-modifying the library where the offending Future implementation is
-produced.
-
-### Example
-```
-async fn not_send(bytes: std::rc::Rc<[u8]>) {}
-```
-Use instead:
-```
-async fn is_send(bytes: std::sync::Arc<[u8]>) {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/get_first.txt b/src/tools/clippy/src/docs/get_first.txt
deleted file mode 100644
index c905a737d..000000000
--- a/src/tools/clippy/src/docs/get_first.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for using `x.get(0)` instead of
-`x.first()`.
-
-### Why is this bad?
-Using `x.first()` is easier to read and has the same
-result.
-
-### Example
-```
-let x = vec![2, 3, 5];
-let first_element = x.get(0);
-```
-
-Use instead:
-```
-let x = vec![2, 3, 5];
-let first_element = x.first();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/get_last_with_len.txt b/src/tools/clippy/src/docs/get_last_with_len.txt
deleted file mode 100644
index 31c7f2695..000000000
--- a/src/tools/clippy/src/docs/get_last_with_len.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for using `x.get(x.len() - 1)` instead of
-`x.last()`.
-
-### Why is this bad?
-Using `x.last()` is easier to read and has the same
-result.
-
-Note that using `x[x.len() - 1]` is semantically different from
-`x.last()`. Indexing into the array will panic on out-of-bounds
-accesses, while `x.get()` and `x.last()` will return `None`.
-
-There is another lint (get_unwrap) that covers the case of using
-`x.get(index).unwrap()` instead of `x[index]`.
-
-### Example
-```
-let x = vec![2, 3, 5];
-let last_element = x.get(x.len() - 1);
-```
-
-Use instead:
-```
-let x = vec![2, 3, 5];
-let last_element = x.last();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/get_unwrap.txt b/src/tools/clippy/src/docs/get_unwrap.txt
deleted file mode 100644
index 8defc2224..000000000
--- a/src/tools/clippy/src/docs/get_unwrap.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-### What it does
-Checks for use of `.get().unwrap()` (or
-`.get_mut().unwrap`) on a standard library type which implements `Index`
-
-### Why is this bad?
-Using the Index trait (`[]`) is more clear and more
-concise.
-
-### Known problems
-Not a replacement for error handling: Using either
-`.unwrap()` or the Index trait (`[]`) carries the risk of causing a `panic`
-if the value being accessed is `None`. If the use of `.get().unwrap()` is a
-temporary placeholder for dealing with the `Option` type, then this does
-not mitigate the need for error handling. If there is a chance that `.get()`
-will be `None` in your program, then it is advisable that the `None` case
-is handled in a future refactor instead of using `.unwrap()` or the Index
-trait.
-
-### Example
-```
-let mut some_vec = vec![0, 1, 2, 3];
-let last = some_vec.get(3).unwrap();
-*some_vec.get_mut(0).unwrap() = 1;
-```
-The correct use would be:
-```
-let mut some_vec = vec![0, 1, 2, 3];
-let last = some_vec[3];
-some_vec[0] = 1;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/identity_op.txt b/src/tools/clippy/src/docs/identity_op.txt
deleted file mode 100644
index a8e40bb43..000000000
--- a/src/tools/clippy/src/docs/identity_op.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-### What it does
-Checks for identity operations, e.g., `x + 0`.
-
-### Why is this bad?
-This code can be removed without changing the
-meaning. So it just obscures what's going on. Delete it mercilessly.
-
-### Example
-```
-x / 1 + 0 * 1 - 0 | 0;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/if_let_mutex.txt b/src/tools/clippy/src/docs/if_let_mutex.txt
deleted file mode 100644
index 4d873ade9..000000000
--- a/src/tools/clippy/src/docs/if_let_mutex.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for `Mutex::lock` calls in `if let` expression
-with lock calls in any of the else blocks.
-
-### Why is this bad?
-The Mutex lock remains held for the whole
-`if let ... else` block and deadlocks.
-
-### Example
-```
-if let Ok(thing) = mutex.lock() {
- do_thing();
-} else {
- mutex.lock();
-}
-```
-Should be written
-```
-let locked = mutex.lock();
-if let Ok(thing) = locked {
- do_thing(thing);
-} else {
- use_locked(locked);
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/if_not_else.txt b/src/tools/clippy/src/docs/if_not_else.txt
deleted file mode 100644
index 0e5ac4ce6..000000000
--- a/src/tools/clippy/src/docs/if_not_else.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for usage of `!` or `!=` in an if condition with an
-else branch.
-
-### Why is this bad?
-Negations reduce the readability of statements.
-
-### Example
-```
-if !v.is_empty() {
- a()
-} else {
- b()
-}
-```
-
-Could be written:
-
-```
-if v.is_empty() {
- b()
-} else {
- a()
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/if_same_then_else.txt b/src/tools/clippy/src/docs/if_same_then_else.txt
deleted file mode 100644
index 75127016b..000000000
--- a/src/tools/clippy/src/docs/if_same_then_else.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for `if/else` with the same body as the *then* part
-and the *else* part.
-
-### Why is this bad?
-This is probably a copy & paste error.
-
-### Example
-```
-let foo = if … {
- 42
-} else {
- 42
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/if_then_some_else_none.txt b/src/tools/clippy/src/docs/if_then_some_else_none.txt
deleted file mode 100644
index 13744f920..000000000
--- a/src/tools/clippy/src/docs/if_then_some_else_none.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for if-else that could be written using either `bool::then` or `bool::then_some`.
-
-### Why is this bad?
-Looks a little redundant. Using `bool::then` is more concise and incurs no loss of clarity.
-For simple calculations and known values, use `bool::then_some`, which is eagerly evaluated
-in comparison to `bool::then`.
-
-### Example
-```
-let a = if v.is_empty() {
- println!("true!");
- Some(42)
-} else {
- None
-};
-```
-
-Could be written:
-
-```
-let a = v.is_empty().then(|| {
- println!("true!");
- 42
-});
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ifs_same_cond.txt b/src/tools/clippy/src/docs/ifs_same_cond.txt
deleted file mode 100644
index 024ba5df9..000000000
--- a/src/tools/clippy/src/docs/ifs_same_cond.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for consecutive `if`s with the same condition.
-
-### Why is this bad?
-This is probably a copy & paste error.
-
-### Example
-```
-if a == b {
- …
-} else if a == b {
- …
-}
-```
-
-Note that this lint ignores all conditions with a function call as it could
-have side effects:
-
-```
-if foo() {
- …
-} else if foo() { // not linted
- …
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/implicit_clone.txt b/src/tools/clippy/src/docs/implicit_clone.txt
deleted file mode 100644
index f5aa112c5..000000000
--- a/src/tools/clippy/src/docs/implicit_clone.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer.
-
-### Why is this bad?
-These methods do the same thing as `_.clone()` but may be confusing as
-to why we are calling `to_vec` on something that is already a `Vec` or calling `to_owned` on something that is already owned.
-
-### Example
-```
-let a = vec![1, 2, 3];
-let b = a.to_vec();
-let c = a.to_owned();
-```
-Use instead:
-```
-let a = vec![1, 2, 3];
-let b = a.clone();
-let c = a.clone();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/implicit_hasher.txt b/src/tools/clippy/src/docs/implicit_hasher.txt
deleted file mode 100644
index 0c1f76620..000000000
--- a/src/tools/clippy/src/docs/implicit_hasher.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for public `impl` or `fn` missing generalization
-over different hashers and implicitly defaulting to the default hashing
-algorithm (`SipHash`).
-
-### Why is this bad?
-`HashMap` or `HashSet` with custom hashers cannot be
-used with them.
-
-### Known problems
-Suggestions for replacing constructors can contain
-false-positives. Also applying suggestions can require modification of other
-pieces of code, possibly including external crates.
-
-### Example
-```
-impl<K: Hash + Eq, V> Serialize for HashMap<K, V> { }
-
-pub fn foo(map: &mut HashMap<i32, i32>) { }
-```
-could be rewritten as
-```
-impl<K: Hash + Eq, V, S: BuildHasher> Serialize for HashMap<K, V, S> { }
-
-pub fn foo<S: BuildHasher>(map: &mut HashMap<i32, i32, S>) { }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/implicit_return.txt b/src/tools/clippy/src/docs/implicit_return.txt
deleted file mode 100644
index ee65a636b..000000000
--- a/src/tools/clippy/src/docs/implicit_return.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for missing return statements at the end of a block.
-
-### Why is this bad?
-Actually omitting the return keyword is idiomatic Rust code. Programmers
-coming from other languages might prefer the expressiveness of `return`. It's possible to miss
-the last returning statement because the only difference is a missing `;`. Especially in bigger
-code with multiple return paths having a `return` keyword makes it easier to find the
-corresponding statements.
-
-### Example
-```
-fn foo(x: usize) -> usize {
- x
-}
-```
-add return
-```
-fn foo(x: usize) -> usize {
- return x;
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/implicit_saturating_add.txt b/src/tools/clippy/src/docs/implicit_saturating_add.txt
deleted file mode 100644
index 5883a5363..000000000
--- a/src/tools/clippy/src/docs/implicit_saturating_add.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for implicit saturating addition.
-
-### Why is this bad?
-The built-in function is more readable and may be faster.
-
-### Example
-```
-let mut u:u32 = 7000;
-
-if u != u32::MAX {
- u += 1;
-}
-```
-Use instead:
-```
-let mut u:u32 = 7000;
-
-u = u.saturating_add(1);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/implicit_saturating_sub.txt b/src/tools/clippy/src/docs/implicit_saturating_sub.txt
deleted file mode 100644
index 03b47905a..000000000
--- a/src/tools/clippy/src/docs/implicit_saturating_sub.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for implicit saturating subtraction.
-
-### Why is this bad?
-Simplicity and readability. Instead we can easily use an builtin function.
-
-### Example
-```
-let mut i: u32 = end - start;
-
-if i != 0 {
- i -= 1;
-}
-```
-
-Use instead:
-```
-let mut i: u32 = end - start;
-
-i = i.saturating_sub(1);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/imprecise_flops.txt b/src/tools/clippy/src/docs/imprecise_flops.txt
deleted file mode 100644
index e84d81cea..000000000
--- a/src/tools/clippy/src/docs/imprecise_flops.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Looks for floating-point expressions that
-can be expressed using built-in methods to improve accuracy
-at the cost of performance.
-
-### Why is this bad?
-Negatively impacts accuracy.
-
-### Example
-```
-let a = 3f32;
-let _ = a.powf(1.0 / 3.0);
-let _ = (1.0 + a).ln();
-let _ = a.exp() - 1.0;
-```
-
-Use instead:
-```
-let a = 3f32;
-let _ = a.cbrt();
-let _ = a.ln_1p();
-let _ = a.exp_m1();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inconsistent_digit_grouping.txt b/src/tools/clippy/src/docs/inconsistent_digit_grouping.txt
deleted file mode 100644
index aa0b072de..000000000
--- a/src/tools/clippy/src/docs/inconsistent_digit_grouping.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Warns if an integral or floating-point constant is
-grouped inconsistently with underscores.
-
-### Why is this bad?
-Readers may incorrectly interpret inconsistently
-grouped digits.
-
-### Example
-```
-618_64_9189_73_511
-```
-
-Use instead:
-```
-61_864_918_973_511
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inconsistent_struct_constructor.txt b/src/tools/clippy/src/docs/inconsistent_struct_constructor.txt
deleted file mode 100644
index eb682109a..000000000
--- a/src/tools/clippy/src/docs/inconsistent_struct_constructor.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-### What it does
-Checks for struct constructors where all fields are shorthand and
-the order of the field init shorthand in the constructor is inconsistent
-with the order in the struct definition.
-
-### Why is this bad?
-Since the order of fields in a constructor doesn't affect the
-resulted instance as the below example indicates,
-
-```
-#[derive(Debug, PartialEq, Eq)]
-struct Foo {
- x: i32,
- y: i32,
-}
-let x = 1;
-let y = 2;
-
-// This assertion never fails:
-assert_eq!(Foo { x, y }, Foo { y, x });
-```
-
-inconsistent order can be confusing and decreases readability and consistency.
-
-### Example
-```
-struct Foo {
- x: i32,
- y: i32,
-}
-let x = 1;
-let y = 2;
-
-Foo { y, x };
-```
-
-Use instead:
-```
-Foo { x, y };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/index_refutable_slice.txt b/src/tools/clippy/src/docs/index_refutable_slice.txt
deleted file mode 100644
index 8a7d52761..000000000
--- a/src/tools/clippy/src/docs/index_refutable_slice.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-The lint checks for slice bindings in patterns that are only used to
-access individual slice values.
-
-### Why is this bad?
-Accessing slice values using indices can lead to panics. Using refutable
-patterns can avoid these. Binding to individual values also improves the
-readability as they can be named.
-
-### Limitations
-This lint currently only checks for immutable access inside `if let`
-patterns.
-
-### Example
-```
-let slice: Option<&[u32]> = Some(&[1, 2, 3]);
-
-if let Some(slice) = slice {
- println!("{}", slice[0]);
-}
-```
-Use instead:
-```
-let slice: Option<&[u32]> = Some(&[1, 2, 3]);
-
-if let Some(&[first, ..]) = slice {
- println!("{}", first);
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/indexing_slicing.txt b/src/tools/clippy/src/docs/indexing_slicing.txt
deleted file mode 100644
index 76ca6ed31..000000000
--- a/src/tools/clippy/src/docs/indexing_slicing.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-### What it does
-Checks for usage of indexing or slicing. Arrays are special cases, this lint
-does report on arrays if we can tell that slicing operations are in bounds and does not
-lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint.
-
-### Why is this bad?
-Indexing and slicing can panic at runtime and there are
-safe alternatives.
-
-### Example
-```
-// Vector
-let x = vec![0; 5];
-
-x[2];
-&x[2..100];
-
-// Array
-let y = [0, 1, 2, 3];
-
-&y[10..100];
-&y[10..];
-```
-
-Use instead:
-```
-
-x.get(2);
-x.get(2..100);
-
-y.get(10);
-y.get(10..100);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ineffective_bit_mask.txt b/src/tools/clippy/src/docs/ineffective_bit_mask.txt
deleted file mode 100644
index f6e7ef556..000000000
--- a/src/tools/clippy/src/docs/ineffective_bit_mask.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for bit masks in comparisons which can be removed
-without changing the outcome. The basic structure can be seen in the
-following table:
-
-|Comparison| Bit Op |Example |equals |
-|----------|----------|------------|-------|
-|`>` / `<=`|`\|` / `^`|`x \| 2 > 3`|`x > 3`|
-|`<` / `>=`|`\|` / `^`|`x ^ 1 < 4` |`x < 4`|
-
-### Why is this bad?
-Not equally evil as [`bad_bit_mask`](#bad_bit_mask),
-but still a bit misleading, because the bit mask is ineffective.
-
-### Known problems
-False negatives: This lint will only match instances
-where we have figured out the math (which is for a power-of-two compared
-value). This means things like `x | 1 >= 7` (which would be better written
-as `x >= 6`) will not be reported (but bit masks like this are fairly
-uncommon).
-
-### Example
-```
-if (x | 1 > 3) { }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inefficient_to_string.txt b/src/tools/clippy/src/docs/inefficient_to_string.txt
deleted file mode 100644
index f7061d1ce..000000000
--- a/src/tools/clippy/src/docs/inefficient_to_string.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for usage of `.to_string()` on an `&&T` where
-`T` implements `ToString` directly (like `&&str` or `&&String`).
-
-### Why is this bad?
-This bypasses the specialized implementation of
-`ToString` and instead goes through the more expensive string formatting
-facilities.
-
-### Example
-```
-// Generic implementation for `T: Display` is used (slow)
-["foo", "bar"].iter().map(|s| s.to_string());
-
-// OK, the specialized impl is used
-["foo", "bar"].iter().map(|&s| s.to_string());
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/infallible_destructuring_match.txt b/src/tools/clippy/src/docs/infallible_destructuring_match.txt
deleted file mode 100644
index 4b5d3c4ba..000000000
--- a/src/tools/clippy/src/docs/infallible_destructuring_match.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for matches being used to destructure a single-variant enum
-or tuple struct where a `let` will suffice.
-
-### Why is this bad?
-Just readability – `let` doesn't nest, whereas a `match` does.
-
-### Example
-```
-enum Wrapper {
- Data(i32),
-}
-
-let wrapper = Wrapper::Data(42);
-
-let data = match wrapper {
- Wrapper::Data(i) => i,
-};
-```
-
-The correct use would be:
-```
-enum Wrapper {
- Data(i32),
-}
-
-let wrapper = Wrapper::Data(42);
-let Wrapper::Data(data) = wrapper;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/infinite_iter.txt b/src/tools/clippy/src/docs/infinite_iter.txt
deleted file mode 100644
index 8a22fabc5..000000000
--- a/src/tools/clippy/src/docs/infinite_iter.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for iteration that is guaranteed to be infinite.
-
-### Why is this bad?
-While there may be places where this is acceptable
-(e.g., in event streams), in most cases this is simply an error.
-
-### Example
-```
-use std::iter;
-
-iter::repeat(1_u8).collect::<Vec<_>>();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inherent_to_string.txt b/src/tools/clippy/src/docs/inherent_to_string.txt
deleted file mode 100644
index b18e600e9..000000000
--- a/src/tools/clippy/src/docs/inherent_to_string.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`.
-
-### Why is this bad?
-This method is also implicitly defined if a type implements the `Display` trait. As the functionality of `Display` is much more versatile, it should be preferred.
-
-### Example
-```
-pub struct A;
-
-impl A {
- pub fn to_string(&self) -> String {
- "I am A".to_string()
- }
-}
-```
-
-Use instead:
-```
-use std::fmt;
-
-pub struct A;
-
-impl fmt::Display for A {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "I am A")
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inherent_to_string_shadow_display.txt b/src/tools/clippy/src/docs/inherent_to_string_shadow_display.txt
deleted file mode 100644
index a4bd0b622..000000000
--- a/src/tools/clippy/src/docs/inherent_to_string_shadow_display.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-### What it does
-Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait.
-
-### Why is this bad?
-This method is also implicitly defined if a type implements the `Display` trait. The less versatile inherent method will then shadow the implementation introduced by `Display`.
-
-### Example
-```
-use std::fmt;
-
-pub struct A;
-
-impl A {
- pub fn to_string(&self) -> String {
- "I am A".to_string()
- }
-}
-
-impl fmt::Display for A {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "I am A, too")
- }
-}
-```
-
-Use instead:
-```
-use std::fmt;
-
-pub struct A;
-
-impl fmt::Display for A {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "I am A")
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/init_numbered_fields.txt b/src/tools/clippy/src/docs/init_numbered_fields.txt
deleted file mode 100644
index ba40af6a5..000000000
--- a/src/tools/clippy/src/docs/init_numbered_fields.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for tuple structs initialized with field syntax.
-It will however not lint if a base initializer is present.
-The lint will also ignore code in macros.
-
-### Why is this bad?
-This may be confusing to the uninitiated and adds no
-benefit as opposed to tuple initializers
-
-### Example
-```
-struct TupleStruct(u8, u16);
-
-let _ = TupleStruct {
- 0: 1,
- 1: 23,
-};
-
-// should be written as
-let base = TupleStruct(1, 23);
-
-// This is OK however
-let _ = TupleStruct { 0: 42, ..base };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inline_always.txt b/src/tools/clippy/src/docs/inline_always.txt
deleted file mode 100644
index 7721da4c4..000000000
--- a/src/tools/clippy/src/docs/inline_always.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for items annotated with `#[inline(always)]`,
-unless the annotated function is empty or simply panics.
-
-### Why is this bad?
-While there are valid uses of this annotation (and once
-you know when to use it, by all means `allow` this lint), it's a common
-newbie-mistake to pepper one's code with it.
-
-As a rule of thumb, before slapping `#[inline(always)]` on a function,
-measure if that additional function call really affects your runtime profile
-sufficiently to make up for the increase in compile time.
-
-### Known problems
-False positives, big time. This lint is meant to be
-deactivated by everyone doing serious performance work. This means having
-done the measurement.
-
-### Example
-```
-#[inline(always)]
-fn not_quite_hot_code(..) { ... }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inline_asm_x86_att_syntax.txt b/src/tools/clippy/src/docs/inline_asm_x86_att_syntax.txt
deleted file mode 100644
index 8eb49d122..000000000
--- a/src/tools/clippy/src/docs/inline_asm_x86_att_syntax.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usage of AT&T x86 assembly syntax.
-
-### Why is this bad?
-The lint has been enabled to indicate a preference
-for Intel x86 assembly syntax.
-
-### Example
-
-```
-asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
-```
-Use instead:
-```
-asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inline_asm_x86_intel_syntax.txt b/src/tools/clippy/src/docs/inline_asm_x86_intel_syntax.txt
deleted file mode 100644
index 5aa22c8ed..000000000
--- a/src/tools/clippy/src/docs/inline_asm_x86_intel_syntax.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usage of Intel x86 assembly syntax.
-
-### Why is this bad?
-The lint has been enabled to indicate a preference
-for AT&T x86 assembly syntax.
-
-### Example
-
-```
-asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
-```
-Use instead:
-```
-asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inline_fn_without_body.txt b/src/tools/clippy/src/docs/inline_fn_without_body.txt
deleted file mode 100644
index 127c161aa..000000000
--- a/src/tools/clippy/src/docs/inline_fn_without_body.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for `#[inline]` on trait methods without bodies
-
-### Why is this bad?
-Only implementations of trait methods may be inlined.
-The inline attribute is ignored for trait methods without bodies.
-
-### Example
-```
-trait Animal {
- #[inline]
- fn name(&self) -> &'static str;
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/inspect_for_each.txt b/src/tools/clippy/src/docs/inspect_for_each.txt
deleted file mode 100644
index 01a46d6c4..000000000
--- a/src/tools/clippy/src/docs/inspect_for_each.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for usage of `inspect().for_each()`.
-
-### Why is this bad?
-It is the same as performing the computation
-inside `inspect` at the beginning of the closure in `for_each`.
-
-### Example
-```
-[1,2,3,4,5].iter()
-.inspect(|&x| println!("inspect the number: {}", x))
-.for_each(|&x| {
- assert!(x >= 0);
-});
-```
-Can be written as
-```
-[1,2,3,4,5].iter()
-.for_each(|&x| {
- println!("inspect the number: {}", x);
- assert!(x >= 0);
-});
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/int_plus_one.txt b/src/tools/clippy/src/docs/int_plus_one.txt
deleted file mode 100644
index 1b68f3eeb..000000000
--- a/src/tools/clippy/src/docs/int_plus_one.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block
-
-### Why is this bad?
-Readability -- better to use `> y` instead of `>= y + 1`.
-
-### Example
-```
-if x >= y + 1 {}
-```
-
-Use instead:
-```
-if x > y {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/integer_arithmetic.txt b/src/tools/clippy/src/docs/integer_arithmetic.txt
deleted file mode 100644
index ea57a2ef9..000000000
--- a/src/tools/clippy/src/docs/integer_arithmetic.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for integer arithmetic operations which could overflow or panic.
-
-Specifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable
-of overflowing according to the [Rust
-Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),
-or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is
-attempted.
-
-### Why is this bad?
-Integer overflow will trigger a panic in debug builds or will wrap in
-release mode. Division by zero will cause a panic in either mode. In some applications one
-wants explicitly checked, wrapping or saturating arithmetic.
-
-### Example
-```
-a + 1;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/integer_division.txt b/src/tools/clippy/src/docs/integer_division.txt
deleted file mode 100644
index f6d334981..000000000
--- a/src/tools/clippy/src/docs/integer_division.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for division of integers
-
-### Why is this bad?
-When outside of some very specific algorithms,
-integer division is very often a mistake because it discards the
-remainder.
-
-### Example
-```
-let x = 3 / 2;
-println!("{}", x);
-```
-
-Use instead:
-```
-let x = 3f32 / 2f32;
-println!("{}", x);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/into_iter_on_ref.txt b/src/tools/clippy/src/docs/into_iter_on_ref.txt
deleted file mode 100644
index acb6bd474..000000000
--- a/src/tools/clippy/src/docs/into_iter_on_ref.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for `into_iter` calls on references which should be replaced by `iter`
-or `iter_mut`.
-
-### Why is this bad?
-Readability. Calling `into_iter` on a reference will not move out its
-content into the resulting iterator, which is confusing. It is better just call `iter` or
-`iter_mut` directly.
-
-### Example
-```
-(&vec).into_iter();
-```
-
-Use instead:
-```
-(&vec).iter();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/invalid_null_ptr_usage.txt b/src/tools/clippy/src/docs/invalid_null_ptr_usage.txt
deleted file mode 100644
index 6fb3fa3f8..000000000
--- a/src/tools/clippy/src/docs/invalid_null_ptr_usage.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-This lint checks for invalid usages of `ptr::null`.
-
-### Why is this bad?
-This causes undefined behavior.
-
-### Example
-```
-// Undefined behavior
-unsafe { std::slice::from_raw_parts(ptr::null(), 0); }
-```
-
-Use instead:
-```
-unsafe { std::slice::from_raw_parts(NonNull::dangling().as_ptr(), 0); }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/invalid_regex.txt b/src/tools/clippy/src/docs/invalid_regex.txt
deleted file mode 100644
index 6c9969b6e..000000000
--- a/src/tools/clippy/src/docs/invalid_regex.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks [regex](https://crates.io/crates/regex) creation
-(with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct
-regex syntax.
-
-### Why is this bad?
-This will lead to a runtime panic.
-
-### Example
-```
-Regex::new("(")
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/invalid_upcast_comparisons.txt b/src/tools/clippy/src/docs/invalid_upcast_comparisons.txt
deleted file mode 100644
index 77cb03308..000000000
--- a/src/tools/clippy/src/docs/invalid_upcast_comparisons.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for comparisons where the relation is always either
-true or false, but where one side has been upcast so that the comparison is
-necessary. Only integer types are checked.
-
-### Why is this bad?
-An expression like `let x : u8 = ...; (x as u32) > 300`
-will mistakenly imply that it is possible for `x` to be outside the range of
-`u8`.
-
-### Known problems
-https://github.com/rust-lang/rust-clippy/issues/886
-
-### Example
-```
-let x: u8 = 1;
-(x as u32) > 300;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/invalid_utf8_in_unchecked.txt b/src/tools/clippy/src/docs/invalid_utf8_in_unchecked.txt
deleted file mode 100644
index afb5acbe9..000000000
--- a/src/tools/clippy/src/docs/invalid_utf8_in_unchecked.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for `std::str::from_utf8_unchecked` with an invalid UTF-8 literal
-
-### Why is this bad?
-Creating such a `str` would result in undefined behavior
-
-### Example
-```
-unsafe {
- std::str::from_utf8_unchecked(b"cl\x82ippy");
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/invisible_characters.txt b/src/tools/clippy/src/docs/invisible_characters.txt
deleted file mode 100644
index 3dda38091..000000000
--- a/src/tools/clippy/src/docs/invisible_characters.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-### What it does
-Checks for invisible Unicode characters in the code.
-
-### Why is this bad?
-Having an invisible character in the code makes for all
-sorts of April fools, but otherwise is very much frowned upon.
-
-### Example
-You don't see it, but there may be a zero-width space or soft hyphen
-some­where in this text. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/is_digit_ascii_radix.txt b/src/tools/clippy/src/docs/is_digit_ascii_radix.txt
deleted file mode 100644
index 9f11cf430..000000000
--- a/src/tools/clippy/src/docs/is_digit_ascii_radix.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Finds usages of [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit) that
-can be replaced with [`is_ascii_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_digit) or
-[`is_ascii_hexdigit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_hexdigit).
-
-### Why is this bad?
-`is_digit(..)` is slower and requires specifying the radix.
-
-### Example
-```
-let c: char = '6';
-c.is_digit(10);
-c.is_digit(16);
-```
-Use instead:
-```
-let c: char = '6';
-c.is_ascii_digit();
-c.is_ascii_hexdigit();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/items_after_statements.txt b/src/tools/clippy/src/docs/items_after_statements.txt
deleted file mode 100644
index 6fdfff50d..000000000
--- a/src/tools/clippy/src/docs/items_after_statements.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-### What it does
-Checks for items declared after some statement in a block.
-
-### Why is this bad?
-Items live for the entire scope they are declared
-in. But statements are processed in order. This might cause confusion as
-it's hard to figure out which item is meant in a statement.
-
-### Example
-```
-fn foo() {
- println!("cake");
-}
-
-fn main() {
- foo(); // prints "foo"
- fn foo() {
- println!("foo");
- }
- foo(); // prints "foo"
-}
-```
-
-Use instead:
-```
-fn foo() {
- println!("cake");
-}
-
-fn main() {
- fn foo() {
- println!("foo");
- }
- foo(); // prints "foo"
- foo(); // prints "foo"
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_cloned_collect.txt b/src/tools/clippy/src/docs/iter_cloned_collect.txt
deleted file mode 100644
index 90dc9ebb4..000000000
--- a/src/tools/clippy/src/docs/iter_cloned_collect.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for the use of `.cloned().collect()` on slice to
-create a `Vec`.
-
-### Why is this bad?
-`.to_vec()` is clearer
-
-### Example
-```
-let s = [1, 2, 3, 4, 5];
-let s2: Vec<isize> = s[..].iter().cloned().collect();
-```
-The better use would be:
-```
-let s = [1, 2, 3, 4, 5];
-let s2: Vec<isize> = s.to_vec();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_count.txt b/src/tools/clippy/src/docs/iter_count.txt
deleted file mode 100644
index f3db4a26c..000000000
--- a/src/tools/clippy/src/docs/iter_count.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for the use of `.iter().count()`.
-
-### Why is this bad?
-`.len()` is more efficient and more
-readable.
-
-### Example
-```
-let some_vec = vec![0, 1, 2, 3];
-
-some_vec.iter().count();
-&some_vec[..].iter().count();
-```
-
-Use instead:
-```
-let some_vec = vec![0, 1, 2, 3];
-
-some_vec.len();
-&some_vec[..].len();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_kv_map.txt b/src/tools/clippy/src/docs/iter_kv_map.txt
deleted file mode 100644
index a063c8195..000000000
--- a/src/tools/clippy/src/docs/iter_kv_map.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-
-Checks for iterating a map (`HashMap` or `BTreeMap`) and
-ignoring either the keys or values.
-
-### Why is this bad?
-
-Readability. There are `keys` and `values` methods that
-can be used to express that we only need the keys or the values.
-
-### Example
-
-```
-let map: HashMap<u32, u32> = HashMap::new();
-let values = map.iter().map(|(_, value)| value).collect::<Vec<_>>();
-```
-
-Use instead:
-```
-let map: HashMap<u32, u32> = HashMap::new();
-let values = map.values().collect::<Vec<_>>();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_next_loop.txt b/src/tools/clippy/src/docs/iter_next_loop.txt
deleted file mode 100644
index b33eb39d6..000000000
--- a/src/tools/clippy/src/docs/iter_next_loop.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for loops on `x.next()`.
-
-### Why is this bad?
-`next()` returns either `Some(value)` if there was a
-value, or `None` otherwise. The insidious thing is that `Option<_>`
-implements `IntoIterator`, so that possibly one value will be iterated,
-leading to some hard to find bugs. No one will want to write such code
-[except to win an Underhanded Rust
-Contest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr).
-
-### Example
-```
-for x in y.next() {
- ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_next_slice.txt b/src/tools/clippy/src/docs/iter_next_slice.txt
deleted file mode 100644
index 1cea25eaf..000000000
--- a/src/tools/clippy/src/docs/iter_next_slice.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usage of `iter().next()` on a Slice or an Array
-
-### Why is this bad?
-These can be shortened into `.get()`
-
-### Example
-```
-a[2..].iter().next();
-b.iter().next();
-```
-should be written as:
-```
-a.get(2);
-b.get(0);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_not_returning_iterator.txt b/src/tools/clippy/src/docs/iter_not_returning_iterator.txt
deleted file mode 100644
index 0ca862910..000000000
--- a/src/tools/clippy/src/docs/iter_not_returning_iterator.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Detects methods named `iter` or `iter_mut` that do not have a return type that implements `Iterator`.
-
-### Why is this bad?
-Methods named `iter` or `iter_mut` conventionally return an `Iterator`.
-
-### Example
-```
-// `String` does not implement `Iterator`
-struct Data {}
-impl Data {
- fn iter(&self) -> String {
- todo!()
- }
-}
-```
-Use instead:
-```
-use std::str::Chars;
-struct Data {}
-impl Data {
- fn iter(&self) -> Chars<'static> {
- todo!()
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_nth.txt b/src/tools/clippy/src/docs/iter_nth.txt
deleted file mode 100644
index 3d67d583f..000000000
--- a/src/tools/clippy/src/docs/iter_nth.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for use of `.iter().nth()` (and the related
-`.iter_mut().nth()`) on standard library types with *O*(1) element access.
-
-### Why is this bad?
-`.get()` and `.get_mut()` are more efficient and more
-readable.
-
-### Example
-```
-let some_vec = vec![0, 1, 2, 3];
-let bad_vec = some_vec.iter().nth(3);
-let bad_slice = &some_vec[..].iter().nth(3);
-```
-The correct use would be:
-```
-let some_vec = vec![0, 1, 2, 3];
-let bad_vec = some_vec.get(3);
-let bad_slice = &some_vec[..].get(3);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_nth_zero.txt b/src/tools/clippy/src/docs/iter_nth_zero.txt
deleted file mode 100644
index 8efe47a16..000000000
--- a/src/tools/clippy/src/docs/iter_nth_zero.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for the use of `iter.nth(0)`.
-
-### Why is this bad?
-`iter.next()` is equivalent to
-`iter.nth(0)`, as they both consume the next element,
- but is more readable.
-
-### Example
-```
-let x = s.iter().nth(0);
-```
-
-Use instead:
-```
-let x = s.iter().next();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_on_empty_collections.txt b/src/tools/clippy/src/docs/iter_on_empty_collections.txt
deleted file mode 100644
index 87c4ec12a..000000000
--- a/src/tools/clippy/src/docs/iter_on_empty_collections.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-
-Checks for calls to `iter`, `iter_mut` or `into_iter` on empty collections
-
-### Why is this bad?
-
-It is simpler to use the empty function from the standard library:
-
-### Example
-
-```
-use std::{slice, option};
-let a: slice::Iter<i32> = [].iter();
-let f: option::IntoIter<i32> = None.into_iter();
-```
-Use instead:
-```
-use std::iter;
-let a: iter::Empty<i32> = iter::empty();
-let b: iter::Empty<i32> = iter::empty();
-```
-
-### Known problems
-
-The type of the resulting iterator might become incompatible with its usage \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_on_single_items.txt b/src/tools/clippy/src/docs/iter_on_single_items.txt
deleted file mode 100644
index d0388f25d..000000000
--- a/src/tools/clippy/src/docs/iter_on_single_items.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-
-Checks for calls to `iter`, `iter_mut` or `into_iter` on collections containing a single item
-
-### Why is this bad?
-
-It is simpler to use the once function from the standard library:
-
-### Example
-
-```
-let a = [123].iter();
-let b = Some(123).into_iter();
-```
-Use instead:
-```
-use std::iter;
-let a = iter::once(&123);
-let b = iter::once(123);
-```
-
-### Known problems
-
-The type of the resulting iterator might become incompatible with its usage \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_overeager_cloned.txt b/src/tools/clippy/src/docs/iter_overeager_cloned.txt
deleted file mode 100644
index 2f902a0c2..000000000
--- a/src/tools/clippy/src/docs/iter_overeager_cloned.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for usage of `_.cloned().<func>()` where call to `.cloned()` can be postponed.
-
-### Why is this bad?
-It's often inefficient to clone all elements of an iterator, when eventually, only some
-of them will be consumed.
-
-### Known Problems
-This `lint` removes the side of effect of cloning items in the iterator.
-A code that relies on that side-effect could fail.
-
-### Examples
-```
-vec.iter().cloned().take(10);
-vec.iter().cloned().last();
-```
-
-Use instead:
-```
-vec.iter().take(10).cloned();
-vec.iter().last().cloned();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_skip_next.txt b/src/tools/clippy/src/docs/iter_skip_next.txt
deleted file mode 100644
index da226b041..000000000
--- a/src/tools/clippy/src/docs/iter_skip_next.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for use of `.skip(x).next()` on iterators.
-
-### Why is this bad?
-`.nth(x)` is cleaner
-
-### Example
-```
-let some_vec = vec![0, 1, 2, 3];
-let bad_vec = some_vec.iter().skip(3).next();
-let bad_slice = &some_vec[..].iter().skip(3).next();
-```
-The correct use would be:
-```
-let some_vec = vec![0, 1, 2, 3];
-let bad_vec = some_vec.iter().nth(3);
-let bad_slice = &some_vec[..].iter().nth(3);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iter_with_drain.txt b/src/tools/clippy/src/docs/iter_with_drain.txt
deleted file mode 100644
index 2c52b99f7..000000000
--- a/src/tools/clippy/src/docs/iter_with_drain.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for use of `.drain(..)` on `Vec` and `VecDeque` for iteration.
-
-### Why is this bad?
-`.into_iter()` is simpler with better performance.
-
-### Example
-```
-let mut foo = vec![0, 1, 2, 3];
-let bar: HashSet<usize> = foo.drain(..).collect();
-```
-Use instead:
-```
-let foo = vec![0, 1, 2, 3];
-let bar: HashSet<usize> = foo.into_iter().collect();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/iterator_step_by_zero.txt b/src/tools/clippy/src/docs/iterator_step_by_zero.txt
deleted file mode 100644
index 73ecc99ac..000000000
--- a/src/tools/clippy/src/docs/iterator_step_by_zero.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for calling `.step_by(0)` on iterators which panics.
-
-### Why is this bad?
-This very much looks like an oversight. Use `panic!()` instead if you
-actually intend to panic.
-
-### Example
-```
-for x in (0..100).step_by(0) {
- //..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/just_underscores_and_digits.txt b/src/tools/clippy/src/docs/just_underscores_and_digits.txt
deleted file mode 100644
index a8790bcf2..000000000
--- a/src/tools/clippy/src/docs/just_underscores_and_digits.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks if you have variables whose name consists of just
-underscores and digits.
-
-### Why is this bad?
-It's hard to memorize what a variable means without a
-descriptive name.
-
-### Example
-```
-let _1 = 1;
-let ___1 = 1;
-let __1___2 = 11;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_const_arrays.txt b/src/tools/clippy/src/docs/large_const_arrays.txt
deleted file mode 100644
index 71f67854f..000000000
--- a/src/tools/clippy/src/docs/large_const_arrays.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for large `const` arrays that should
-be defined as `static` instead.
-
-### Why is this bad?
-Performance: const variables are inlined upon use.
-Static items result in only one instance and has a fixed location in memory.
-
-### Example
-```
-pub const a = [0u32; 1_000_000];
-```
-
-Use instead:
-```
-pub static a = [0u32; 1_000_000];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_digit_groups.txt b/src/tools/clippy/src/docs/large_digit_groups.txt
deleted file mode 100644
index f60b19345..000000000
--- a/src/tools/clippy/src/docs/large_digit_groups.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Warns if the digits of an integral or floating-point
-constant are grouped into groups that
-are too large.
-
-### Why is this bad?
-Negatively impacts readability.
-
-### Example
-```
-let x: u64 = 6186491_8973511;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_enum_variant.txt b/src/tools/clippy/src/docs/large_enum_variant.txt
deleted file mode 100644
index 1f9543079..000000000
--- a/src/tools/clippy/src/docs/large_enum_variant.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-### What it does
-Checks for large size differences between variants on
-`enum`s.
-
-### Why is this bad?
-Enum size is bounded by the largest variant. Having one
-large variant can penalize the memory layout of that enum.
-
-### Known problems
-This lint obviously cannot take the distribution of
-variants in your running program into account. It is possible that the
-smaller variants make up less than 1% of all instances, in which case
-the overhead is negligible and the boxing is counter-productive. Always
-measure the change this lint suggests.
-
-For types that implement `Copy`, the suggestion to `Box` a variant's
-data would require removing the trait impl. The types can of course
-still be `Clone`, but that is worse ergonomically. Depending on the
-use case it may be possible to store the large data in an auxiliary
-structure (e.g. Arena or ECS).
-
-The lint will ignore the impact of generic types to the type layout by
-assuming every type parameter is zero-sized. Depending on your use case,
-this may lead to a false positive.
-
-### Example
-```
-enum Test {
- A(i32),
- B([i32; 8000]),
-}
-```
-
-Use instead:
-```
-// Possibly better
-enum Test2 {
- A(i32),
- B(Box<[i32; 8000]>),
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_include_file.txt b/src/tools/clippy/src/docs/large_include_file.txt
deleted file mode 100644
index b2a54bd2e..000000000
--- a/src/tools/clippy/src/docs/large_include_file.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for the inclusion of large files via `include_bytes!()`
-and `include_str!()`
-
-### Why is this bad?
-Including large files can increase the size of the binary
-
-### Example
-```
-let included_str = include_str!("very_large_file.txt");
-let included_bytes = include_bytes!("very_large_file.txt");
-```
-
-Use instead:
-```
-use std::fs;
-
-// You can load the file at runtime
-let string = fs::read_to_string("very_large_file.txt")?;
-let bytes = fs::read("very_large_file.txt")?;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_stack_arrays.txt b/src/tools/clippy/src/docs/large_stack_arrays.txt
deleted file mode 100644
index 4a6f34785..000000000
--- a/src/tools/clippy/src/docs/large_stack_arrays.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-### What it does
-Checks for local arrays that may be too large.
-
-### Why is this bad?
-Large local arrays may cause stack overflow.
-
-### Example
-```
-let a = [0u32; 1_000_000];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/large_types_passed_by_value.txt b/src/tools/clippy/src/docs/large_types_passed_by_value.txt
deleted file mode 100644
index bca07f3ac..000000000
--- a/src/tools/clippy/src/docs/large_types_passed_by_value.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for functions taking arguments by value, where
-the argument type is `Copy` and large enough to be worth considering
-passing by reference. Does not trigger if the function is being exported,
-because that might induce API breakage, if the parameter is declared as mutable,
-or if the argument is a `self`.
-
-### Why is this bad?
-Arguments passed by value might result in an unnecessary
-shallow copy, taking up more space in the stack and requiring a call to
-`memcpy`, which can be expensive.
-
-### Example
-```
-#[derive(Clone, Copy)]
-struct TooLarge([u8; 2048]);
-
-fn foo(v: TooLarge) {}
-```
-
-Use instead:
-```
-fn foo(v: &TooLarge) {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/len_without_is_empty.txt b/src/tools/clippy/src/docs/len_without_is_empty.txt
deleted file mode 100644
index 47a2e8575..000000000
--- a/src/tools/clippy/src/docs/len_without_is_empty.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for items that implement `.len()` but not
-`.is_empty()`.
-
-### Why is this bad?
-It is good custom to have both methods, because for
-some data structures, asking about the length will be a costly operation,
-whereas `.is_empty()` can usually answer in constant time. Also it used to
-lead to false positives on the [`len_zero`](#len_zero) lint – currently that
-lint will ignore such entities.
-
-### Example
-```
-impl X {
- pub fn len(&self) -> usize {
- ..
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/len_zero.txt b/src/tools/clippy/src/docs/len_zero.txt
deleted file mode 100644
index 664124bd3..000000000
--- a/src/tools/clippy/src/docs/len_zero.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for getting the length of something via `.len()`
-just to compare to zero, and suggests using `.is_empty()` where applicable.
-
-### Why is this bad?
-Some structures can answer `.is_empty()` much faster
-than calculating their length. So it is good to get into the habit of using
-`.is_empty()`, and having it is cheap.
-Besides, it makes the intent clearer than a manual comparison in some contexts.
-
-### Example
-```
-if x.len() == 0 {
- ..
-}
-if y.len() != 0 {
- ..
-}
-```
-instead use
-```
-if x.is_empty() {
- ..
-}
-if !y.is_empty() {
- ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/let_and_return.txt b/src/tools/clippy/src/docs/let_and_return.txt
deleted file mode 100644
index eba5a90dd..000000000
--- a/src/tools/clippy/src/docs/let_and_return.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for `let`-bindings, which are subsequently
-returned.
-
-### Why is this bad?
-It is just extraneous code. Remove it to make your code
-more rusty.
-
-### Example
-```
-fn foo() -> String {
- let x = String::new();
- x
-}
-```
-instead, use
-```
-fn foo() -> String {
- String::new()
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/let_underscore_drop.txt b/src/tools/clippy/src/docs/let_underscore_drop.txt
deleted file mode 100644
index 29ce9bf50..000000000
--- a/src/tools/clippy/src/docs/let_underscore_drop.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for `let _ = <expr>`
-where expr has a type that implements `Drop`
-
-### Why is this bad?
-This statement immediately drops the initializer
-expression instead of extending its lifetime to the end of the scope, which
-is often not intended. To extend the expression's lifetime to the end of the
-scope, use an underscore-prefixed name instead (i.e. _var). If you want to
-explicitly drop the expression, `std::mem::drop` conveys your intention
-better and is less error-prone.
-
-### Example
-```
-{
- let _ = DroppableItem;
- // ^ dropped here
- /* more code */
-}
-```
-
-Use instead:
-```
-{
- let _droppable = DroppableItem;
- /* more code */
- // dropped at end of scope
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/let_underscore_lock.txt b/src/tools/clippy/src/docs/let_underscore_lock.txt
deleted file mode 100644
index bd8217fb5..000000000
--- a/src/tools/clippy/src/docs/let_underscore_lock.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for `let _ = sync_lock`.
-This supports `mutex` and `rwlock` in `std::sync` and `parking_lot`.
-
-### Why is this bad?
-This statement immediately drops the lock instead of
-extending its lifetime to the end of the scope, which is often not intended.
-To extend lock lifetime to the end of the scope, use an underscore-prefixed
-name instead (i.e. _lock). If you want to explicitly drop the lock,
-`std::mem::drop` conveys your intention better and is less error-prone.
-
-### Example
-```
-let _ = mutex.lock();
-```
-
-Use instead:
-```
-let _lock = mutex.lock();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/let_underscore_must_use.txt b/src/tools/clippy/src/docs/let_underscore_must_use.txt
deleted file mode 100644
index 270b81d9a..000000000
--- a/src/tools/clippy/src/docs/let_underscore_must_use.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for `let _ = <expr>` where expr is `#[must_use]`
-
-### Why is this bad?
-It's better to explicitly handle the value of a `#[must_use]`
-expr
-
-### Example
-```
-fn f() -> Result<u32, u32> {
- Ok(0)
-}
-
-let _ = f();
-// is_ok() is marked #[must_use]
-let _ = f().is_ok();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/let_unit_value.txt b/src/tools/clippy/src/docs/let_unit_value.txt
deleted file mode 100644
index bc16d5b3d..000000000
--- a/src/tools/clippy/src/docs/let_unit_value.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for binding a unit value.
-
-### Why is this bad?
-A unit value cannot usefully be used anywhere. So
-binding one is kind of pointless.
-
-### Example
-```
-let x = {
- 1;
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/linkedlist.txt b/src/tools/clippy/src/docs/linkedlist.txt
deleted file mode 100644
index 986ff1369..000000000
--- a/src/tools/clippy/src/docs/linkedlist.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks for usage of any `LinkedList`, suggesting to use a
-`Vec` or a `VecDeque` (formerly called `RingBuf`).
-
-### Why is this bad?
-Gankro says:
-
-> The TL;DR of `LinkedList` is that it's built on a massive amount of
-pointers and indirection.
-> It wastes memory, it has terrible cache locality, and is all-around slow.
-`RingBuf`, while
-> "only" amortized for push/pop, should be faster in the general case for
-almost every possible
-> workload, and isn't even amortized at all if you can predict the capacity
-you need.
->
-> `LinkedList`s are only really good if you're doing a lot of merging or
-splitting of lists.
-> This is because they can just mangle some pointers instead of actually
-copying the data. Even
-> if you're doing a lot of insertion in the middle of the list, `RingBuf`
-can still be better
-> because of how expensive it is to seek to the middle of a `LinkedList`.
-
-### Known problems
-False positives – the instances where using a
-`LinkedList` makes sense are few and far between, but they can still happen.
-
-### Example
-```
-let x: LinkedList<usize> = LinkedList::new();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/lossy_float_literal.txt b/src/tools/clippy/src/docs/lossy_float_literal.txt
deleted file mode 100644
index bbcb9115e..000000000
--- a/src/tools/clippy/src/docs/lossy_float_literal.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for whole number float literals that
-cannot be represented as the underlying type without loss.
-
-### Why is this bad?
-Rust will silently lose precision during
-conversion to a float.
-
-### Example
-```
-let _: f32 = 16_777_217.0; // 16_777_216.0
-```
-
-Use instead:
-```
-let _: f32 = 16_777_216.0;
-let _: f64 = 16_777_217.0;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/macro_use_imports.txt b/src/tools/clippy/src/docs/macro_use_imports.txt
deleted file mode 100644
index 6a8180a60..000000000
--- a/src/tools/clippy/src/docs/macro_use_imports.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for `#[macro_use] use...`.
-
-### Why is this bad?
-Since the Rust 2018 edition you can import
-macro's directly, this is considered idiomatic.
-
-### Example
-```
-#[macro_use]
-use some_macro;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/main_recursion.txt b/src/tools/clippy/src/docs/main_recursion.txt
deleted file mode 100644
index e49becd15..000000000
--- a/src/tools/clippy/src/docs/main_recursion.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for recursion using the entrypoint.
-
-### Why is this bad?
-Apart from special setups (which we could detect following attributes like #![no_std]),
-recursing into main() seems like an unintuitive anti-pattern we should be able to detect.
-
-### Example
-```
-fn main() {
- main();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_assert.txt b/src/tools/clippy/src/docs/manual_assert.txt
deleted file mode 100644
index 93653081a..000000000
--- a/src/tools/clippy/src/docs/manual_assert.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Detects `if`-then-`panic!` that can be replaced with `assert!`.
-
-### Why is this bad?
-`assert!` is simpler than `if`-then-`panic!`.
-
-### Example
-```
-let sad_people: Vec<&str> = vec![];
-if !sad_people.is_empty() {
- panic!("there are sad people: {:?}", sad_people);
-}
-```
-Use instead:
-```
-let sad_people: Vec<&str> = vec![];
-assert!(sad_people.is_empty(), "there are sad people: {:?}", sad_people);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_async_fn.txt b/src/tools/clippy/src/docs/manual_async_fn.txt
deleted file mode 100644
index d01ac402e..000000000
--- a/src/tools/clippy/src/docs/manual_async_fn.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-It checks for manual implementations of `async` functions.
-
-### Why is this bad?
-It's more idiomatic to use the dedicated syntax.
-
-### Example
-```
-use std::future::Future;
-
-fn foo() -> impl Future<Output = i32> { async { 42 } }
-```
-Use instead:
-```
-async fn foo() -> i32 { 42 }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_bits.txt b/src/tools/clippy/src/docs/manual_bits.txt
deleted file mode 100644
index b96c2eb15..000000000
--- a/src/tools/clippy/src/docs/manual_bits.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for uses of `std::mem::size_of::<T>() * 8` when
-`T::BITS` is available.
-
-### Why is this bad?
-Can be written as the shorter `T::BITS`.
-
-### Example
-```
-std::mem::size_of::<usize>() * 8;
-```
-Use instead:
-```
-usize::BITS as usize;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_clamp.txt b/src/tools/clippy/src/docs/manual_clamp.txt
deleted file mode 100644
index 8993f6683..000000000
--- a/src/tools/clippy/src/docs/manual_clamp.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-### What it does
-Identifies good opportunities for a clamp function from std or core, and suggests using it.
-
-### Why is this bad?
-clamp is much shorter, easier to read, and doesn't use any control flow.
-
-### Known issue(s)
-If the clamped variable is NaN this suggestion will cause the code to propagate NaN
-rather than returning either `max` or `min`.
-
-`clamp` functions will panic if `max < min`, `max.is_nan()`, or `min.is_nan()`.
-Some may consider panicking in these situations to be desirable, but it also may
-introduce panicking where there wasn't any before.
-
-### Examples
-```
-if input > max {
- max
-} else if input < min {
- min
-} else {
- input
-}
-```
-
-```
-input.max(min).min(max)
-```
-
-```
-match input {
- x if x > max => max,
- x if x < min => min,
- x => x,
-}
-```
-
-```
-let mut x = input;
-if x < min { x = min; }
-if x > max { x = max; }
-```
-Use instead:
-```
-input.clamp(min, max)
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_filter.txt b/src/tools/clippy/src/docs/manual_filter.txt
deleted file mode 100644
index 19a4d9319..000000000
--- a/src/tools/clippy/src/docs/manual_filter.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for usages of `match` which could be implemented using `filter`
-
-### Why is this bad?
-Using the `filter` method is clearer and more concise.
-
-### Example
-```
-match Some(0) {
- Some(x) => if x % 2 == 0 {
- Some(x)
- } else {
- None
- },
- None => None,
-};
-```
-Use instead:
-```
-Some(0).filter(|&x| x % 2 == 0);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_filter_map.txt b/src/tools/clippy/src/docs/manual_filter_map.txt
deleted file mode 100644
index 3b6860798..000000000
--- a/src/tools/clippy/src/docs/manual_filter_map.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for usage of `_.filter(_).map(_)` that can be written more simply
-as `filter_map(_)`.
-
-### Why is this bad?
-Redundant code in the `filter` and `map` operations is poor style and
-less performant.
-
-### Example
-```
-(0_i32..10)
- .filter(|n| n.checked_add(1).is_some())
- .map(|n| n.checked_add(1).unwrap());
-```
-
-Use instead:
-```
-(0_i32..10).filter_map(|n| n.checked_add(1));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_find.txt b/src/tools/clippy/src/docs/manual_find.txt
deleted file mode 100644
index e3e07a277..000000000
--- a/src/tools/clippy/src/docs/manual_find.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Check for manual implementations of Iterator::find
-
-### Why is this bad?
-It doesn't affect performance, but using `find` is shorter and easier to read.
-
-### Example
-
-```
-fn example(arr: Vec<i32>) -> Option<i32> {
- for el in arr {
- if el == 1 {
- return Some(el);
- }
- }
- None
-}
-```
-Use instead:
-```
-fn example(arr: Vec<i32>) -> Option<i32> {
- arr.into_iter().find(|&el| el == 1)
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_find_map.txt b/src/tools/clippy/src/docs/manual_find_map.txt
deleted file mode 100644
index 83b22060c..000000000
--- a/src/tools/clippy/src/docs/manual_find_map.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for usage of `_.find(_).map(_)` that can be written more simply
-as `find_map(_)`.
-
-### Why is this bad?
-Redundant code in the `find` and `map` operations is poor style and
-less performant.
-
-### Example
-```
-(0_i32..10)
- .find(|n| n.checked_add(1).is_some())
- .map(|n| n.checked_add(1).unwrap());
-```
-
-Use instead:
-```
-(0_i32..10).find_map(|n| n.checked_add(1));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_flatten.txt b/src/tools/clippy/src/docs/manual_flatten.txt
deleted file mode 100644
index 62d5f3ec9..000000000
--- a/src/tools/clippy/src/docs/manual_flatten.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Check for unnecessary `if let` usage in a for loop
-where only the `Some` or `Ok` variant of the iterator element is used.
-
-### Why is this bad?
-It is verbose and can be simplified
-by first calling the `flatten` method on the `Iterator`.
-
-### Example
-
-```
-let x = vec![Some(1), Some(2), Some(3)];
-for n in x {
- if let Some(n) = n {
- println!("{}", n);
- }
-}
-```
-Use instead:
-```
-let x = vec![Some(1), Some(2), Some(3)];
-for n in x.into_iter().flatten() {
- println!("{}", n);
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_instant_elapsed.txt b/src/tools/clippy/src/docs/manual_instant_elapsed.txt
deleted file mode 100644
index dde3d493c..000000000
--- a/src/tools/clippy/src/docs/manual_instant_elapsed.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Lints subtraction between `Instant::now()` and another `Instant`.
-
-### Why is this bad?
-It is easy to accidentally write `prev_instant - Instant::now()`, which will always be 0ns
-as `Instant` subtraction saturates.
-
-`prev_instant.elapsed()` also more clearly signals intention.
-
-### Example
-```
-use std::time::Instant;
-let prev_instant = Instant::now();
-let duration = Instant::now() - prev_instant;
-```
-Use instead:
-```
-use std::time::Instant;
-let prev_instant = Instant::now();
-let duration = prev_instant.elapsed();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_map.txt b/src/tools/clippy/src/docs/manual_map.txt
deleted file mode 100644
index 7f68ccd10..000000000
--- a/src/tools/clippy/src/docs/manual_map.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for usages of `match` which could be implemented using `map`
-
-### Why is this bad?
-Using the `map` method is clearer and more concise.
-
-### Example
-```
-match Some(0) {
- Some(x) => Some(x + 1),
- None => None,
-};
-```
-Use instead:
-```
-Some(0).map(|x| x + 1);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_memcpy.txt b/src/tools/clippy/src/docs/manual_memcpy.txt
deleted file mode 100644
index d7690bf25..000000000
--- a/src/tools/clippy/src/docs/manual_memcpy.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for for-loops that manually copy items between
-slices that could be optimized by having a memcpy.
-
-### Why is this bad?
-It is not as fast as a memcpy.
-
-### Example
-```
-for i in 0..src.len() {
- dst[i + 64] = src[i];
-}
-```
-
-Use instead:
-```
-dst[64..(src.len() + 64)].clone_from_slice(&src[..]);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_non_exhaustive.txt b/src/tools/clippy/src/docs/manual_non_exhaustive.txt
deleted file mode 100644
index fb021393b..000000000
--- a/src/tools/clippy/src/docs/manual_non_exhaustive.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-### What it does
-Checks for manual implementations of the non-exhaustive pattern.
-
-### Why is this bad?
-Using the #[non_exhaustive] attribute expresses better the intent
-and allows possible optimizations when applied to enums.
-
-### Example
-```
-struct S {
- pub a: i32,
- pub b: i32,
- _c: (),
-}
-
-enum E {
- A,
- B,
- #[doc(hidden)]
- _C,
-}
-
-struct T(pub i32, pub i32, ());
-```
-Use instead:
-```
-#[non_exhaustive]
-struct S {
- pub a: i32,
- pub b: i32,
-}
-
-#[non_exhaustive]
-enum E {
- A,
- B,
-}
-
-#[non_exhaustive]
-struct T(pub i32, pub i32);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_ok_or.txt b/src/tools/clippy/src/docs/manual_ok_or.txt
deleted file mode 100644
index 5accdf259..000000000
--- a/src/tools/clippy/src/docs/manual_ok_or.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-
-Finds patterns that reimplement `Option::ok_or`.
-
-### Why is this bad?
-
-Concise code helps focusing on behavior instead of boilerplate.
-
-### Examples
-```
-let foo: Option<i32> = None;
-foo.map_or(Err("error"), |v| Ok(v));
-```
-
-Use instead:
-```
-let foo: Option<i32> = None;
-foo.ok_or("error");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_range_contains.txt b/src/tools/clippy/src/docs/manual_range_contains.txt
deleted file mode 100644
index 0ade26951..000000000
--- a/src/tools/clippy/src/docs/manual_range_contains.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for expressions like `x >= 3 && x < 8` that could
-be more readably expressed as `(3..8).contains(x)`.
-
-### Why is this bad?
-`contains` expresses the intent better and has less
-failure modes (such as fencepost errors or using `||` instead of `&&`).
-
-### Example
-```
-// given
-let x = 6;
-
-assert!(x >= 3 && x < 8);
-```
-Use instead:
-```
-assert!((3..8).contains(&x));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_rem_euclid.txt b/src/tools/clippy/src/docs/manual_rem_euclid.txt
deleted file mode 100644
index d3bb8c613..000000000
--- a/src/tools/clippy/src/docs/manual_rem_euclid.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for an expression like `((x % 4) + 4) % 4` which is a common manual reimplementation
-of `x.rem_euclid(4)`.
-
-### Why is this bad?
-It's simpler and more readable.
-
-### Example
-```
-let x: i32 = 24;
-let rem = ((x % 4) + 4) % 4;
-```
-Use instead:
-```
-let x: i32 = 24;
-let rem = x.rem_euclid(4);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_retain.txt b/src/tools/clippy/src/docs/manual_retain.txt
deleted file mode 100644
index cd4f65a93..000000000
--- a/src/tools/clippy/src/docs/manual_retain.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for code to be replaced by `.retain()`.
-### Why is this bad?
-`.retain()` is simpler and avoids needless allocation.
-### Example
-```
-let mut vec = vec![0, 1, 2];
-vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();
-vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
-```
-Use instead:
-```
-let mut vec = vec![0, 1, 2];
-vec.retain(|x| x % 2 == 0);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_saturating_arithmetic.txt b/src/tools/clippy/src/docs/manual_saturating_arithmetic.txt
deleted file mode 100644
index d9f5d3d11..000000000
--- a/src/tools/clippy/src/docs/manual_saturating_arithmetic.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`.
-
-### Why is this bad?
-These can be written simply with `saturating_add/sub` methods.
-
-### Example
-```
-let add = x.checked_add(y).unwrap_or(u32::MAX);
-let sub = x.checked_sub(y).unwrap_or(u32::MIN);
-```
-
-can be written using dedicated methods for saturating addition/subtraction as:
-
-```
-let add = x.saturating_add(y);
-let sub = x.saturating_sub(y);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_split_once.txt b/src/tools/clippy/src/docs/manual_split_once.txt
deleted file mode 100644
index 291ae447d..000000000
--- a/src/tools/clippy/src/docs/manual_split_once.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for usages of `str::splitn(2, _)`
-
-### Why is this bad?
-`split_once` is both clearer in intent and slightly more efficient.
-
-### Example
-```
-let s = "key=value=add";
-let (key, value) = s.splitn(2, '=').next_tuple()?;
-let value = s.splitn(2, '=').nth(1)?;
-
-let mut parts = s.splitn(2, '=');
-let key = parts.next()?;
-let value = parts.next()?;
-```
-
-Use instead:
-```
-let s = "key=value=add";
-let (key, value) = s.split_once('=')?;
-let value = s.split_once('=')?.1;
-
-let (key, value) = s.split_once('=')?;
-```
-
-### Limitations
-The multiple statement variant currently only detects `iter.next()?`/`iter.next().unwrap()`
-in two separate `let` statements that immediately follow the `splitn()` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_str_repeat.txt b/src/tools/clippy/src/docs/manual_str_repeat.txt
deleted file mode 100644
index 1d4a7a48e..000000000
--- a/src/tools/clippy/src/docs/manual_str_repeat.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for manual implementations of `str::repeat`
-
-### Why is this bad?
-These are both harder to read, as well as less performant.
-
-### Example
-```
-let x: String = std::iter::repeat('x').take(10).collect();
-```
-
-Use instead:
-```
-let x: String = "x".repeat(10);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_string_new.txt b/src/tools/clippy/src/docs/manual_string_new.txt
deleted file mode 100644
index 4cbc43f8f..000000000
--- a/src/tools/clippy/src/docs/manual_string_new.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-
-Checks for usage of `""` to create a `String`, such as `"".to_string()`, `"".to_owned()`,
-`String::from("")` and others.
-
-### Why is this bad?
-
-Different ways of creating an empty string makes your code less standardized, which can
-be confusing.
-
-### Example
-```
-let a = "".to_string();
-let b: String = "".into();
-```
-Use instead:
-```
-let a = String::new();
-let b = String::new();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_strip.txt b/src/tools/clippy/src/docs/manual_strip.txt
deleted file mode 100644
index f32d8e7a0..000000000
--- a/src/tools/clippy/src/docs/manual_strip.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using
-the pattern's length.
-
-### Why is this bad?
-Using `str:strip_{prefix,suffix}` is safer and may have better performance as there is no
-slicing which may panic and the compiler does not need to insert this panic code. It is
-also sometimes more readable as it removes the need for duplicating or storing the pattern
-used by `str::{starts,ends}_with` and in the slicing.
-
-### Example
-```
-let s = "hello, world!";
-if s.starts_with("hello, ") {
- assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
-}
-```
-Use instead:
-```
-let s = "hello, world!";
-if let Some(end) = s.strip_prefix("hello, ") {
- assert_eq!(end.to_uppercase(), "WORLD!");
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_swap.txt b/src/tools/clippy/src/docs/manual_swap.txt
deleted file mode 100644
index bd9526288..000000000
--- a/src/tools/clippy/src/docs/manual_swap.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for manual swapping.
-
-### Why is this bad?
-The `std::mem::swap` function exposes the intent better
-without deinitializing or copying either variable.
-
-### Example
-```
-let mut a = 42;
-let mut b = 1337;
-
-let t = b;
-b = a;
-a = t;
-```
-Use std::mem::swap():
-```
-let mut a = 1;
-let mut b = 2;
-std::mem::swap(&mut a, &mut b);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/manual_unwrap_or.txt b/src/tools/clippy/src/docs/manual_unwrap_or.txt
deleted file mode 100644
index 1fd7d831b..000000000
--- a/src/tools/clippy/src/docs/manual_unwrap_or.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Finds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`.
-
-### Why is this bad?
-Concise code helps focusing on behavior instead of boilerplate.
-
-### Example
-```
-let foo: Option<i32> = None;
-match foo {
- Some(v) => v,
- None => 1,
-};
-```
-
-Use instead:
-```
-let foo: Option<i32> = None;
-foo.unwrap_or(1);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/many_single_char_names.txt b/src/tools/clippy/src/docs/many_single_char_names.txt
deleted file mode 100644
index 55ee5da55..000000000
--- a/src/tools/clippy/src/docs/many_single_char_names.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for too many variables whose name consists of a
-single character.
-
-### Why is this bad?
-It's hard to memorize what a variable means without a
-descriptive name.
-
-### Example
-```
-let (a, b, c, d, e, f, g) = (...);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_clone.txt b/src/tools/clippy/src/docs/map_clone.txt
deleted file mode 100644
index 3ee27f072..000000000
--- a/src/tools/clippy/src/docs/map_clone.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for usage of `map(|x| x.clone())` or
-dereferencing closures for `Copy` types, on `Iterator` or `Option`,
-and suggests `cloned()` or `copied()` instead
-
-### Why is this bad?
-Readability, this can be written more concisely
-
-### Example
-```
-let x = vec![42, 43];
-let y = x.iter();
-let z = y.map(|i| *i);
-```
-
-The correct use would be:
-
-```
-let x = vec![42, 43];
-let y = x.iter();
-let z = y.cloned();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_collect_result_unit.txt b/src/tools/clippy/src/docs/map_collect_result_unit.txt
deleted file mode 100644
index 9b7206124..000000000
--- a/src/tools/clippy/src/docs/map_collect_result_unit.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for usage of `_.map(_).collect::<Result<(), _>()`.
-
-### Why is this bad?
-Using `try_for_each` instead is more readable and idiomatic.
-
-### Example
-```
-(0..3).map(|t| Err(t)).collect::<Result<(), _>>();
-```
-Use instead:
-```
-(0..3).try_for_each(|t| Err(t));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_entry.txt b/src/tools/clippy/src/docs/map_entry.txt
deleted file mode 100644
index 20dba1798..000000000
--- a/src/tools/clippy/src/docs/map_entry.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for uses of `contains_key` + `insert` on `HashMap`
-or `BTreeMap`.
-
-### Why is this bad?
-Using `entry` is more efficient.
-
-### Known problems
-The suggestion may have type inference errors in some cases. e.g.
-```
-let mut map = std::collections::HashMap::new();
-let _ = if !map.contains_key(&0) {
- map.insert(0, 0)
-} else {
- None
-};
-```
-
-### Example
-```
-if !map.contains_key(&k) {
- map.insert(k, v);
-}
-```
-Use instead:
-```
-map.entry(k).or_insert(v);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_err_ignore.txt b/src/tools/clippy/src/docs/map_err_ignore.txt
deleted file mode 100644
index 2606c13a7..000000000
--- a/src/tools/clippy/src/docs/map_err_ignore.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-### What it does
-Checks for instances of `map_err(|_| Some::Enum)`
-
-### Why is this bad?
-This `map_err` throws away the original error rather than allowing the enum to contain and report the cause of the error
-
-### Example
-Before:
-```
-use std::fmt;
-
-#[derive(Debug)]
-enum Error {
- Indivisible,
- Remainder(u8),
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Error::Indivisible => write!(f, "could not divide input by three"),
- Error::Remainder(remainder) => write!(
- f,
- "input is not divisible by three, remainder = {}",
- remainder
- ),
- }
- }
-}
-
-impl std::error::Error for Error {}
-
-fn divisible_by_3(input: &str) -> Result<(), Error> {
- input
- .parse::<i32>()
- .map_err(|_| Error::Indivisible)
- .map(|v| v % 3)
- .and_then(|remainder| {
- if remainder == 0 {
- Ok(())
- } else {
- Err(Error::Remainder(remainder as u8))
- }
- })
-}
- ```
-
- After:
- ```rust
-use std::{fmt, num::ParseIntError};
-
-#[derive(Debug)]
-enum Error {
- Indivisible(ParseIntError),
- Remainder(u8),
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Error::Indivisible(_) => write!(f, "could not divide input by three"),
- Error::Remainder(remainder) => write!(
- f,
- "input is not divisible by three, remainder = {}",
- remainder
- ),
- }
- }
-}
-
-impl std::error::Error for Error {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- match self {
- Error::Indivisible(source) => Some(source),
- _ => None,
- }
- }
-}
-
-fn divisible_by_3(input: &str) -> Result<(), Error> {
- input
- .parse::<i32>()
- .map_err(Error::Indivisible)
- .map(|v| v % 3)
- .and_then(|remainder| {
- if remainder == 0 {
- Ok(())
- } else {
- Err(Error::Remainder(remainder as u8))
- }
- })
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_flatten.txt b/src/tools/clippy/src/docs/map_flatten.txt
deleted file mode 100644
index 73c0e5140..000000000
--- a/src/tools/clippy/src/docs/map_flatten.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option`
-
-### Why is this bad?
-Readability, this can be written more concisely as
-`_.flat_map(_)` for `Iterator` or `_.and_then(_)` for `Option`
-
-### Example
-```
-let vec = vec![vec![1]];
-let opt = Some(5);
-
-vec.iter().map(|x| x.iter()).flatten();
-opt.map(|x| Some(x * 2)).flatten();
-```
-
-Use instead:
-```
-vec.iter().flat_map(|x| x.iter());
-opt.and_then(|x| Some(x * 2));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_identity.txt b/src/tools/clippy/src/docs/map_identity.txt
deleted file mode 100644
index e2e7af0be..000000000
--- a/src/tools/clippy/src/docs/map_identity.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for instances of `map(f)` where `f` is the identity function.
-
-### Why is this bad?
-It can be written more concisely without the call to `map`.
-
-### Example
-```
-let x = [1, 2, 3];
-let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect();
-```
-Use instead:
-```
-let x = [1, 2, 3];
-let y: Vec<_> = x.iter().map(|x| 2*x).collect();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/map_unwrap_or.txt b/src/tools/clippy/src/docs/map_unwrap_or.txt
deleted file mode 100644
index 485b29f01..000000000
--- a/src/tools/clippy/src/docs/map_unwrap_or.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or
-`result.map(_).unwrap_or_else(_)`.
-
-### Why is this bad?
-Readability, these can be written more concisely (resp.) as
-`option.map_or(_, _)`, `option.map_or_else(_, _)` and `result.map_or_else(_, _)`.
-
-### Known problems
-The order of the arguments is not in execution order
-
-### Examples
-```
-option.map(|a| a + 1).unwrap_or(0);
-result.map(|a| a + 1).unwrap_or_else(some_function);
-```
-
-Use instead:
-```
-option.map_or(0, |a| a + 1);
-result.map_or_else(some_function, |a| a + 1);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_as_ref.txt b/src/tools/clippy/src/docs/match_as_ref.txt
deleted file mode 100644
index 5e5f3d645..000000000
--- a/src/tools/clippy/src/docs/match_as_ref.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for match which is used to add a reference to an
-`Option` value.
-
-### Why is this bad?
-Using `as_ref()` or `as_mut()` instead is shorter.
-
-### Example
-```
-let x: Option<()> = None;
-
-let r: Option<&()> = match x {
- None => None,
- Some(ref v) => Some(v),
-};
-```
-
-Use instead:
-```
-let x: Option<()> = None;
-
-let r: Option<&()> = x.as_ref();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_bool.txt b/src/tools/clippy/src/docs/match_bool.txt
deleted file mode 100644
index 96f9e1f8b..000000000
--- a/src/tools/clippy/src/docs/match_bool.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for matches where match expression is a `bool`. It
-suggests to replace the expression with an `if...else` block.
-
-### Why is this bad?
-It makes the code less readable.
-
-### Example
-```
-let condition: bool = true;
-match condition {
- true => foo(),
- false => bar(),
-}
-```
-Use if/else instead:
-```
-let condition: bool = true;
-if condition {
- foo();
-} else {
- bar();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_like_matches_macro.txt b/src/tools/clippy/src/docs/match_like_matches_macro.txt
deleted file mode 100644
index 643e2ddc9..000000000
--- a/src/tools/clippy/src/docs/match_like_matches_macro.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks for `match` or `if let` expressions producing a
-`bool` that could be written using `matches!`
-
-### Why is this bad?
-Readability and needless complexity.
-
-### Known problems
-This lint falsely triggers, if there are arms with
-`cfg` attributes that remove an arm evaluating to `false`.
-
-### Example
-```
-let x = Some(5);
-
-let a = match x {
- Some(0) => true,
- _ => false,
-};
-
-let a = if let Some(0) = x {
- true
-} else {
- false
-};
-```
-
-Use instead:
-```
-let x = Some(5);
-let a = matches!(x, Some(0));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_on_vec_items.txt b/src/tools/clippy/src/docs/match_on_vec_items.txt
deleted file mode 100644
index 981d18d0f..000000000
--- a/src/tools/clippy/src/docs/match_on_vec_items.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for `match vec[idx]` or `match vec[n..m]`.
-
-### Why is this bad?
-This can panic at runtime.
-
-### Example
-```
-let arr = vec![0, 1, 2, 3];
-let idx = 1;
-
-match arr[idx] {
- 0 => println!("{}", 0),
- 1 => println!("{}", 3),
- _ => {},
-}
-```
-
-Use instead:
-```
-let arr = vec![0, 1, 2, 3];
-let idx = 1;
-
-match arr.get(idx) {
- Some(0) => println!("{}", 0),
- Some(1) => println!("{}", 3),
- _ => {},
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_overlapping_arm.txt b/src/tools/clippy/src/docs/match_overlapping_arm.txt
deleted file mode 100644
index 841c091bd..000000000
--- a/src/tools/clippy/src/docs/match_overlapping_arm.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for overlapping match arms.
-
-### Why is this bad?
-It is likely to be an error and if not, makes the code
-less obvious.
-
-### Example
-```
-let x = 5;
-match x {
- 1..=10 => println!("1 ... 10"),
- 5..=15 => println!("5 ... 15"),
- _ => (),
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_ref_pats.txt b/src/tools/clippy/src/docs/match_ref_pats.txt
deleted file mode 100644
index b1d902995..000000000
--- a/src/tools/clippy/src/docs/match_ref_pats.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for matches where all arms match a reference,
-suggesting to remove the reference and deref the matched expression
-instead. It also checks for `if let &foo = bar` blocks.
-
-### Why is this bad?
-It just makes the code less readable. That reference
-destructuring adds nothing to the code.
-
-### Example
-```
-match x {
- &A(ref y) => foo(y),
- &B => bar(),
- _ => frob(&x),
-}
-```
-
-Use instead:
-```
-match *x {
- A(ref y) => foo(y),
- B => bar(),
- _ => frob(x),
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_result_ok.txt b/src/tools/clippy/src/docs/match_result_ok.txt
deleted file mode 100644
index eea7c8e00..000000000
--- a/src/tools/clippy/src/docs/match_result_ok.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for unnecessary `ok()` in `while let`.
-
-### Why is this bad?
-Calling `ok()` in `while let` is unnecessary, instead match
-on `Ok(pat)`
-
-### Example
-```
-while let Some(value) = iter.next().ok() {
- vec.push(value)
-}
-
-if let Some(value) = iter.next().ok() {
- vec.push(value)
-}
-```
-Use instead:
-```
-while let Ok(value) = iter.next() {
- vec.push(value)
-}
-
-if let Ok(value) = iter.next() {
- vec.push(value)
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_same_arms.txt b/src/tools/clippy/src/docs/match_same_arms.txt
deleted file mode 100644
index 14edf1203..000000000
--- a/src/tools/clippy/src/docs/match_same_arms.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-### What it does
-Checks for `match` with identical arm bodies.
-
-### Why is this bad?
-This is probably a copy & paste error. If arm bodies
-are the same on purpose, you can factor them
-[using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns).
-
-### Known problems
-False positive possible with order dependent `match`
-(see issue
-[#860](https://github.com/rust-lang/rust-clippy/issues/860)).
-
-### Example
-```
-match foo {
- Bar => bar(),
- Quz => quz(),
- Baz => bar(), // <= oops
-}
-```
-
-This should probably be
-```
-match foo {
- Bar => bar(),
- Quz => quz(),
- Baz => baz(), // <= fixed
-}
-```
-
-or if the original code was not a typo:
-```
-match foo {
- Bar | Baz => bar(), // <= shows the intent better
- Quz => quz(),
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_single_binding.txt b/src/tools/clippy/src/docs/match_single_binding.txt
deleted file mode 100644
index 67ded0bbd..000000000
--- a/src/tools/clippy/src/docs/match_single_binding.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for useless match that binds to only one value.
-
-### Why is this bad?
-Readability and needless complexity.
-
-### Known problems
- Suggested replacements may be incorrect when `match`
-is actually binding temporary value, bringing a 'dropped while borrowed' error.
-
-### Example
-```
-match (a, b) {
- (c, d) => {
- // useless match
- }
-}
-```
-
-Use instead:
-```
-let (c, d) = (a, b);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_str_case_mismatch.txt b/src/tools/clippy/src/docs/match_str_case_mismatch.txt
deleted file mode 100644
index 19e74c208..000000000
--- a/src/tools/clippy/src/docs/match_str_case_mismatch.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for `match` expressions modifying the case of a string with non-compliant arms
-
-### Why is this bad?
-The arm is unreachable, which is likely a mistake
-
-### Example
-```
-match &*text.to_ascii_lowercase() {
- "foo" => {},
- "Bar" => {},
- _ => {},
-}
-```
-Use instead:
-```
-match &*text.to_ascii_lowercase() {
- "foo" => {},
- "bar" => {},
- _ => {},
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_wild_err_arm.txt b/src/tools/clippy/src/docs/match_wild_err_arm.txt
deleted file mode 100644
index f89b3a23a..000000000
--- a/src/tools/clippy/src/docs/match_wild_err_arm.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for arm which matches all errors with `Err(_)`
-and take drastic actions like `panic!`.
-
-### Why is this bad?
-It is generally a bad practice, similar to
-catching all exceptions in java with `catch(Exception)`
-
-### Example
-```
-let x: Result<i32, &str> = Ok(3);
-match x {
- Ok(_) => println!("ok"),
- Err(_) => panic!("err"),
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/match_wildcard_for_single_variants.txt b/src/tools/clippy/src/docs/match_wildcard_for_single_variants.txt
deleted file mode 100644
index 25559b9ec..000000000
--- a/src/tools/clippy/src/docs/match_wildcard_for_single_variants.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for wildcard enum matches for a single variant.
-
-### Why is this bad?
-New enum variants added by library updates can be missed.
-
-### Known problems
-Suggested replacements may not use correct path to enum
-if it's not present in the current scope.
-
-### Example
-```
-match x {
- Foo::A => {},
- Foo::B => {},
- _ => {},
-}
-```
-
-Use instead:
-```
-match x {
- Foo::A => {},
- Foo::B => {},
- Foo::C => {},
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/maybe_infinite_iter.txt b/src/tools/clippy/src/docs/maybe_infinite_iter.txt
deleted file mode 100644
index 1204a49b4..000000000
--- a/src/tools/clippy/src/docs/maybe_infinite_iter.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for iteration that may be infinite.
-
-### Why is this bad?
-While there may be places where this is acceptable
-(e.g., in event streams), in most cases this is simply an error.
-
-### Known problems
-The code may have a condition to stop iteration, but
-this lint is not clever enough to analyze it.
-
-### Example
-```
-let infinite_iter = 0..;
-[0..].iter().zip(infinite_iter.take_while(|x| *x > 5));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mem_forget.txt b/src/tools/clippy/src/docs/mem_forget.txt
deleted file mode 100644
index a6888c48f..000000000
--- a/src/tools/clippy/src/docs/mem_forget.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for usage of `std::mem::forget(t)` where `t` is
-`Drop`.
-
-### Why is this bad?
-`std::mem::forget(t)` prevents `t` from running its
-destructor, possibly causing leaks.
-
-### Example
-```
-mem::forget(Rc::new(55))
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mem_replace_option_with_none.txt b/src/tools/clippy/src/docs/mem_replace_option_with_none.txt
deleted file mode 100644
index 7f243d1c1..000000000
--- a/src/tools/clippy/src/docs/mem_replace_option_with_none.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for `mem::replace()` on an `Option` with
-`None`.
-
-### Why is this bad?
-`Option` already has the method `take()` for
-taking its current value (Some(..) or None) and replacing it with
-`None`.
-
-### Example
-```
-use std::mem;
-
-let mut an_option = Some(0);
-let replaced = mem::replace(&mut an_option, None);
-```
-Is better expressed with:
-```
-let mut an_option = Some(0);
-let taken = an_option.take();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mem_replace_with_default.txt b/src/tools/clippy/src/docs/mem_replace_with_default.txt
deleted file mode 100644
index 24e0913a3..000000000
--- a/src/tools/clippy/src/docs/mem_replace_with_default.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for `std::mem::replace` on a value of type
-`T` with `T::default()`.
-
-### Why is this bad?
-`std::mem` module already has the method `take` to
-take the current value and replace it with the default value of that type.
-
-### Example
-```
-let mut text = String::from("foo");
-let replaced = std::mem::replace(&mut text, String::default());
-```
-Is better expressed with:
-```
-let mut text = String::from("foo");
-let taken = std::mem::take(&mut text);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mem_replace_with_uninit.txt b/src/tools/clippy/src/docs/mem_replace_with_uninit.txt
deleted file mode 100644
index 0bb483668..000000000
--- a/src/tools/clippy/src/docs/mem_replace_with_uninit.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for `mem::replace(&mut _, mem::uninitialized())`
-and `mem::replace(&mut _, mem::zeroed())`.
-
-### Why is this bad?
-This will lead to undefined behavior even if the
-value is overwritten later, because the uninitialized value may be
-observed in the case of a panic.
-
-### Example
-```
-use std::mem;
-
-#[allow(deprecated, invalid_value)]
-fn myfunc (v: &mut Vec<i32>) {
- let taken_v = unsafe { mem::replace(v, mem::uninitialized()) };
- let new_v = may_panic(taken_v); // undefined behavior on panic
- mem::forget(mem::replace(v, new_v));
-}
-```
-
-The [take_mut](https://docs.rs/take_mut) crate offers a sound solution,
-at the cost of either lazily creating a replacement value or aborting
-on panic, to ensure that the uninitialized value cannot be observed. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/min_max.txt b/src/tools/clippy/src/docs/min_max.txt
deleted file mode 100644
index 6acf0f932..000000000
--- a/src/tools/clippy/src/docs/min_max.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for expressions where `std::cmp::min` and `max` are
-used to clamp values, but switched so that the result is constant.
-
-### Why is this bad?
-This is in all probability not the intended outcome. At
-the least it hurts readability of the code.
-
-### Example
-```
-min(0, max(100, x))
-
-// or
-
-x.max(100).min(0)
-```
-It will always be equal to `0`. Probably the author meant to clamp the value
-between 0 and 100, but has erroneously swapped `min` and `max`. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mismatched_target_os.txt b/src/tools/clippy/src/docs/mismatched_target_os.txt
deleted file mode 100644
index 51e5ec6e7..000000000
--- a/src/tools/clippy/src/docs/mismatched_target_os.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for cfg attributes having operating systems used in target family position.
-
-### Why is this bad?
-The configuration option will not be recognised and the related item will not be included
-by the conditional compilation engine.
-
-### Example
-```
-#[cfg(linux)]
-fn conditional() { }
-```
-
-Use instead:
-```
-#[cfg(target_os = "linux")]
-fn conditional() { }
-
-// or
-
-#[cfg(unix)]
-fn conditional() { }
-```
-Check the [Rust Reference](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os) for more details. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mismatching_type_param_order.txt b/src/tools/clippy/src/docs/mismatching_type_param_order.txt
deleted file mode 100644
index ffc7f32d0..000000000
--- a/src/tools/clippy/src/docs/mismatching_type_param_order.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-### What it does
-Checks for type parameters which are positioned inconsistently between
-a type definition and impl block. Specifically, a parameter in an impl
-block which has the same name as a parameter in the type def, but is in
-a different place.
-
-### Why is this bad?
-Type parameters are determined by their position rather than name.
-Naming type parameters inconsistently may cause you to refer to the
-wrong type parameter.
-
-### Limitations
-This lint only applies to impl blocks with simple generic params, e.g.
-`A`. If there is anything more complicated, such as a tuple, it will be
-ignored.
-
-### Example
-```
-struct Foo<A, B> {
- x: A,
- y: B,
-}
-// inside the impl, B refers to Foo::A
-impl<B, A> Foo<B, A> {}
-```
-Use instead:
-```
-struct Foo<A, B> {
- x: A,
- y: B,
-}
-impl<A, B> Foo<A, B> {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/misrefactored_assign_op.txt b/src/tools/clippy/src/docs/misrefactored_assign_op.txt
deleted file mode 100644
index 3d691fe41..000000000
--- a/src/tools/clippy/src/docs/misrefactored_assign_op.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for `a op= a op b` or `a op= b op a` patterns.
-
-### Why is this bad?
-Most likely these are bugs where one meant to write `a
-op= b`.
-
-### Known problems
-Clippy cannot know for sure if `a op= a op b` should have
-been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore, it suggests both.
-If `a op= a op b` is really the correct behavior it should be
-written as `a = a op a op b` as it's less confusing.
-
-### Example
-```
-let mut a = 5;
-let b = 2;
-// ...
-a += a + b;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_const_for_fn.txt b/src/tools/clippy/src/docs/missing_const_for_fn.txt
deleted file mode 100644
index 067614d4c..000000000
--- a/src/tools/clippy/src/docs/missing_const_for_fn.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-### What it does
-Suggests the use of `const` in functions and methods where possible.
-
-### Why is this bad?
-Not having the function const prevents callers of the function from being const as well.
-
-### Known problems
-Const functions are currently still being worked on, with some features only being available
-on nightly. This lint does not consider all edge cases currently and the suggestions may be
-incorrect if you are using this lint on stable.
-
-Also, the lint only runs one pass over the code. Consider these two non-const functions:
-
-```
-fn a() -> i32 {
- 0
-}
-fn b() -> i32 {
- a()
-}
-```
-
-When running Clippy, the lint will only suggest to make `a` const, because `b` at this time
-can't be const as it calls a non-const function. Making `a` const and running Clippy again,
-will suggest to make `b` const, too.
-
-### Example
-```
-fn new() -> Self {
- Self { random_number: 42 }
-}
-```
-
-Could be a const fn:
-
-```
-const fn new() -> Self {
- Self { random_number: 42 }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_docs_in_private_items.txt b/src/tools/clippy/src/docs/missing_docs_in_private_items.txt
deleted file mode 100644
index 5d37505bb..000000000
--- a/src/tools/clippy/src/docs/missing_docs_in_private_items.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-### What it does
-Warns if there is missing doc for any documentable item
-(public or private).
-
-### Why is this bad?
-Doc is good. *rustc* has a `MISSING_DOCS`
-allowed-by-default lint for
-public members, but has no way to enforce documentation of private items.
-This lint fixes that. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_enforced_import_renames.txt b/src/tools/clippy/src/docs/missing_enforced_import_renames.txt
deleted file mode 100644
index 8f4649bd5..000000000
--- a/src/tools/clippy/src/docs/missing_enforced_import_renames.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for imports that do not rename the item as specified
-in the `enforce-import-renames` config option.
-
-### Why is this bad?
-Consistency is important, if a project has defined import
-renames they should be followed. More practically, some item names are too
-vague outside of their defining scope this can enforce a more meaningful naming.
-
-### Example
-An example clippy.toml configuration:
-```
-enforced-import-renames = [ { path = "serde_json::Value", rename = "JsonValue" }]
-```
-
-```
-use serde_json::Value;
-```
-Use instead:
-```
-use serde_json::Value as JsonValue;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_errors_doc.txt b/src/tools/clippy/src/docs/missing_errors_doc.txt
deleted file mode 100644
index 028778d85..000000000
--- a/src/tools/clippy/src/docs/missing_errors_doc.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks the doc comments of publicly visible functions that
-return a `Result` type and warns if there is no `# Errors` section.
-
-### Why is this bad?
-Documenting the type of errors that can be returned from a
-function can help callers write code to handle the errors appropriately.
-
-### Examples
-Since the following function returns a `Result` it has an `# Errors` section in
-its doc comment:
-
-```
-/// # Errors
-///
-/// Will return `Err` if `filename` does not exist or the user does not have
-/// permission to read it.
-pub fn read(filename: String) -> io::Result<String> {
- unimplemented!();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_inline_in_public_items.txt b/src/tools/clippy/src/docs/missing_inline_in_public_items.txt
deleted file mode 100644
index d90c50fe7..000000000
--- a/src/tools/clippy/src/docs/missing_inline_in_public_items.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-### What it does
-It lints if an exported function, method, trait method with default impl,
-or trait method impl is not `#[inline]`.
-
-### Why is this bad?
-In general, it is not. Functions can be inlined across
-crates when that's profitable as long as any form of LTO is used. When LTO is disabled,
-functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates
-might intend for most of the methods in their public API to be able to be inlined across
-crates even when LTO is disabled. For these types of crates, enabling this lint might make
-sense. It allows the crate to require all exported methods to be `#[inline]` by default, and
-then opt out for specific methods where this might not make sense.
-
-### Example
-```
-pub fn foo() {} // missing #[inline]
-fn ok() {} // ok
-#[inline] pub fn bar() {} // ok
-#[inline(always)] pub fn baz() {} // ok
-
-pub trait Bar {
- fn bar(); // ok
- fn def_bar() {} // missing #[inline]
-}
-
-struct Baz;
-impl Baz {
- fn private() {} // ok
-}
-
-impl Bar for Baz {
- fn bar() {} // ok - Baz is not exported
-}
-
-pub struct PubBaz;
-impl PubBaz {
- fn private() {} // ok
- pub fn not_private() {} // missing #[inline]
-}
-
-impl Bar for PubBaz {
- fn bar() {} // missing #[inline]
- fn def_bar() {} // missing #[inline]
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_panics_doc.txt b/src/tools/clippy/src/docs/missing_panics_doc.txt
deleted file mode 100644
index e5e39a824..000000000
--- a/src/tools/clippy/src/docs/missing_panics_doc.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks the doc comments of publicly visible functions that
-may panic and warns if there is no `# Panics` section.
-
-### Why is this bad?
-Documenting the scenarios in which panicking occurs
-can help callers who do not want to panic to avoid those situations.
-
-### Examples
-Since the following function may panic it has a `# Panics` section in
-its doc comment:
-
-```
-/// # Panics
-///
-/// Will panic if y is 0
-pub fn divide_by(x: i32, y: i32) -> i32 {
- if y == 0 {
- panic!("Cannot divide by 0")
- } else {
- x / y
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_safety_doc.txt b/src/tools/clippy/src/docs/missing_safety_doc.txt
deleted file mode 100644
index 6492eb84f..000000000
--- a/src/tools/clippy/src/docs/missing_safety_doc.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for the doc comments of publicly visible
-unsafe functions and warns if there is no `# Safety` section.
-
-### Why is this bad?
-Unsafe functions should document their safety
-preconditions, so that users can be sure they are using them safely.
-
-### Examples
-```
-/// This function should really be documented
-pub unsafe fn start_apocalypse(u: &mut Universe) {
- unimplemented!();
-}
-```
-
-At least write a line about safety:
-
-```
-/// # Safety
-///
-/// This function should not be called before the horsemen are ready.
-pub unsafe fn start_apocalypse(u: &mut Universe) {
- unimplemented!();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_spin_loop.txt b/src/tools/clippy/src/docs/missing_spin_loop.txt
deleted file mode 100644
index 3a06a91d7..000000000
--- a/src/tools/clippy/src/docs/missing_spin_loop.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Check for empty spin loops
-
-### Why is this bad?
-The loop body should have something like `thread::park()` or at least
-`std::hint::spin_loop()` to avoid needlessly burning cycles and conserve
-energy. Perhaps even better use an actual lock, if possible.
-
-### Known problems
-This lint doesn't currently trigger on `while let` or
-`loop { match .. { .. } }` loops, which would be considered idiomatic in
-combination with e.g. `AtomicBool::compare_exchange_weak`.
-
-### Example
-
-```
-use core::sync::atomic::{AtomicBool, Ordering};
-let b = AtomicBool::new(true);
-// give a ref to `b` to another thread,wait for it to become false
-while b.load(Ordering::Acquire) {};
-```
-Use instead:
-```
-while b.load(Ordering::Acquire) {
- std::hint::spin_loop()
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/missing_trait_methods.txt b/src/tools/clippy/src/docs/missing_trait_methods.txt
deleted file mode 100644
index 788ad764f..000000000
--- a/src/tools/clippy/src/docs/missing_trait_methods.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-### What it does
-Checks if a provided method is used implicitly by a trait
-implementation. A usage example would be a wrapper where every method
-should perform some operation before delegating to the inner type's
-implemenation.
-
-This lint should typically be enabled on a specific trait `impl` item
-rather than globally.
-
-### Why is this bad?
-Indicates that a method is missing.
-
-### Example
-```
-trait Trait {
- fn required();
-
- fn provided() {}
-}
-
-#[warn(clippy::missing_trait_methods)]
-impl Trait for Type {
- fn required() { /* ... */ }
-}
-```
-Use instead:
-```
-trait Trait {
- fn required();
-
- fn provided() {}
-}
-
-#[warn(clippy::missing_trait_methods)]
-impl Trait for Type {
- fn required() { /* ... */ }
-
- fn provided() { /* ... */ }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mistyped_literal_suffixes.txt b/src/tools/clippy/src/docs/mistyped_literal_suffixes.txt
deleted file mode 100644
index 1760fcbfe..000000000
--- a/src/tools/clippy/src/docs/mistyped_literal_suffixes.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Warns for mistyped suffix in literals
-
-### Why is this bad?
-This is most probably a typo
-
-### Known problems
-- Does not match on integers too large to fit in the corresponding unsigned type
-- Does not match on `_127` since that is a valid grouping for decimal and octal numbers
-
-### Example
-```
-`2_32` => `2_i32`
-`250_8 => `250_u8`
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mixed_case_hex_literals.txt b/src/tools/clippy/src/docs/mixed_case_hex_literals.txt
deleted file mode 100644
index d2d01e0c9..000000000
--- a/src/tools/clippy/src/docs/mixed_case_hex_literals.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Warns on hexadecimal literals with mixed-case letter
-digits.
-
-### Why is this bad?
-It looks confusing.
-
-### Example
-```
-0x1a9BAcD
-```
-
-Use instead:
-```
-0x1A9BACD
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mixed_read_write_in_expression.txt b/src/tools/clippy/src/docs/mixed_read_write_in_expression.txt
deleted file mode 100644
index 02d1c5d05..000000000
--- a/src/tools/clippy/src/docs/mixed_read_write_in_expression.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks for a read and a write to the same variable where
-whether the read occurs before or after the write depends on the evaluation
-order of sub-expressions.
-
-### Why is this bad?
-It is often confusing to read. As described [here](https://doc.rust-lang.org/reference/expressions.html?highlight=subexpression#evaluation-order-of-operands),
-the operands of these expressions are evaluated before applying the effects of the expression.
-
-### Known problems
-Code which intentionally depends on the evaluation
-order, or which is correct for any evaluation order.
-
-### Example
-```
-let mut x = 0;
-
-let a = {
- x = 1;
- 1
-} + x;
-// Unclear whether a is 1 or 2.
-```
-
-Use instead:
-```
-let tmp = {
- x = 1;
- 1
-};
-let a = tmp + x;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mod_module_files.txt b/src/tools/clippy/src/docs/mod_module_files.txt
deleted file mode 100644
index 95bca583a..000000000
--- a/src/tools/clippy/src/docs/mod_module_files.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks that module layout uses only self named module files, bans `mod.rs` files.
-
-### Why is this bad?
-Having multiple module layout styles in a project can be confusing.
-
-### Example
-```
-src/
- stuff/
- stuff_files.rs
- mod.rs
- lib.rs
-```
-Use instead:
-```
-src/
- stuff/
- stuff_files.rs
- stuff.rs
- lib.rs
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/module_inception.txt b/src/tools/clippy/src/docs/module_inception.txt
deleted file mode 100644
index d80a1b8d8..000000000
--- a/src/tools/clippy/src/docs/module_inception.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for modules that have the same name as their
-parent module
-
-### Why is this bad?
-A typical beginner mistake is to have `mod foo;` and
-again `mod foo { ..
-}` in `foo.rs`.
-The expectation is that items inside the inner `mod foo { .. }` are then
-available
-through `foo::x`, but they are only available through
-`foo::foo::x`.
-If this is done on purpose, it would be better to choose a more
-representative module name.
-
-### Example
-```
-// lib.rs
-mod foo;
-// foo.rs
-mod foo {
- ...
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/module_name_repetitions.txt b/src/tools/clippy/src/docs/module_name_repetitions.txt
deleted file mode 100644
index 3bc05d027..000000000
--- a/src/tools/clippy/src/docs/module_name_repetitions.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Detects type names that are prefixed or suffixed by the
-containing module's name.
-
-### Why is this bad?
-It requires the user to type the module name twice.
-
-### Example
-```
-mod cake {
- struct BlackForestCake;
-}
-```
-
-Use instead:
-```
-mod cake {
- struct BlackForest;
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/modulo_arithmetic.txt b/src/tools/clippy/src/docs/modulo_arithmetic.txt
deleted file mode 100644
index ff7296f3c..000000000
--- a/src/tools/clippy/src/docs/modulo_arithmetic.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for modulo arithmetic.
-
-### Why is this bad?
-The results of modulo (%) operation might differ
-depending on the language, when negative numbers are involved.
-If you interop with different languages it might be beneficial
-to double check all places that use modulo arithmetic.
-
-For example, in Rust `17 % -3 = 2`, but in Python `17 % -3 = -1`.
-
-### Example
-```
-let x = -17 % 3;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/modulo_one.txt b/src/tools/clippy/src/docs/modulo_one.txt
deleted file mode 100644
index bc8f95b0b..000000000
--- a/src/tools/clippy/src/docs/modulo_one.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for getting the remainder of a division by one or minus
-one.
-
-### Why is this bad?
-The result for a divisor of one can only ever be zero; for
-minus one it can cause panic/overflow (if the left operand is the minimal value of
-the respective integer type) or results in zero. No one will write such code
-deliberately, unless trying to win an Underhanded Rust Contest. Even for that
-contest, it's probably a bad idea. Use something more underhanded.
-
-### Example
-```
-let a = x % 1;
-let a = x % -1;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/multi_assignments.txt b/src/tools/clippy/src/docs/multi_assignments.txt
deleted file mode 100644
index ed1f1b420..000000000
--- a/src/tools/clippy/src/docs/multi_assignments.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for nested assignments.
-
-### Why is this bad?
-While this is in most cases already a type mismatch,
-the result of an assignment being `()` can throw off people coming from languages like python or C,
-where such assignments return a copy of the assigned value.
-
-### Example
-```
-a = b = 42;
-```
-Use instead:
-```
-b = 42;
-a = b;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/multiple_crate_versions.txt b/src/tools/clippy/src/docs/multiple_crate_versions.txt
deleted file mode 100644
index cf2d2c6ab..000000000
--- a/src/tools/clippy/src/docs/multiple_crate_versions.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks to see if multiple versions of a crate are being
-used.
-
-### Why is this bad?
-This bloats the size of targets, and can lead to
-confusing error messages when structs or traits are used interchangeably
-between different versions of a crate.
-
-### Known problems
-Because this can be caused purely by the dependencies
-themselves, it's not always possible to fix this issue.
-
-### Example
-```
-[dependencies]
-ctrlc = "=3.1.0"
-ansi_term = "=0.11.0"
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/multiple_inherent_impl.txt b/src/tools/clippy/src/docs/multiple_inherent_impl.txt
deleted file mode 100644
index 9d4228656..000000000
--- a/src/tools/clippy/src/docs/multiple_inherent_impl.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for multiple inherent implementations of a struct
-
-### Why is this bad?
-Splitting the implementation of a type makes the code harder to navigate.
-
-### Example
-```
-struct X;
-impl X {
- fn one() {}
-}
-impl X {
- fn other() {}
-}
-```
-
-Could be written:
-
-```
-struct X;
-impl X {
- fn one() {}
- fn other() {}
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/must_use_candidate.txt b/src/tools/clippy/src/docs/must_use_candidate.txt
deleted file mode 100644
index 70890346f..000000000
--- a/src/tools/clippy/src/docs/must_use_candidate.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for public functions that have no
-`#[must_use]` attribute, but return something not already marked
-must-use, have no mutable arg and mutate no statics.
-
-### Why is this bad?
-Not bad at all, this lint just shows places where
-you could add the attribute.
-
-### Known problems
-The lint only checks the arguments for mutable
-types without looking if they are actually changed. On the other hand,
-it also ignores a broad range of potentially interesting side effects,
-because we cannot decide whether the programmer intends the function to
-be called for the side effect or the result. Expect many false
-positives. At least we don't lint if the result type is unit or already
-`#[must_use]`.
-
-### Examples
-```
-// this could be annotated with `#[must_use]`.
-fn id<T>(t: T) -> T { t }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/must_use_unit.txt b/src/tools/clippy/src/docs/must_use_unit.txt
deleted file mode 100644
index cabbb23f8..000000000
--- a/src/tools/clippy/src/docs/must_use_unit.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for a `#[must_use]` attribute on
-unit-returning functions and methods.
-
-### Why is this bad?
-Unit values are useless. The attribute is likely
-a remnant of a refactoring that removed the return type.
-
-### Examples
-```
-#[must_use]
-fn useless() { }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mut_from_ref.txt b/src/tools/clippy/src/docs/mut_from_ref.txt
deleted file mode 100644
index cc1da1254..000000000
--- a/src/tools/clippy/src/docs/mut_from_ref.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-This lint checks for functions that take immutable references and return
-mutable ones. This will not trigger if no unsafe code exists as there
-are multiple safe functions which will do this transformation
-
-To be on the conservative side, if there's at least one mutable
-reference with the output lifetime, this lint will not trigger.
-
-### Why is this bad?
-Creating a mutable reference which can be repeatably derived from an
-immutable reference is unsound as it allows creating multiple live
-mutable references to the same object.
-
-This [error](https://github.com/rust-lang/rust/issues/39465) actually
-lead to an interim Rust release 1.15.1.
-
-### Known problems
-This pattern is used by memory allocators to allow allocating multiple
-objects while returning mutable references to each one. So long as
-different mutable references are returned each time such a function may
-be safe.
-
-### Example
-```
-fn foo(&Foo) -> &mut Bar { .. }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mut_mut.txt b/src/tools/clippy/src/docs/mut_mut.txt
deleted file mode 100644
index 0bd34dd24..000000000
--- a/src/tools/clippy/src/docs/mut_mut.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for instances of `mut mut` references.
-
-### Why is this bad?
-Multiple `mut`s don't add anything meaningful to the
-source. This is either a copy'n'paste error, or it shows a fundamental
-misunderstanding of references.
-
-### Example
-```
-let x = &mut &mut y;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mut_mutex_lock.txt b/src/tools/clippy/src/docs/mut_mutex_lock.txt
deleted file mode 100644
index 5e9ad8a3f..000000000
--- a/src/tools/clippy/src/docs/mut_mutex_lock.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for `&mut Mutex::lock` calls
-
-### Why is this bad?
-`Mutex::lock` is less efficient than
-calling `Mutex::get_mut`. In addition you also have a statically
-guarantee that the mutex isn't locked, instead of just a runtime
-guarantee.
-
-### Example
-```
-use std::sync::{Arc, Mutex};
-
-let mut value_rc = Arc::new(Mutex::new(42_u8));
-let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
-
-let mut value = value_mutex.lock().unwrap();
-*value += 1;
-```
-Use instead:
-```
-use std::sync::{Arc, Mutex};
-
-let mut value_rc = Arc::new(Mutex::new(42_u8));
-let value_mutex = Arc::get_mut(&mut value_rc).unwrap();
-
-let value = value_mutex.get_mut().unwrap();
-*value += 1;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mut_range_bound.txt b/src/tools/clippy/src/docs/mut_range_bound.txt
deleted file mode 100644
index e9c38a543..000000000
--- a/src/tools/clippy/src/docs/mut_range_bound.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for loops which have a range bound that is a mutable variable
-
-### Why is this bad?
-One might think that modifying the mutable variable changes the loop bounds
-
-### Known problems
-False positive when mutation is followed by a `break`, but the `break` is not immediately
-after the mutation:
-
-```
-let mut x = 5;
-for _ in 0..x {
- x += 1; // x is a range bound that is mutated
- ..; // some other expression
- break; // leaves the loop, so mutation is not an issue
-}
-```
-
-False positive on nested loops ([#6072](https://github.com/rust-lang/rust-clippy/issues/6072))
-
-### Example
-```
-let mut foo = 42;
-for i in 0..foo {
- foo -= 1;
- println!("{}", i); // prints numbers from 0 to 42, not 0 to 21
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mutable_key_type.txt b/src/tools/clippy/src/docs/mutable_key_type.txt
deleted file mode 100644
index 15fe34f2b..000000000
--- a/src/tools/clippy/src/docs/mutable_key_type.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-### What it does
-Checks for sets/maps with mutable key types.
-
-### Why is this bad?
-All of `HashMap`, `HashSet`, `BTreeMap` and
-`BtreeSet` rely on either the hash or the order of keys be unchanging,
-so having types with interior mutability is a bad idea.
-
-### Known problems
-
-#### False Positives
-It's correct to use a struct that contains interior mutability as a key, when its
-implementation of `Hash` or `Ord` doesn't access any of the interior mutable types.
-However, this lint is unable to recognize this, so it will often cause false positives in
-theses cases. The `bytes` crate is a great example of this.
-
-#### False Negatives
-For custom `struct`s/`enum`s, this lint is unable to check for interior mutability behind
-indirection. For example, `struct BadKey<'a>(&'a Cell<usize>)` will be seen as immutable
-and cause a false negative if its implementation of `Hash`/`Ord` accesses the `Cell`.
-
-This lint does check a few cases for indirection. Firstly, using some standard library
-types (`Option`, `Result`, `Box`, `Rc`, `Arc`, `Vec`, `VecDeque`, `BTreeMap` and
-`BTreeSet`) directly as keys (e.g. in `HashMap<Box<Cell<usize>>, ()>`) **will** trigger the
-lint, because the impls of `Hash`/`Ord` for these types directly call `Hash`/`Ord` on their
-contained type.
-
-Secondly, the implementations of `Hash` and `Ord` for raw pointers (`*const T` or `*mut T`)
-apply only to the **address** of the contained value. Therefore, interior mutability
-behind raw pointers (e.g. in `HashSet<*mut Cell<usize>>`) can't impact the value of `Hash`
-or `Ord`, and therefore will not trigger this link. For more info, see issue
-[#6745](https://github.com/rust-lang/rust-clippy/issues/6745).
-
-### Example
-```
-use std::cmp::{PartialEq, Eq};
-use std::collections::HashSet;
-use std::hash::{Hash, Hasher};
-use std::sync::atomic::AtomicUsize;
-
-struct Bad(AtomicUsize);
-impl PartialEq for Bad {
- fn eq(&self, rhs: &Self) -> bool {
- ..
-; unimplemented!();
- }
-}
-
-impl Eq for Bad {}
-
-impl Hash for Bad {
- fn hash<H: Hasher>(&self, h: &mut H) {
- ..
-; unimplemented!();
- }
-}
-
-fn main() {
- let _: HashSet<Bad> = HashSet::new();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mutex_atomic.txt b/src/tools/clippy/src/docs/mutex_atomic.txt
deleted file mode 100644
index 062ac8b32..000000000
--- a/src/tools/clippy/src/docs/mutex_atomic.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for usages of `Mutex<X>` where an atomic will do.
-
-### Why is this bad?
-Using a mutex just to make access to a plain bool or
-reference sequential is shooting flies with cannons.
-`std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and
-faster.
-
-### Known problems
-This lint cannot detect if the mutex is actually used
-for waiting before a critical section.
-
-### Example
-```
-let x = Mutex::new(&y);
-```
-
-Use instead:
-```
-let x = AtomicBool::new(y);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/mutex_integer.txt b/src/tools/clippy/src/docs/mutex_integer.txt
deleted file mode 100644
index f9dbdfb90..000000000
--- a/src/tools/clippy/src/docs/mutex_integer.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for usages of `Mutex<X>` where `X` is an integral
-type.
-
-### Why is this bad?
-Using a mutex just to make access to a plain integer
-sequential is
-shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster.
-
-### Known problems
-This lint cannot detect if the mutex is actually used
-for waiting before a critical section.
-
-### Example
-```
-let x = Mutex::new(0usize);
-```
-
-Use instead:
-```
-let x = AtomicUsize::new(0usize);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/naive_bytecount.txt b/src/tools/clippy/src/docs/naive_bytecount.txt
deleted file mode 100644
index 24659dc79..000000000
--- a/src/tools/clippy/src/docs/naive_bytecount.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for naive byte counts
-
-### Why is this bad?
-The [`bytecount`](https://crates.io/crates/bytecount)
-crate has methods to count your bytes faster, especially for large slices.
-
-### Known problems
-If you have predominantly small slices, the
-`bytecount::count(..)` method may actually be slower. However, if you can
-ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be
-faster in those cases.
-
-### Example
-```
-let count = vec.iter().filter(|x| **x == 0u8).count();
-```
-
-Use instead:
-```
-let count = bytecount::count(&vec, 0u8);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_arbitrary_self_type.txt b/src/tools/clippy/src/docs/needless_arbitrary_self_type.txt
deleted file mode 100644
index 8216a3a3f..000000000
--- a/src/tools/clippy/src/docs/needless_arbitrary_self_type.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-### What it does
-The lint checks for `self` in fn parameters that
-specify the `Self`-type explicitly
-### Why is this bad?
-Increases the amount and decreases the readability of code
-
-### Example
-```
-enum ValType {
- I32,
- I64,
- F32,
- F64,
-}
-
-impl ValType {
- pub fn bytes(self: Self) -> usize {
- match self {
- Self::I32 | Self::F32 => 4,
- Self::I64 | Self::F64 => 8,
- }
- }
-}
-```
-
-Could be rewritten as
-
-```
-enum ValType {
- I32,
- I64,
- F32,
- F64,
-}
-
-impl ValType {
- pub fn bytes(self) -> usize {
- match self {
- Self::I32 | Self::F32 => 4,
- Self::I64 | Self::F64 => 8,
- }
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_bitwise_bool.txt b/src/tools/clippy/src/docs/needless_bitwise_bool.txt
deleted file mode 100644
index fcd7b730a..000000000
--- a/src/tools/clippy/src/docs/needless_bitwise_bool.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for uses of bitwise and/or operators between booleans, where performance may be improved by using
-a lazy and.
-
-### Why is this bad?
-The bitwise operators do not support short-circuiting, so it may hinder code performance.
-Additionally, boolean logic "masked" as bitwise logic is not caught by lints like `unnecessary_fold`
-
-### Known problems
-This lint evaluates only when the right side is determined to have no side effects. At this time, that
-determination is quite conservative.
-
-### Example
-```
-let (x,y) = (true, false);
-if x & !y {} // where both x and y are booleans
-```
-Use instead:
-```
-let (x,y) = (true, false);
-if x && !y {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_bool.txt b/src/tools/clippy/src/docs/needless_bool.txt
deleted file mode 100644
index b5c78871f..000000000
--- a/src/tools/clippy/src/docs/needless_bool.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for expressions of the form `if c { true } else {
-false }` (or vice versa) and suggests using the condition directly.
-
-### Why is this bad?
-Redundant code.
-
-### Known problems
-Maybe false positives: Sometimes, the two branches are
-painstakingly documented (which we, of course, do not detect), so they *may*
-have some value. Even then, the documentation can be rewritten to match the
-shorter code.
-
-### Example
-```
-if x {
- false
-} else {
- true
-}
-```
-
-Use instead:
-```
-!x
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_borrow.txt b/src/tools/clippy/src/docs/needless_borrow.txt
deleted file mode 100644
index 4debcf473..000000000
--- a/src/tools/clippy/src/docs/needless_borrow.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for address of operations (`&`) that are going to
-be dereferenced immediately by the compiler.
-
-### Why is this bad?
-Suggests that the receiver of the expression borrows
-the expression.
-
-### Example
-```
-fn fun(_a: &i32) {}
-
-let x: &i32 = &&&&&&5;
-fun(&x);
-```
-
-Use instead:
-```
-let x: &i32 = &5;
-fun(x);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_borrowed_reference.txt b/src/tools/clippy/src/docs/needless_borrowed_reference.txt
deleted file mode 100644
index 152459ba1..000000000
--- a/src/tools/clippy/src/docs/needless_borrowed_reference.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for bindings that needlessly destructure a reference and borrow the inner
-value with `&ref`.
-
-### Why is this bad?
-This pattern has no effect in almost all cases.
-
-### Example
-```
-let mut v = Vec::<String>::new();
-v.iter_mut().filter(|&ref a| a.is_empty());
-
-if let &[ref first, ref second] = v.as_slice() {}
-```
-
-Use instead:
-```
-let mut v = Vec::<String>::new();
-v.iter_mut().filter(|a| a.is_empty());
-
-if let [first, second] = v.as_slice() {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_collect.txt b/src/tools/clippy/src/docs/needless_collect.txt
deleted file mode 100644
index 275c39afc..000000000
--- a/src/tools/clippy/src/docs/needless_collect.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for functions collecting an iterator when collect
-is not needed.
-
-### Why is this bad?
-`collect` causes the allocation of a new data structure,
-when this allocation may not be needed.
-
-### Example
-```
-let len = iterator.clone().collect::<Vec<_>>().len();
-// should be
-let len = iterator.count();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_continue.txt b/src/tools/clippy/src/docs/needless_continue.txt
deleted file mode 100644
index 2cee621c1..000000000
--- a/src/tools/clippy/src/docs/needless_continue.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-### What it does
-The lint checks for `if`-statements appearing in loops
-that contain a `continue` statement in either their main blocks or their
-`else`-blocks, when omitting the `else`-block possibly with some
-rearrangement of code can make the code easier to understand.
-
-### Why is this bad?
-Having explicit `else` blocks for `if` statements
-containing `continue` in their THEN branch adds unnecessary branching and
-nesting to the code. Having an else block containing just `continue` can
-also be better written by grouping the statements following the whole `if`
-statement within the THEN block and omitting the else block completely.
-
-### Example
-```
-while condition() {
- update_condition();
- if x {
- // ...
- } else {
- continue;
- }
- println!("Hello, world");
-}
-```
-
-Could be rewritten as
-
-```
-while condition() {
- update_condition();
- if x {
- // ...
- println!("Hello, world");
- }
-}
-```
-
-As another example, the following code
-
-```
-loop {
- if waiting() {
- continue;
- } else {
- // Do something useful
- }
- # break;
-}
-```
-Could be rewritten as
-
-```
-loop {
- if waiting() {
- continue;
- }
- // Do something useful
- # break;
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_doctest_main.txt b/src/tools/clippy/src/docs/needless_doctest_main.txt
deleted file mode 100644
index 8f91a7baa..000000000
--- a/src/tools/clippy/src/docs/needless_doctest_main.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for `fn main() { .. }` in doctests
-
-### Why is this bad?
-The test can be shorter (and likely more readable)
-if the `fn main()` is left implicit.
-
-### Examples
-```
-/// An example of a doctest with a `main()` function
-///
-/// # Examples
-///
-/// ```
-/// fn main() {
-/// // this needs not be in an `fn`
-/// }
-/// ```
-fn needless_main() {
- unimplemented!();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_for_each.txt b/src/tools/clippy/src/docs/needless_for_each.txt
deleted file mode 100644
index 9ae6dd360..000000000
--- a/src/tools/clippy/src/docs/needless_for_each.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for usage of `for_each` that would be more simply written as a
-`for` loop.
-
-### Why is this bad?
-`for_each` may be used after applying iterator transformers like
-`filter` for better readability and performance. It may also be used to fit a simple
-operation on one line.
-But when none of these apply, a simple `for` loop is more idiomatic.
-
-### Example
-```
-let v = vec![0, 1, 2];
-v.iter().for_each(|elem| {
- println!("{}", elem);
-})
-```
-Use instead:
-```
-let v = vec![0, 1, 2];
-for elem in v.iter() {
- println!("{}", elem);
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_late_init.txt b/src/tools/clippy/src/docs/needless_late_init.txt
deleted file mode 100644
index 9e7bbcea9..000000000
--- a/src/tools/clippy/src/docs/needless_late_init.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-### What it does
-Checks for late initializations that can be replaced by a `let` statement
-with an initializer.
-
-### Why is this bad?
-Assigning in the `let` statement is less repetitive.
-
-### Example
-```
-let a;
-a = 1;
-
-let b;
-match 3 {
- 0 => b = "zero",
- 1 => b = "one",
- _ => b = "many",
-}
-
-let c;
-if true {
- c = 1;
-} else {
- c = -1;
-}
-```
-Use instead:
-```
-let a = 1;
-
-let b = match 3 {
- 0 => "zero",
- 1 => "one",
- _ => "many",
-};
-
-let c = if true {
- 1
-} else {
- -1
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_lifetimes.txt b/src/tools/clippy/src/docs/needless_lifetimes.txt
deleted file mode 100644
index b280caa66..000000000
--- a/src/tools/clippy/src/docs/needless_lifetimes.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for lifetime annotations which can be removed by
-relying on lifetime elision.
-
-### Why is this bad?
-The additional lifetimes make the code look more
-complicated, while there is nothing out of the ordinary going on. Removing
-them leads to more readable code.
-
-### Known problems
-- We bail out if the function has a `where` clause where lifetimes
-are mentioned due to potential false positives.
-- Lifetime bounds such as `impl Foo + 'a` and `T: 'a` must be elided with the
-placeholder notation `'_` because the fully elided notation leaves the type bound to `'static`.
-
-### Example
-```
-// Unnecessary lifetime annotations
-fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 {
- x
-}
-```
-
-Use instead:
-```
-fn elided(x: &u8, y: u8) -> &u8 {
- x
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_match.txt b/src/tools/clippy/src/docs/needless_match.txt
deleted file mode 100644
index 92b40a5df..000000000
--- a/src/tools/clippy/src/docs/needless_match.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-### What it does
-Checks for unnecessary `match` or match-like `if let` returns for `Option` and `Result`
-when function signatures are the same.
-
-### Why is this bad?
-This `match` block does nothing and might not be what the coder intended.
-
-### Example
-```
-fn foo() -> Result<(), i32> {
- match result {
- Ok(val) => Ok(val),
- Err(err) => Err(err),
- }
-}
-
-fn bar() -> Option<i32> {
- if let Some(val) = option {
- Some(val)
- } else {
- None
- }
-}
-```
-
-Could be replaced as
-
-```
-fn foo() -> Result<(), i32> {
- result
-}
-
-fn bar() -> Option<i32> {
- option
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_option_as_deref.txt b/src/tools/clippy/src/docs/needless_option_as_deref.txt
deleted file mode 100644
index 226396c97..000000000
--- a/src/tools/clippy/src/docs/needless_option_as_deref.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for no-op uses of `Option::{as_deref, as_deref_mut}`,
-for example, `Option<&T>::as_deref()` returns the same type.
-
-### Why is this bad?
-Redundant code and improving readability.
-
-### Example
-```
-let a = Some(&1);
-let b = a.as_deref(); // goes from Option<&i32> to Option<&i32>
-```
-
-Use instead:
-```
-let a = Some(&1);
-let b = a;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_option_take.txt b/src/tools/clippy/src/docs/needless_option_take.txt
deleted file mode 100644
index 6bac65a13..000000000
--- a/src/tools/clippy/src/docs/needless_option_take.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for calling `take` function after `as_ref`.
-
-### Why is this bad?
-Redundant code. `take` writes `None` to its argument.
-In this case the modification is useless as it's a temporary that cannot be read from afterwards.
-
-### Example
-```
-let x = Some(3);
-x.as_ref().take();
-```
-Use instead:
-```
-let x = Some(3);
-x.as_ref();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_parens_on_range_literals.txt b/src/tools/clippy/src/docs/needless_parens_on_range_literals.txt
deleted file mode 100644
index 85fab10cb..000000000
--- a/src/tools/clippy/src/docs/needless_parens_on_range_literals.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-The lint checks for parenthesis on literals in range statements that are
-superfluous.
-
-### Why is this bad?
-Having superfluous parenthesis makes the code less readable
-overhead when reading.
-
-### Example
-
-```
-for i in (0)..10 {
- println!("{i}");
-}
-```
-
-Use instead:
-
-```
-for i in 0..10 {
- println!("{i}");
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_pass_by_value.txt b/src/tools/clippy/src/docs/needless_pass_by_value.txt
deleted file mode 100644
index 58c420b19..000000000
--- a/src/tools/clippy/src/docs/needless_pass_by_value.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for functions taking arguments by value, but not
-consuming them in its
-body.
-
-### Why is this bad?
-Taking arguments by reference is more flexible and can
-sometimes avoid
-unnecessary allocations.
-
-### Known problems
-* This lint suggests taking an argument by reference,
-however sometimes it is better to let users decide the argument type
-(by using `Borrow` trait, for example), depending on how the function is used.
-
-### Example
-```
-fn foo(v: Vec<i32>) {
- assert_eq!(v.len(), 42);
-}
-```
-should be
-```
-fn foo(v: &[i32]) {
- assert_eq!(v.len(), 42);
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_question_mark.txt b/src/tools/clippy/src/docs/needless_question_mark.txt
deleted file mode 100644
index 540739fd4..000000000
--- a/src/tools/clippy/src/docs/needless_question_mark.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-### What it does
-Suggests alternatives for useless applications of `?` in terminating expressions
-
-### Why is this bad?
-There's no reason to use `?` to short-circuit when execution of the body will end there anyway.
-
-### Example
-```
-struct TO {
- magic: Option<usize>,
-}
-
-fn f(to: TO) -> Option<usize> {
- Some(to.magic?)
-}
-
-struct TR {
- magic: Result<usize, bool>,
-}
-
-fn g(tr: Result<TR, bool>) -> Result<usize, bool> {
- tr.and_then(|t| Ok(t.magic?))
-}
-
-```
-Use instead:
-```
-struct TO {
- magic: Option<usize>,
-}
-
-fn f(to: TO) -> Option<usize> {
- to.magic
-}
-
-struct TR {
- magic: Result<usize, bool>,
-}
-
-fn g(tr: Result<TR, bool>) -> Result<usize, bool> {
- tr.and_then(|t| t.magic)
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_range_loop.txt b/src/tools/clippy/src/docs/needless_range_loop.txt
deleted file mode 100644
index 583c09b28..000000000
--- a/src/tools/clippy/src/docs/needless_range_loop.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for looping over the range of `0..len` of some
-collection just to get the values by index.
-
-### Why is this bad?
-Just iterating the collection itself makes the intent
-more clear and is probably faster.
-
-### Example
-```
-let vec = vec!['a', 'b', 'c'];
-for i in 0..vec.len() {
- println!("{}", vec[i]);
-}
-```
-
-Use instead:
-```
-let vec = vec!['a', 'b', 'c'];
-for i in vec {
- println!("{}", i);
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_return.txt b/src/tools/clippy/src/docs/needless_return.txt
deleted file mode 100644
index 48782cb0c..000000000
--- a/src/tools/clippy/src/docs/needless_return.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for return statements at the end of a block.
-
-### Why is this bad?
-Removing the `return` and semicolon will make the code
-more rusty.
-
-### Example
-```
-fn foo(x: usize) -> usize {
- return x;
-}
-```
-simplify to
-```
-fn foo(x: usize) -> usize {
- x
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_splitn.txt b/src/tools/clippy/src/docs/needless_splitn.txt
deleted file mode 100644
index b10a84fbc..000000000
--- a/src/tools/clippy/src/docs/needless_splitn.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usages of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same.
-### Why is this bad?
-The function `split` is simpler and there is no performance difference in these cases, considering
-that both functions return a lazy iterator.
-### Example
-```
-let str = "key=value=add";
-let _ = str.splitn(3, '=').next().unwrap();
-```
-
-Use instead:
-```
-let str = "key=value=add";
-let _ = str.split('=').next().unwrap();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/needless_update.txt b/src/tools/clippy/src/docs/needless_update.txt
deleted file mode 100644
index 82adabf64..000000000
--- a/src/tools/clippy/src/docs/needless_update.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-### What it does
-Checks for needlessly including a base struct on update
-when all fields are changed anyway.
-
-This lint is not applied to structs marked with
-[non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html).
-
-### Why is this bad?
-This will cost resources (because the base has to be
-somewhere), and make the code less readable.
-
-### Example
-```
-Point {
- x: 1,
- y: 1,
- z: 1,
- ..zero_point
-};
-```
-
-Use instead:
-```
-// Missing field `z`
-Point {
- x: 1,
- y: 1,
- ..zero_point
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/neg_cmp_op_on_partial_ord.txt b/src/tools/clippy/src/docs/neg_cmp_op_on_partial_ord.txt
deleted file mode 100644
index fa55c6cfd..000000000
--- a/src/tools/clippy/src/docs/neg_cmp_op_on_partial_ord.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for the usage of negated comparison operators on types which only implement
-`PartialOrd` (e.g., `f64`).
-
-### Why is this bad?
-These operators make it easy to forget that the underlying types actually allow not only three
-potential Orderings (Less, Equal, Greater) but also a fourth one (Uncomparable). This is
-especially easy to miss if the operator based comparison result is negated.
-
-### Example
-```
-let a = 1.0;
-let b = f64::NAN;
-
-let not_less_or_equal = !(a <= b);
-```
-
-Use instead:
-```
-use std::cmp::Ordering;
-
-let _not_less_or_equal = match a.partial_cmp(&b) {
- None | Some(Ordering::Greater) => true,
- _ => false,
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/neg_multiply.txt b/src/tools/clippy/src/docs/neg_multiply.txt
deleted file mode 100644
index 4e8b096eb..000000000
--- a/src/tools/clippy/src/docs/neg_multiply.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for multiplication by -1 as a form of negation.
-
-### Why is this bad?
-It's more readable to just negate.
-
-### Known problems
-This only catches integers (for now).
-
-### Example
-```
-let a = x * -1;
-```
-
-Use instead:
-```
-let a = -x;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/negative_feature_names.txt b/src/tools/clippy/src/docs/negative_feature_names.txt
deleted file mode 100644
index 01ee9efb3..000000000
--- a/src/tools/clippy/src/docs/negative_feature_names.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for negative feature names with prefix `no-` or `not-`
-
-### Why is this bad?
-Features are supposed to be additive, and negatively-named features violate it.
-
-### Example
-```
-[features]
-default = []
-no-abc = []
-not-def = []
-
-```
-Use instead:
-```
-[features]
-default = ["abc", "def"]
-abc = []
-def = []
-
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/never_loop.txt b/src/tools/clippy/src/docs/never_loop.txt
deleted file mode 100644
index 737ccf415..000000000
--- a/src/tools/clippy/src/docs/never_loop.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for loops that will always `break`, `return` or
-`continue` an outer loop.
-
-### Why is this bad?
-This loop never loops, all it does is obfuscating the
-code.
-
-### Example
-```
-loop {
- ..;
- break;
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/new_ret_no_self.txt b/src/tools/clippy/src/docs/new_ret_no_self.txt
deleted file mode 100644
index 291bad24a..000000000
--- a/src/tools/clippy/src/docs/new_ret_no_self.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-### What it does
-Checks for `new` not returning a type that contains `Self`.
-
-### Why is this bad?
-As a convention, `new` methods are used to make a new
-instance of a type.
-
-### Example
-In an impl block:
-```
-impl Foo {
- fn new() -> NotAFoo {
- }
-}
-```
-
-```
-struct Bar(Foo);
-impl Foo {
- // Bad. The type name must contain `Self`
- fn new() -> Bar {
- }
-}
-```
-
-```
-impl Foo {
- // Good. Return type contains `Self`
- fn new() -> Result<Foo, FooError> {
- }
-}
-```
-
-Or in a trait definition:
-```
-pub trait Trait {
- // Bad. The type name must contain `Self`
- fn new();
-}
-```
-
-```
-pub trait Trait {
- // Good. Return type contains `Self`
- fn new() -> Self;
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/new_without_default.txt b/src/tools/clippy/src/docs/new_without_default.txt
deleted file mode 100644
index 662d39c8e..000000000
--- a/src/tools/clippy/src/docs/new_without_default.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks for public types with a `pub fn new() -> Self` method and no
-implementation of
-[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html).
-
-### Why is this bad?
-The user might expect to be able to use
-[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the
-type can be constructed without arguments.
-
-### Example
-```
-pub struct Foo(Bar);
-
-impl Foo {
- pub fn new() -> Self {
- Foo(Bar::new())
- }
-}
-```
-
-To fix the lint, add a `Default` implementation that delegates to `new`:
-
-```
-pub struct Foo(Bar);
-
-impl Default for Foo {
- fn default() -> Self {
- Foo::new()
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/no_effect.txt b/src/tools/clippy/src/docs/no_effect.txt
deleted file mode 100644
index d4cc08fa8..000000000
--- a/src/tools/clippy/src/docs/no_effect.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for statements which have no effect.
-
-### Why is this bad?
-Unlike dead code, these statements are actually
-executed. However, as they have no effect, all they do is make the code less
-readable.
-
-### Example
-```
-0;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/no_effect_replace.txt b/src/tools/clippy/src/docs/no_effect_replace.txt
deleted file mode 100644
index 646d45287..000000000
--- a/src/tools/clippy/src/docs/no_effect_replace.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-### What it does
-Checks for `replace` statements which have no effect.
-
-### Why is this bad?
-It's either a mistake or confusing.
-
-### Example
-```
-"1234".replace("12", "12");
-"1234".replacen("12", "12", 1);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/no_effect_underscore_binding.txt b/src/tools/clippy/src/docs/no_effect_underscore_binding.txt
deleted file mode 100644
index 972f60dd0..000000000
--- a/src/tools/clippy/src/docs/no_effect_underscore_binding.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for binding to underscore prefixed variable without side-effects.
-
-### Why is this bad?
-Unlike dead code, these bindings are actually
-executed. However, as they have no effect and shouldn't be used further on, all they
-do is make the code less readable.
-
-### Known problems
-Further usage of this variable is not checked, which can lead to false positives if it is
-used later in the code.
-
-### Example
-```
-let _i_serve_no_purpose = 1;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/non_ascii_literal.txt b/src/tools/clippy/src/docs/non_ascii_literal.txt
deleted file mode 100644
index 164902b47..000000000
--- a/src/tools/clippy/src/docs/non_ascii_literal.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for non-ASCII characters in string and char literals.
-
-### Why is this bad?
-Yeah, we know, the 90's called and wanted their charset
-back. Even so, there still are editors and other programs out there that
-don't work well with Unicode. So if the code is meant to be used
-internationally, on multiple operating systems, or has other portability
-requirements, activating this lint could be useful.
-
-### Example
-```
-let x = String::from("€");
-```
-
-Use instead:
-```
-let x = String::from("\u{20ac}");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/non_octal_unix_permissions.txt b/src/tools/clippy/src/docs/non_octal_unix_permissions.txt
deleted file mode 100644
index 4a468e94d..000000000
--- a/src/tools/clippy/src/docs/non_octal_unix_permissions.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for non-octal values used to set Unix file permissions.
-
-### Why is this bad?
-They will be converted into octal, creating potentially
-unintended file permissions.
-
-### Example
-```
-use std::fs::OpenOptions;
-use std::os::unix::fs::OpenOptionsExt;
-
-let mut options = OpenOptions::new();
-options.mode(644);
-```
-Use instead:
-```
-use std::fs::OpenOptions;
-use std::os::unix::fs::OpenOptionsExt;
-
-let mut options = OpenOptions::new();
-options.mode(0o644);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/non_send_fields_in_send_ty.txt b/src/tools/clippy/src/docs/non_send_fields_in_send_ty.txt
deleted file mode 100644
index 11e6f6e16..000000000
--- a/src/tools/clippy/src/docs/non_send_fields_in_send_ty.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-### What it does
-This lint warns about a `Send` implementation for a type that
-contains fields that are not safe to be sent across threads.
-It tries to detect fields that can cause a soundness issue
-when sent to another thread (e.g., `Rc`) while allowing `!Send` fields
-that are expected to exist in a `Send` type, such as raw pointers.
-
-### Why is this bad?
-Sending the struct to another thread effectively sends all of its fields,
-and the fields that do not implement `Send` can lead to soundness bugs
-such as data races when accessed in a thread
-that is different from the thread that created it.
-
-See:
-* [*The Rustonomicon* about *Send and Sync*](https://doc.rust-lang.org/nomicon/send-and-sync.html)
-* [The documentation of `Send`](https://doc.rust-lang.org/std/marker/trait.Send.html)
-
-### Known Problems
-This lint relies on heuristics to distinguish types that are actually
-unsafe to be sent across threads and `!Send` types that are expected to
-exist in `Send` type. Its rule can filter out basic cases such as
-`Vec<*const T>`, but it's not perfect. Feel free to create an issue if
-you have a suggestion on how this heuristic can be improved.
-
-### Example
-```
-struct ExampleStruct<T> {
- rc_is_not_send: Rc<String>,
- unbounded_generic_field: T,
-}
-
-// This impl is unsound because it allows sending `!Send` types through `ExampleStruct`
-unsafe impl<T> Send for ExampleStruct<T> {}
-```
-Use thread-safe types like [`std::sync::Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html)
-or specify correct bounds on generic type parameters (`T: Send`). \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/nonminimal_bool.txt b/src/tools/clippy/src/docs/nonminimal_bool.txt
deleted file mode 100644
index 488980ddf..000000000
--- a/src/tools/clippy/src/docs/nonminimal_bool.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for boolean expressions that can be written more
-concisely.
-
-### Why is this bad?
-Readability of boolean expressions suffers from
-unnecessary duplication.
-
-### Known problems
-Ignores short circuiting behavior of `||` and
-`&&`. Ignores `|`, `&` and `^`.
-
-### Example
-```
-if a && true {}
-if !(a == b) {}
-```
-
-Use instead:
-```
-if a {}
-if a != b {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/nonsensical_open_options.txt b/src/tools/clippy/src/docs/nonsensical_open_options.txt
deleted file mode 100644
index 7a95443b5..000000000
--- a/src/tools/clippy/src/docs/nonsensical_open_options.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for duplicate open options as well as combinations
-that make no sense.
-
-### Why is this bad?
-In the best case, the code will be harder to read than
-necessary. I don't know the worst case.
-
-### Example
-```
-use std::fs::OpenOptions;
-
-OpenOptions::new().read(true).truncate(true);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/nonstandard_macro_braces.txt b/src/tools/clippy/src/docs/nonstandard_macro_braces.txt
deleted file mode 100644
index 7e8d0d2d3..000000000
--- a/src/tools/clippy/src/docs/nonstandard_macro_braces.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks that common macros are used with consistent bracing.
-
-### Why is this bad?
-This is mostly a consistency lint although using () or []
-doesn't give you a semicolon in item position, which can be unexpected.
-
-### Example
-```
-vec!{1, 2, 3};
-```
-Use instead:
-```
-vec![1, 2, 3];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/not_unsafe_ptr_arg_deref.txt b/src/tools/clippy/src/docs/not_unsafe_ptr_arg_deref.txt
deleted file mode 100644
index 31355fbb7..000000000
--- a/src/tools/clippy/src/docs/not_unsafe_ptr_arg_deref.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-### What it does
-Checks for public functions that dereference raw pointer
-arguments but are not marked `unsafe`.
-
-### Why is this bad?
-The function should probably be marked `unsafe`, since
-for an arbitrary raw pointer, there is no way of telling for sure if it is
-valid.
-
-### Known problems
-* It does not check functions recursively so if the pointer is passed to a
-private non-`unsafe` function which does the dereferencing, the lint won't
-trigger.
-* It only checks for arguments whose type are raw pointers, not raw pointers
-got from an argument in some other way (`fn foo(bar: &[*const u8])` or
-`some_argument.get_raw_ptr()`).
-
-### Example
-```
-pub fn foo(x: *const u8) {
- println!("{}", unsafe { *x });
-}
-```
-
-Use instead:
-```
-pub unsafe fn foo(x: *const u8) {
- println!("{}", unsafe { *x });
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/obfuscated_if_else.txt b/src/tools/clippy/src/docs/obfuscated_if_else.txt
deleted file mode 100644
index 638f63b0d..000000000
--- a/src/tools/clippy/src/docs/obfuscated_if_else.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for usages of `.then_some(..).unwrap_or(..)`
-
-### Why is this bad?
-This can be written more clearly with `if .. else ..`
-
-### Limitations
-This lint currently only looks for usages of
-`.then_some(..).unwrap_or(..)`, but will be expanded
-to account for similar patterns.
-
-### Example
-```
-let x = true;
-x.then_some("a").unwrap_or("b");
-```
-Use instead:
-```
-let x = true;
-if x { "a" } else { "b" };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/octal_escapes.txt b/src/tools/clippy/src/docs/octal_escapes.txt
deleted file mode 100644
index eee820587..000000000
--- a/src/tools/clippy/src/docs/octal_escapes.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-### What it does
-Checks for `\0` escapes in string and byte literals that look like octal
-character escapes in C.
-
-### Why is this bad?
-
-C and other languages support octal character escapes in strings, where
-a backslash is followed by up to three octal digits. For example, `\033`
-stands for the ASCII character 27 (ESC). Rust does not support this
-notation, but has the escape code `\0` which stands for a null
-byte/character, and any following digits do not form part of the escape
-sequence. Therefore, `\033` is not a compiler error but the result may
-be surprising.
-
-### Known problems
-The actual meaning can be the intended one. `\x00` can be used in these
-cases to be unambiguous.
-
-The lint does not trigger for format strings in `print!()`, `write!()`
-and friends since the string is already preprocessed when Clippy lints
-can see it.
-
-### Example
-```
-let one = "\033[1m Bold? \033[0m"; // \033 intended as escape
-let two = "\033\0"; // \033 intended as null-3-3
-```
-
-Use instead:
-```
-let one = "\x1b[1mWill this be bold?\x1b[0m";
-let two = "\x0033\x00";
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ok_expect.txt b/src/tools/clippy/src/docs/ok_expect.txt
deleted file mode 100644
index fd5205d49..000000000
--- a/src/tools/clippy/src/docs/ok_expect.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for usage of `ok().expect(..)`.
-
-### Why is this bad?
-Because you usually call `expect()` on the `Result`
-directly to get a better error message.
-
-### Known problems
-The error type needs to implement `Debug`
-
-### Example
-```
-x.ok().expect("why did I do this again?");
-```
-
-Use instead:
-```
-x.expect("why did I do this again?");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/only_used_in_recursion.txt b/src/tools/clippy/src/docs/only_used_in_recursion.txt
deleted file mode 100644
index f19f47ff9..000000000
--- a/src/tools/clippy/src/docs/only_used_in_recursion.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-### What it does
-Checks for arguments that are only used in recursion with no side-effects.
-
-### Why is this bad?
-It could contain a useless calculation and can make function simpler.
-
-The arguments can be involved in calculations and assignments but as long as
-the calculations have no side-effects (function calls or mutating dereference)
-and the assigned variables are also only in recursion, it is useless.
-
-### Known problems
-Too many code paths in the linting code are currently untested and prone to produce false
-positives or are prone to have performance implications.
-
-In some cases, this would not catch all useless arguments.
-
-```
-fn foo(a: usize, b: usize) -> usize {
- let f = |x| x + 1;
-
- if a == 0 {
- 1
- } else {
- foo(a - 1, f(b))
- }
-}
-```
-
-For example, the argument `b` is only used in recursion, but the lint would not catch it.
-
-List of some examples that can not be caught:
-- binary operation of non-primitive types
-- closure usage
-- some `break` relative operations
-- struct pattern binding
-
-Also, when you recurse the function name with path segments, it is not possible to detect.
-
-### Example
-```
-fn f(a: usize, b: usize) -> usize {
- if a == 0 {
- 1
- } else {
- f(a - 1, b + 1)
- }
-}
-```
-Use instead:
-```
-fn f(a: usize) -> usize {
- if a == 0 {
- 1
- } else {
- f(a - 1)
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/op_ref.txt b/src/tools/clippy/src/docs/op_ref.txt
deleted file mode 100644
index 7a7ed1bc9..000000000
--- a/src/tools/clippy/src/docs/op_ref.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for arguments to `==` which have their address
-taken to satisfy a bound
-and suggests to dereference the other argument instead
-
-### Why is this bad?
-It is more idiomatic to dereference the other argument.
-
-### Example
-```
-&x == y
-```
-
-Use instead:
-```
-x == *y
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_as_ref_deref.txt b/src/tools/clippy/src/docs/option_as_ref_deref.txt
deleted file mode 100644
index ad7411d3d..000000000
--- a/src/tools/clippy/src/docs/option_as_ref_deref.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for usage of `_.as_ref().map(Deref::deref)` or it's aliases (such as String::as_str).
-
-### Why is this bad?
-Readability, this can be written more concisely as
-`_.as_deref()`.
-
-### Example
-```
-opt.as_ref().map(String::as_str)
-```
-Can be written as
-```
-opt.as_deref()
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_env_unwrap.txt b/src/tools/clippy/src/docs/option_env_unwrap.txt
deleted file mode 100644
index c952cba8e..000000000
--- a/src/tools/clippy/src/docs/option_env_unwrap.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for usage of `option_env!(...).unwrap()` and
-suggests usage of the `env!` macro.
-
-### Why is this bad?
-Unwrapping the result of `option_env!` will panic
-at run-time if the environment variable doesn't exist, whereas `env!`
-catches it at compile-time.
-
-### Example
-```
-let _ = option_env!("HOME").unwrap();
-```
-
-Is better expressed as:
-
-```
-let _ = env!("HOME");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_filter_map.txt b/src/tools/clippy/src/docs/option_filter_map.txt
deleted file mode 100644
index 25f7bde7b..000000000
--- a/src/tools/clippy/src/docs/option_filter_map.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for indirect collection of populated `Option`
-
-### Why is this bad?
-`Option` is like a collection of 0-1 things, so `flatten`
-automatically does this without suspicious-looking `unwrap` calls.
-
-### Example
-```
-let _ = std::iter::empty::<Option<i32>>().filter(Option::is_some).map(Option::unwrap);
-```
-Use instead:
-```
-let _ = std::iter::empty::<Option<i32>>().flatten();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_if_let_else.txt b/src/tools/clippy/src/docs/option_if_let_else.txt
deleted file mode 100644
index 43652db51..000000000
--- a/src/tools/clippy/src/docs/option_if_let_else.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-### What it does
-Lints usage of `if let Some(v) = ... { y } else { x }` and
-`match .. { Some(v) => y, None/_ => x }` which are more
-idiomatically done with `Option::map_or` (if the else bit is a pure
-expression) or `Option::map_or_else` (if the else bit is an impure
-expression).
-
-### Why is this bad?
-Using the dedicated functions of the `Option` type is clearer and
-more concise than an `if let` expression.
-
-### Known problems
-This lint uses a deliberately conservative metric for checking
-if the inside of either body contains breaks or continues which will
-cause it to not suggest a fix if either block contains a loop with
-continues or breaks contained within the loop.
-
-### Example
-```
-let _ = if let Some(foo) = optional {
- foo
-} else {
- 5
-};
-let _ = match optional {
- Some(val) => val + 1,
- None => 5
-};
-let _ = if let Some(foo) = optional {
- foo
-} else {
- let y = do_complicated_function();
- y*y
-};
-```
-
-should be
-
-```
-let _ = optional.map_or(5, |foo| foo);
-let _ = optional.map_or(5, |val| val + 1);
-let _ = optional.map_or_else(||{
- let y = do_complicated_function();
- y*y
-}, |foo| foo);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_map_or_none.txt b/src/tools/clippy/src/docs/option_map_or_none.txt
deleted file mode 100644
index c86c65215..000000000
--- a/src/tools/clippy/src/docs/option_map_or_none.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for usage of `_.map_or(None, _)`.
-
-### Why is this bad?
-Readability, this can be written more concisely as
-`_.and_then(_)`.
-
-### Known problems
-The order of the arguments is not in execution order.
-
-### Example
-```
-opt.map_or(None, |a| Some(a + 1));
-```
-
-Use instead:
-```
-opt.and_then(|a| Some(a + 1));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_map_unit_fn.txt b/src/tools/clippy/src/docs/option_map_unit_fn.txt
deleted file mode 100644
index fc4b528f0..000000000
--- a/src/tools/clippy/src/docs/option_map_unit_fn.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for usage of `option.map(f)` where f is a function
-or closure that returns the unit type `()`.
-
-### Why is this bad?
-Readability, this can be written more clearly with
-an if let statement
-
-### Example
-```
-let x: Option<String> = do_stuff();
-x.map(log_err_msg);
-x.map(|msg| log_err_msg(format_msg(msg)));
-```
-
-The correct use would be:
-
-```
-let x: Option<String> = do_stuff();
-if let Some(msg) = x {
- log_err_msg(msg);
-}
-
-if let Some(msg) = x {
- log_err_msg(format_msg(msg));
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/option_option.txt b/src/tools/clippy/src/docs/option_option.txt
deleted file mode 100644
index b4324bd83..000000000
--- a/src/tools/clippy/src/docs/option_option.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks for use of `Option<Option<_>>` in function signatures and type
-definitions
-
-### Why is this bad?
-`Option<_>` represents an optional value. `Option<Option<_>>`
-represents an optional optional value which is logically the same thing as an optional
-value but has an unneeded extra level of wrapping.
-
-If you have a case where `Some(Some(_))`, `Some(None)` and `None` are distinct cases,
-consider a custom `enum` instead, with clear names for each case.
-
-### Example
-```
-fn get_data() -> Option<Option<u32>> {
- None
-}
-```
-
-Better:
-
-```
-pub enum Contents {
- Data(Vec<u8>), // Was Some(Some(Vec<u8>))
- NotYetFetched, // Was Some(None)
- None, // Was None
-}
-
-fn get_data() -> Contents {
- Contents::None
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/or_fun_call.txt b/src/tools/clippy/src/docs/or_fun_call.txt
deleted file mode 100644
index 6ce77cc26..000000000
--- a/src/tools/clippy/src/docs/or_fun_call.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`,
-`.or_insert(foo(..))` etc., and suggests to use `.or_else(|| foo(..))`,
-`.unwrap_or_else(|| foo(..))`, `.unwrap_or_default()` or `.or_default()`
-etc. instead.
-
-### Why is this bad?
-The function will always be called and potentially
-allocate an object acting as the default.
-
-### Known problems
-If the function has side-effects, not calling it will
-change the semantic of the program, but you shouldn't rely on that anyway.
-
-### Example
-```
-foo.unwrap_or(String::new());
-```
-
-Use instead:
-```
-foo.unwrap_or_else(String::new);
-
-// or
-
-foo.unwrap_or_default();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/or_then_unwrap.txt b/src/tools/clippy/src/docs/or_then_unwrap.txt
deleted file mode 100644
index 64ac53749..000000000
--- a/src/tools/clippy/src/docs/or_then_unwrap.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for `.or(…).unwrap()` calls to Options and Results.
-
-### Why is this bad?
-You should use `.unwrap_or(…)` instead for clarity.
-
-### Example
-```
-// Result
-let value = result.or::<Error>(Ok(fallback)).unwrap();
-
-// Option
-let value = option.or(Some(fallback)).unwrap();
-```
-Use instead:
-```
-// Result
-let value = result.unwrap_or(fallback);
-
-// Option
-let value = option.unwrap_or(fallback);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/out_of_bounds_indexing.txt b/src/tools/clippy/src/docs/out_of_bounds_indexing.txt
deleted file mode 100644
index 5802eea29..000000000
--- a/src/tools/clippy/src/docs/out_of_bounds_indexing.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for out of bounds array indexing with a constant
-index.
-
-### Why is this bad?
-This will always panic at runtime.
-
-### Example
-```
-let x = [1, 2, 3, 4];
-
-x[9];
-&x[2..9];
-```
-
-Use instead:
-```
-// Index within bounds
-
-x[0];
-x[3];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/overflow_check_conditional.txt b/src/tools/clippy/src/docs/overflow_check_conditional.txt
deleted file mode 100644
index a09cc18a0..000000000
--- a/src/tools/clippy/src/docs/overflow_check_conditional.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-### What it does
-Detects classic underflow/overflow checks.
-
-### Why is this bad?
-Most classic C underflow/overflow checks will fail in
-Rust. Users can use functions like `overflowing_*` and `wrapping_*` instead.
-
-### Example
-```
-a + b < a;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/overly_complex_bool_expr.txt b/src/tools/clippy/src/docs/overly_complex_bool_expr.txt
deleted file mode 100644
index 65ca18392..000000000
--- a/src/tools/clippy/src/docs/overly_complex_bool_expr.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for boolean expressions that contain terminals that
-can be eliminated.
-
-### Why is this bad?
-This is most likely a logic bug.
-
-### Known problems
-Ignores short circuiting behavior.
-
-### Example
-```
-// The `b` is unnecessary, the expression is equivalent to `if a`.
-if a && b || a { ... }
-```
-
-Use instead:
-```
-if a {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/panic.txt b/src/tools/clippy/src/docs/panic.txt
deleted file mode 100644
index f9bdc6e87..000000000
--- a/src/tools/clippy/src/docs/panic.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-### What it does
-Checks for usage of `panic!`.
-
-### Why is this bad?
-`panic!` will stop the execution of the executable
-
-### Example
-```
-panic!("even with a good reason");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/panic_in_result_fn.txt b/src/tools/clippy/src/docs/panic_in_result_fn.txt
deleted file mode 100644
index 51c2f8ae5..000000000
--- a/src/tools/clippy/src/docs/panic_in_result_fn.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result.
-
-### Why is this bad?
-For some codebases, it is desirable for functions of type result to return an error instead of crashing. Hence panicking macros should be avoided.
-
-### Known problems
-Functions called from a function returning a `Result` may invoke a panicking macro. This is not checked.
-
-### Example
-```
-fn result_with_panic() -> Result<bool, String>
-{
- panic!("error");
-}
-```
-Use instead:
-```
-fn result_without_panic() -> Result<bool, String> {
- Err(String::from("error"))
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/panicking_unwrap.txt b/src/tools/clippy/src/docs/panicking_unwrap.txt
deleted file mode 100644
index 1fbc245c8..000000000
--- a/src/tools/clippy/src/docs/panicking_unwrap.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for calls of `unwrap[_err]()` that will always fail.
-
-### Why is this bad?
-If panicking is desired, an explicit `panic!()` should be used.
-
-### Known problems
-This lint only checks `if` conditions not assignments.
-So something like `let x: Option<()> = None; x.unwrap();` will not be recognized.
-
-### Example
-```
-if option.is_none() {
- do_something_with(option.unwrap())
-}
-```
-
-This code will always panic. The if condition should probably be inverted. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/partial_pub_fields.txt b/src/tools/clippy/src/docs/partial_pub_fields.txt
deleted file mode 100644
index b529adf15..000000000
--- a/src/tools/clippy/src/docs/partial_pub_fields.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks whether partial fields of a struct are public.
-
-Either make all fields of a type public, or make none of them public
-
-### Why is this bad?
-Most types should either be:
-* Abstract data types: complex objects with opaque implementation which guard
-interior invariants and expose intentionally limited API to the outside world.
-* Data: relatively simple objects which group a bunch of related attributes together.
-
-### Example
-```
-pub struct Color {
- pub r: u8,
- pub g: u8,
- b: u8,
-}
-```
-Use instead:
-```
-pub struct Color {
- pub r: u8,
- pub g: u8,
- pub b: u8,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/partialeq_ne_impl.txt b/src/tools/clippy/src/docs/partialeq_ne_impl.txt
deleted file mode 100644
index 78f55188b..000000000
--- a/src/tools/clippy/src/docs/partialeq_ne_impl.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for manual re-implementations of `PartialEq::ne`.
-
-### Why is this bad?
-`PartialEq::ne` is required to always return the
-negated result of `PartialEq::eq`, which is exactly what the default
-implementation does. Therefore, there should never be any need to
-re-implement it.
-
-### Example
-```
-struct Foo;
-
-impl PartialEq for Foo {
- fn eq(&self, other: &Foo) -> bool { true }
- fn ne(&self, other: &Foo) -> bool { !(self == other) }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/partialeq_to_none.txt b/src/tools/clippy/src/docs/partialeq_to_none.txt
deleted file mode 100644
index 5cc07bf88..000000000
--- a/src/tools/clippy/src/docs/partialeq_to_none.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-
-Checks for binary comparisons to a literal `Option::None`.
-
-### Why is this bad?
-
-A programmer checking if some `foo` is `None` via a comparison `foo == None`
-is usually inspired from other programming languages (e.g. `foo is None`
-in Python).
-Checking if a value of type `Option<T>` is (not) equal to `None` in that
-way relies on `T: PartialEq` to do the comparison, which is unneeded.
-
-### Example
-```
-fn foo(f: Option<u32>) -> &'static str {
- if f != None { "yay" } else { "nay" }
-}
-```
-Use instead:
-```
-fn foo(f: Option<u32>) -> &'static str {
- if f.is_some() { "yay" } else { "nay" }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/path_buf_push_overwrite.txt b/src/tools/clippy/src/docs/path_buf_push_overwrite.txt
deleted file mode 100644
index 34f8901da..000000000
--- a/src/tools/clippy/src/docs/path_buf_push_overwrite.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)
-calls on `PathBuf` that can cause overwrites.
-
-### Why is this bad?
-Calling `push` with a root path at the start can overwrite the
-previous defined path.
-
-### Example
-```
-use std::path::PathBuf;
-
-let mut x = PathBuf::from("/foo");
-x.push("/bar");
-assert_eq!(x, PathBuf::from("/bar"));
-```
-Could be written:
-
-```
-use std::path::PathBuf;
-
-let mut x = PathBuf::from("/foo");
-x.push("bar");
-assert_eq!(x, PathBuf::from("/foo/bar"));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/pattern_type_mismatch.txt b/src/tools/clippy/src/docs/pattern_type_mismatch.txt
deleted file mode 100644
index 64da881d5..000000000
--- a/src/tools/clippy/src/docs/pattern_type_mismatch.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-### What it does
-Checks for patterns that aren't exact representations of the types
-they are applied to.
-
-To satisfy this lint, you will have to adjust either the expression that is matched
-against or the pattern itself, as well as the bindings that are introduced by the
-adjusted patterns. For matching you will have to either dereference the expression
-with the `*` operator, or amend the patterns to explicitly match against `&<pattern>`
-or `&mut <pattern>` depending on the reference mutability. For the bindings you need
-to use the inverse. You can leave them as plain bindings if you wish for the value
-to be copied, but you must use `ref mut <variable>` or `ref <variable>` to construct
-a reference into the matched structure.
-
-If you are looking for a way to learn about ownership semantics in more detail, it
-is recommended to look at IDE options available to you to highlight types, lifetimes
-and reference semantics in your code. The available tooling would expose these things
-in a general way even outside of the various pattern matching mechanics. Of course
-this lint can still be used to highlight areas of interest and ensure a good understanding
-of ownership semantics.
-
-### Why is this bad?
-It isn't bad in general. But in some contexts it can be desirable
-because it increases ownership hints in the code, and will guard against some changes
-in ownership.
-
-### Example
-This example shows the basic adjustments necessary to satisfy the lint. Note how
-the matched expression is explicitly dereferenced with `*` and the `inner` variable
-is bound to a shared borrow via `ref inner`.
-
-```
-// Bad
-let value = &Some(Box::new(23));
-match value {
- Some(inner) => println!("{}", inner),
- None => println!("none"),
-}
-
-// Good
-let value = &Some(Box::new(23));
-match *value {
- Some(ref inner) => println!("{}", inner),
- None => println!("none"),
-}
-```
-
-The following example demonstrates one of the advantages of the more verbose style.
-Note how the second version uses `ref mut a` to explicitly declare `a` a shared mutable
-borrow, while `b` is simply taken by value. This ensures that the loop body cannot
-accidentally modify the wrong part of the structure.
-
-```
-// Bad
-let mut values = vec![(2, 3), (3, 4)];
-for (a, b) in &mut values {
- *a += *b;
-}
-
-// Good
-let mut values = vec![(2, 3), (3, 4)];
-for &mut (ref mut a, b) in &mut values {
- *a += b;
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/possible_missing_comma.txt b/src/tools/clippy/src/docs/possible_missing_comma.txt
deleted file mode 100644
index 5d92f4cae..000000000
--- a/src/tools/clippy/src/docs/possible_missing_comma.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for possible missing comma in an array. It lints if
-an array element is a binary operator expression and it lies on two lines.
-
-### Why is this bad?
-This could lead to unexpected results.
-
-### Example
-```
-let a = &[
- -1, -2, -3 // <= no comma here
- -4, -5, -6
-];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/precedence.txt b/src/tools/clippy/src/docs/precedence.txt
deleted file mode 100644
index fda0b831f..000000000
--- a/src/tools/clippy/src/docs/precedence.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for operations where precedence may be unclear
-and suggests to add parentheses. Currently it catches the following:
-* mixed usage of arithmetic and bit shifting/combining operators without
-parentheses
-* a "negative" numeric literal (which is really a unary `-` followed by a
-numeric literal)
- followed by a method call
-
-### Why is this bad?
-Not everyone knows the precedence of those operators by
-heart, so expressions like these may trip others trying to reason about the
-code.
-
-### Example
-* `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7
-* `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1 \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/print_in_format_impl.txt b/src/tools/clippy/src/docs/print_in_format_impl.txt
deleted file mode 100644
index 140d23d6f..000000000
--- a/src/tools/clippy/src/docs/print_in_format_impl.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-### What it does
-Checks for use of `println`, `print`, `eprintln` or `eprint` in an
-implementation of a formatting trait.
-
-### Why is this bad?
-Using a print macro is likely unintentional since formatting traits
-should write to the `Formatter`, not stdout/stderr.
-
-### Example
-```
-use std::fmt::{Display, Error, Formatter};
-
-struct S;
-impl Display for S {
- fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
- println!("S");
-
- Ok(())
- }
-}
-```
-Use instead:
-```
-use std::fmt::{Display, Error, Formatter};
-
-struct S;
-impl Display for S {
- fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
- writeln!(f, "S");
-
- Ok(())
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/print_literal.txt b/src/tools/clippy/src/docs/print_literal.txt
deleted file mode 100644
index a6252a687..000000000
--- a/src/tools/clippy/src/docs/print_literal.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-This lint warns about the use of literals as `print!`/`println!` args.
-
-### Why is this bad?
-Using literals as `println!` args is inefficient
-(c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary
-(i.e., just put the literal in the format string)
-
-### Example
-```
-println!("{}", "foo");
-```
-use the literal without formatting:
-```
-println!("foo");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/print_stderr.txt b/src/tools/clippy/src/docs/print_stderr.txt
deleted file mode 100644
index 9c6edeeef..000000000
--- a/src/tools/clippy/src/docs/print_stderr.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for printing on *stderr*. The purpose of this lint
-is to catch debugging remnants.
-
-### Why is this bad?
-People often print on *stderr* while debugging an
-application and might forget to remove those prints afterward.
-
-### Known problems
-Only catches `eprint!` and `eprintln!` calls.
-
-### Example
-```
-eprintln!("Hello world!");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/print_stdout.txt b/src/tools/clippy/src/docs/print_stdout.txt
deleted file mode 100644
index d2cbd811d..000000000
--- a/src/tools/clippy/src/docs/print_stdout.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for printing on *stdout*. The purpose of this lint
-is to catch debugging remnants.
-
-### Why is this bad?
-People often print on *stdout* while debugging an
-application and might forget to remove those prints afterward.
-
-### Known problems
-Only catches `print!` and `println!` calls.
-
-### Example
-```
-println!("Hello world!");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/print_with_newline.txt b/src/tools/clippy/src/docs/print_with_newline.txt
deleted file mode 100644
index 640323e82..000000000
--- a/src/tools/clippy/src/docs/print_with_newline.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-This lint warns when you use `print!()` with a format
-string that ends in a newline.
-
-### Why is this bad?
-You should use `println!()` instead, which appends the
-newline.
-
-### Example
-```
-print!("Hello {}!\n", name);
-```
-use println!() instead
-```
-println!("Hello {}!", name);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/println_empty_string.txt b/src/tools/clippy/src/docs/println_empty_string.txt
deleted file mode 100644
index b98041302..000000000
--- a/src/tools/clippy/src/docs/println_empty_string.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-This lint warns when you use `println!("")` to
-print a newline.
-
-### Why is this bad?
-You should use `println!()`, which is simpler.
-
-### Example
-```
-println!("");
-```
-
-Use instead:
-```
-println!();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ptr_arg.txt b/src/tools/clippy/src/docs/ptr_arg.txt
deleted file mode 100644
index 796b0a65b..000000000
--- a/src/tools/clippy/src/docs/ptr_arg.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-This lint checks for function arguments of type `&String`, `&Vec`,
-`&PathBuf`, and `Cow<_>`. It will also suggest you replace `.clone()` calls
-with the appropriate `.to_owned()`/`to_string()` calls.
-
-### Why is this bad?
-Requiring the argument to be of the specific size
-makes the function less useful for no benefit; slices in the form of `&[T]`
-or `&str` usually suffice and can be obtained from other types, too.
-
-### Known problems
-There may be `fn(&Vec)`-typed references pointing to your function.
-If you have them, you will get a compiler error after applying this lint's
-suggestions. You then have the choice to undo your changes or change the
-type of the reference.
-
-Note that if the function is part of your public interface, there may be
-other crates referencing it, of which you may not be aware. Carefully
-deprecate the function before applying the lint suggestions in this case.
-
-### Example
-```
-fn foo(&Vec<u32>) { .. }
-```
-
-Use instead:
-```
-fn foo(&[u32]) { .. }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ptr_as_ptr.txt b/src/tools/clippy/src/docs/ptr_as_ptr.txt
deleted file mode 100644
index 8fb35c4aa..000000000
--- a/src/tools/clippy/src/docs/ptr_as_ptr.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for `as` casts between raw pointers without changing its mutability,
-namely `*const T` to `*const U` and `*mut T` to `*mut U`.
-
-### Why is this bad?
-Though `as` casts between raw pointers is not terrible, `pointer::cast` is safer because
-it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`.
-
-### Example
-```
-let ptr: *const u32 = &42_u32;
-let mut_ptr: *mut u32 = &mut 42_u32;
-let _ = ptr as *const i32;
-let _ = mut_ptr as *mut i32;
-```
-Use instead:
-```
-let ptr: *const u32 = &42_u32;
-let mut_ptr: *mut u32 = &mut 42_u32;
-let _ = ptr.cast::<i32>();
-let _ = mut_ptr.cast::<i32>();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ptr_eq.txt b/src/tools/clippy/src/docs/ptr_eq.txt
deleted file mode 100644
index 06b36ca55..000000000
--- a/src/tools/clippy/src/docs/ptr_eq.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Use `std::ptr::eq` when applicable
-
-### Why is this bad?
-`ptr::eq` can be used to compare `&T` references
-(which coerce to `*const T` implicitly) by their address rather than
-comparing the values they point to.
-
-### Example
-```
-let a = &[1, 2, 3];
-let b = &[1, 2, 3];
-
-assert!(a as *const _ as usize == b as *const _ as usize);
-```
-Use instead:
-```
-let a = &[1, 2, 3];
-let b = &[1, 2, 3];
-
-assert!(std::ptr::eq(a, b));
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ptr_offset_with_cast.txt b/src/tools/clippy/src/docs/ptr_offset_with_cast.txt
deleted file mode 100644
index f204e769b..000000000
--- a/src/tools/clippy/src/docs/ptr_offset_with_cast.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-### What it does
-Checks for usage of the `offset` pointer method with a `usize` casted to an
-`isize`.
-
-### Why is this bad?
-If we’re always increasing the pointer address, we can avoid the numeric
-cast by using the `add` method instead.
-
-### Example
-```
-let vec = vec![b'a', b'b', b'c'];
-let ptr = vec.as_ptr();
-let offset = 1_usize;
-
-unsafe {
- ptr.offset(offset as isize);
-}
-```
-
-Could be written:
-
-```
-let vec = vec![b'a', b'b', b'c'];
-let ptr = vec.as_ptr();
-let offset = 1_usize;
-
-unsafe {
- ptr.add(offset);
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/pub_use.txt b/src/tools/clippy/src/docs/pub_use.txt
deleted file mode 100644
index 407cafa01..000000000
--- a/src/tools/clippy/src/docs/pub_use.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-
-Restricts the usage of `pub use ...`
-
-### Why is this bad?
-
-`pub use` is usually fine, but a project may wish to limit `pub use` instances to prevent
-unintentional exports or to encourage placing exported items directly in public modules
-
-### Example
-```
-pub mod outer {
- mod inner {
- pub struct Test {}
- }
- pub use inner::Test;
-}
-
-use outer::Test;
-```
-Use instead:
-```
-pub mod outer {
- pub struct Test {}
-}
-
-use outer::Test;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/question_mark.txt b/src/tools/clippy/src/docs/question_mark.txt
deleted file mode 100644
index 4dc987be8..000000000
--- a/src/tools/clippy/src/docs/question_mark.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for expressions that could be replaced by the question mark operator.
-
-### Why is this bad?
-Question mark usage is more idiomatic.
-
-### Example
-```
-if option.is_none() {
- return None;
-}
-```
-
-Could be written:
-
-```
-option?;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/range_minus_one.txt b/src/tools/clippy/src/docs/range_minus_one.txt
deleted file mode 100644
index fcb96dcc3..000000000
--- a/src/tools/clippy/src/docs/range_minus_one.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for inclusive ranges where 1 is subtracted from
-the upper bound, e.g., `x..=(y-1)`.
-
-### Why is this bad?
-The code is more readable with an exclusive range
-like `x..y`.
-
-### Known problems
-This will cause a warning that cannot be fixed if
-the consumer of the range only accepts a specific range type, instead of
-the generic `RangeBounds` trait
-([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)).
-
-### Example
-```
-for i in x..=(y-1) {
- // ..
-}
-```
-
-Use instead:
-```
-for i in x..y {
- // ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/range_plus_one.txt b/src/tools/clippy/src/docs/range_plus_one.txt
deleted file mode 100644
index 193c85f9c..000000000
--- a/src/tools/clippy/src/docs/range_plus_one.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-### What it does
-Checks for exclusive ranges where 1 is added to the
-upper bound, e.g., `x..(y+1)`.
-
-### Why is this bad?
-The code is more readable with an inclusive range
-like `x..=y`.
-
-### Known problems
-Will add unnecessary pair of parentheses when the
-expression is not wrapped in a pair but starts with an opening parenthesis
-and ends with a closing one.
-I.e., `let _ = (f()+1)..(f()+1)` results in `let _ = ((f()+1)..=f())`.
-
-Also in many cases, inclusive ranges are still slower to run than
-exclusive ranges, because they essentially add an extra branch that
-LLVM may fail to hoist out of the loop.
-
-This will cause a warning that cannot be fixed if the consumer of the
-range only accepts a specific range type, instead of the generic
-`RangeBounds` trait
-([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)).
-
-### Example
-```
-for i in x..(y+1) {
- // ..
-}
-```
-
-Use instead:
-```
-for i in x..=y {
- // ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/range_zip_with_len.txt b/src/tools/clippy/src/docs/range_zip_with_len.txt
deleted file mode 100644
index 24c1efec7..000000000
--- a/src/tools/clippy/src/docs/range_zip_with_len.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for zipping a collection with the range of
-`0.._.len()`.
-
-### Why is this bad?
-The code is better expressed with `.enumerate()`.
-
-### Example
-```
-let _ = x.iter().zip(0..x.len());
-```
-
-Use instead:
-```
-let _ = x.iter().enumerate();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/rc_buffer.txt b/src/tools/clippy/src/docs/rc_buffer.txt
deleted file mode 100644
index 82ac58eeb..000000000
--- a/src/tools/clippy/src/docs/rc_buffer.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for `Rc<T>` and `Arc<T>` when `T` is a mutable buffer type such as `String` or `Vec`.
-
-### Why is this bad?
-Expressions such as `Rc<String>` usually have no advantage over `Rc<str>`, since
-it is larger and involves an extra level of indirection, and doesn't implement `Borrow<str>`.
-
-While mutating a buffer type would still be possible with `Rc::get_mut()`, it only
-works if there are no additional references yet, which usually defeats the purpose of
-enclosing it in a shared ownership type. Instead, additionally wrapping the inner
-type with an interior mutable container (such as `RefCell` or `Mutex`) would normally
-be used.
-
-### Known problems
-This pattern can be desirable to avoid the overhead of a `RefCell` or `Mutex` for
-cases where mutation only happens before there are any additional references.
-
-### Example
-```
-fn foo(interned: Rc<String>) { ... }
-```
-
-Better:
-
-```
-fn foo(interned: Rc<str>) { ... }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/rc_clone_in_vec_init.txt b/src/tools/clippy/src/docs/rc_clone_in_vec_init.txt
deleted file mode 100644
index 6fc08aaf9..000000000
--- a/src/tools/clippy/src/docs/rc_clone_in_vec_init.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for reference-counted pointers (`Arc`, `Rc`, `rc::Weak`, and `sync::Weak`)
-in `vec![elem; len]`
-
-### Why is this bad?
-This will create `elem` once and clone it `len` times - doing so with `Arc`/`Rc`/`Weak`
-is a bit misleading, as it will create references to the same pointer, rather
-than different instances.
-
-### Example
-```
-let v = vec![std::sync::Arc::new("some data".to_string()); 100];
-// or
-let v = vec![std::rc::Rc::new("some data".to_string()); 100];
-```
-Use instead:
-```
-// Initialize each value separately:
-let mut data = Vec::with_capacity(100);
-for _ in 0..100 {
- data.push(std::rc::Rc::new("some data".to_string()));
-}
-
-// Or if you want clones of the same reference,
-// Create the reference beforehand to clarify that
-// it should be cloned for each value
-let data = std::rc::Rc::new("some data".to_string());
-let v = vec![data; 100];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/rc_mutex.txt b/src/tools/clippy/src/docs/rc_mutex.txt
deleted file mode 100644
index ed7a1e344..000000000
--- a/src/tools/clippy/src/docs/rc_mutex.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for `Rc<Mutex<T>>`.
-
-### Why is this bad?
-`Rc` is used in single thread and `Mutex` is used in multi thread.
-Consider using `Rc<RefCell<T>>` in single thread or `Arc<Mutex<T>>` in multi thread.
-
-### Known problems
-Sometimes combining generic types can lead to the requirement that a
-type use Rc in conjunction with Mutex. We must consider those cases false positives, but
-alas they are quite hard to rule out. Luckily they are also rare.
-
-### Example
-```
-use std::rc::Rc;
-use std::sync::Mutex;
-fn foo(interned: Rc<Mutex<i32>>) { ... }
-```
-
-Better:
-
-```
-use std::rc::Rc;
-use std::cell::RefCell
-fn foo(interned: Rc<RefCell<i32>>) { ... }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/read_zero_byte_vec.txt b/src/tools/clippy/src/docs/read_zero_byte_vec.txt
deleted file mode 100644
index cef5604e0..000000000
--- a/src/tools/clippy/src/docs/read_zero_byte_vec.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-### What it does
-This lint catches reads into a zero-length `Vec`.
-Especially in the case of a call to `with_capacity`, this lint warns that read
-gets the number of bytes from the `Vec`'s length, not its capacity.
-
-### Why is this bad?
-Reading zero bytes is almost certainly not the intended behavior.
-
-### Known problems
-In theory, a very unusual read implementation could assign some semantic meaning
-to zero-byte reads. But it seems exceptionally unlikely that code intending to do
-a zero-byte read would allocate a `Vec` for it.
-
-### Example
-```
-use std::io;
-fn foo<F: io::Read>(mut f: F) {
- let mut data = Vec::with_capacity(100);
- f.read(&mut data).unwrap();
-}
-```
-Use instead:
-```
-use std::io;
-fn foo<F: io::Read>(mut f: F) {
- let mut data = Vec::with_capacity(100);
- data.resize(100, 0);
- f.read(&mut data).unwrap();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/recursive_format_impl.txt b/src/tools/clippy/src/docs/recursive_format_impl.txt
deleted file mode 100644
index 32fffd84c..000000000
--- a/src/tools/clippy/src/docs/recursive_format_impl.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks for format trait implementations (e.g. `Display`) with a recursive call to itself
-which uses `self` as a parameter.
-This is typically done indirectly with the `write!` macro or with `to_string()`.
-
-### Why is this bad?
-This will lead to infinite recursion and a stack overflow.
-
-### Example
-
-```
-use std::fmt;
-
-struct Structure(i32);
-impl fmt::Display for Structure {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", self.to_string())
- }
-}
-
-```
-Use instead:
-```
-use std::fmt;
-
-struct Structure(i32);
-impl fmt::Display for Structure {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", self.0)
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_allocation.txt b/src/tools/clippy/src/docs/redundant_allocation.txt
deleted file mode 100644
index 86bf51e8d..000000000
--- a/src/tools/clippy/src/docs/redundant_allocation.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for use of redundant allocations anywhere in the code.
-
-### Why is this bad?
-Expressions such as `Rc<&T>`, `Rc<Rc<T>>`, `Rc<Arc<T>>`, `Rc<Box<T>>`, `Arc<&T>`, `Arc<Rc<T>>`,
-`Arc<Arc<T>>`, `Arc<Box<T>>`, `Box<&T>`, `Box<Rc<T>>`, `Box<Arc<T>>`, `Box<Box<T>>`, add an unnecessary level of indirection.
-
-### Example
-```
-fn foo(bar: Rc<&usize>) {}
-```
-
-Better:
-
-```
-fn foo(bar: &usize) {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_clone.txt b/src/tools/clippy/src/docs/redundant_clone.txt
deleted file mode 100644
index b29aed0b5..000000000
--- a/src/tools/clippy/src/docs/redundant_clone.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for a redundant `clone()` (and its relatives) which clones an owned
-value that is going to be dropped without further use.
-
-### Why is this bad?
-It is not always possible for the compiler to eliminate useless
-allocations and deallocations generated by redundant `clone()`s.
-
-### Known problems
-False-negatives: analysis performed by this lint is conservative and limited.
-
-### Example
-```
-{
- let x = Foo::new();
- call(x.clone());
- call(x.clone()); // this can just pass `x`
-}
-
-["lorem", "ipsum"].join(" ").to_string();
-
-Path::new("/a/b").join("c").to_path_buf();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_closure.txt b/src/tools/clippy/src/docs/redundant_closure.txt
deleted file mode 100644
index 0faa9513f..000000000
--- a/src/tools/clippy/src/docs/redundant_closure.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for closures which just call another function where
-the function can be called directly. `unsafe` functions or calls where types
-get adjusted are ignored.
-
-### Why is this bad?
-Needlessly creating a closure adds code for no benefit
-and gives the optimizer more work.
-
-### Known problems
-If creating the closure inside the closure has a side-
-effect then moving the closure creation out will change when that side-
-effect runs.
-See [#1439](https://github.com/rust-lang/rust-clippy/issues/1439) for more details.
-
-### Example
-```
-xs.map(|x| foo(x))
-```
-
-Use instead:
-```
-// where `foo(_)` is a plain function that takes the exact argument type of `x`.
-xs.map(foo)
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_closure_call.txt b/src/tools/clippy/src/docs/redundant_closure_call.txt
deleted file mode 100644
index 913d1a705..000000000
--- a/src/tools/clippy/src/docs/redundant_closure_call.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Detects closures called in the same expression where they
-are defined.
-
-### Why is this bad?
-It is unnecessarily adding to the expression's
-complexity.
-
-### Example
-```
-let a = (|| 42)();
-```
-
-Use instead:
-```
-let a = 42;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_closure_for_method_calls.txt b/src/tools/clippy/src/docs/redundant_closure_for_method_calls.txt
deleted file mode 100644
index 865510e14..000000000
--- a/src/tools/clippy/src/docs/redundant_closure_for_method_calls.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for closures which only invoke a method on the closure
-argument and can be replaced by referencing the method directly.
-
-### Why is this bad?
-It's unnecessary to create the closure.
-
-### Example
-```
-Some('a').map(|s| s.to_uppercase());
-```
-may be rewritten as
-```
-Some('a').map(char::to_uppercase);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_else.txt b/src/tools/clippy/src/docs/redundant_else.txt
deleted file mode 100644
index 3f4e86917..000000000
--- a/src/tools/clippy/src/docs/redundant_else.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-### What it does
-Checks for `else` blocks that can be removed without changing semantics.
-
-### Why is this bad?
-The `else` block adds unnecessary indentation and verbosity.
-
-### Known problems
-Some may prefer to keep the `else` block for clarity.
-
-### Example
-```
-fn my_func(count: u32) {
- if count == 0 {
- print!("Nothing to do");
- return;
- } else {
- print!("Moving on...");
- }
-}
-```
-Use instead:
-```
-fn my_func(count: u32) {
- if count == 0 {
- print!("Nothing to do");
- return;
- }
- print!("Moving on...");
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_feature_names.txt b/src/tools/clippy/src/docs/redundant_feature_names.txt
deleted file mode 100644
index 5bd6925ed..000000000
--- a/src/tools/clippy/src/docs/redundant_feature_names.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for feature names with prefix `use-`, `with-` or suffix `-support`
-
-### Why is this bad?
-These prefixes and suffixes have no significant meaning.
-
-### Example
-```
-[features]
-default = ["use-abc", "with-def", "ghi-support"]
-use-abc = [] // redundant
-with-def = [] // redundant
-ghi-support = [] // redundant
-```
-
-Use instead:
-```
-[features]
-default = ["abc", "def", "ghi"]
-abc = []
-def = []
-ghi = []
-```
diff --git a/src/tools/clippy/src/docs/redundant_field_names.txt b/src/tools/clippy/src/docs/redundant_field_names.txt
deleted file mode 100644
index 35f20a466..000000000
--- a/src/tools/clippy/src/docs/redundant_field_names.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for fields in struct literals where shorthands
-could be used.
-
-### Why is this bad?
-If the field and variable names are the same,
-the field name is redundant.
-
-### Example
-```
-let bar: u8 = 123;
-
-struct Foo {
- bar: u8,
-}
-
-let foo = Foo { bar: bar };
-```
-the last line can be simplified to
-```
-let foo = Foo { bar };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_pattern.txt b/src/tools/clippy/src/docs/redundant_pattern.txt
deleted file mode 100644
index 45f6cfc86..000000000
--- a/src/tools/clippy/src/docs/redundant_pattern.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for patterns in the form `name @ _`.
-
-### Why is this bad?
-It's almost always more readable to just use direct
-bindings.
-
-### Example
-```
-match v {
- Some(x) => (),
- y @ _ => (),
-}
-```
-
-Use instead:
-```
-match v {
- Some(x) => (),
- y => (),
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_pattern_matching.txt b/src/tools/clippy/src/docs/redundant_pattern_matching.txt
deleted file mode 100644
index 77b1021e0..000000000
--- a/src/tools/clippy/src/docs/redundant_pattern_matching.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-### What it does
-Lint for redundant pattern matching over `Result`, `Option`,
-`std::task::Poll` or `std::net::IpAddr`
-
-### Why is this bad?
-It's more concise and clear to just use the proper
-utility function
-
-### Known problems
-This will change the drop order for the matched type. Both `if let` and
-`while let` will drop the value at the end of the block, both `if` and `while` will drop the
-value before entering the block. For most types this change will not matter, but for a few
-types this will not be an acceptable change (e.g. locks). See the
-[reference](https://doc.rust-lang.org/reference/destructors.html#drop-scopes) for more about
-drop order.
-
-### Example
-```
-if let Ok(_) = Ok::<i32, i32>(42) {}
-if let Err(_) = Err::<i32, i32>(42) {}
-if let None = None::<()> {}
-if let Some(_) = Some(42) {}
-if let Poll::Pending = Poll::Pending::<()> {}
-if let Poll::Ready(_) = Poll::Ready(42) {}
-if let IpAddr::V4(_) = IpAddr::V4(Ipv4Addr::LOCALHOST) {}
-if let IpAddr::V6(_) = IpAddr::V6(Ipv6Addr::LOCALHOST) {}
-match Ok::<i32, i32>(42) {
- Ok(_) => true,
- Err(_) => false,
-};
-```
-
-The more idiomatic use would be:
-
-```
-if Ok::<i32, i32>(42).is_ok() {}
-if Err::<i32, i32>(42).is_err() {}
-if None::<()>.is_none() {}
-if Some(42).is_some() {}
-if Poll::Pending::<()>.is_pending() {}
-if Poll::Ready(42).is_ready() {}
-if IpAddr::V4(Ipv4Addr::LOCALHOST).is_ipv4() {}
-if IpAddr::V6(Ipv6Addr::LOCALHOST).is_ipv6() {}
-Ok::<i32, i32>(42).is_ok();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_pub_crate.txt b/src/tools/clippy/src/docs/redundant_pub_crate.txt
deleted file mode 100644
index a527bb5ac..000000000
--- a/src/tools/clippy/src/docs/redundant_pub_crate.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for items declared `pub(crate)` that are not crate visible because they
-are inside a private module.
-
-### Why is this bad?
-Writing `pub(crate)` is misleading when it's redundant due to the parent
-module's visibility.
-
-### Example
-```
-mod internal {
- pub(crate) fn internal_fn() { }
-}
-```
-This function is not visible outside the module and it can be declared with `pub` or
-private visibility
-```
-mod internal {
- pub fn internal_fn() { }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_slicing.txt b/src/tools/clippy/src/docs/redundant_slicing.txt
deleted file mode 100644
index 6798911ed..000000000
--- a/src/tools/clippy/src/docs/redundant_slicing.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for redundant slicing expressions which use the full range, and
-do not change the type.
-
-### Why is this bad?
-It unnecessarily adds complexity to the expression.
-
-### Known problems
-If the type being sliced has an implementation of `Index<RangeFull>`
-that actually changes anything then it can't be removed. However, this would be surprising
-to people reading the code and should have a note with it.
-
-### Example
-```
-fn get_slice(x: &[u32]) -> &[u32] {
- &x[..]
-}
-```
-Use instead:
-```
-fn get_slice(x: &[u32]) -> &[u32] {
- x
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/redundant_static_lifetimes.txt b/src/tools/clippy/src/docs/redundant_static_lifetimes.txt
deleted file mode 100644
index edb8e7b5c..000000000
--- a/src/tools/clippy/src/docs/redundant_static_lifetimes.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for constants and statics with an explicit `'static` lifetime.
-
-### Why is this bad?
-Adding `'static` to every reference can create very
-complicated types.
-
-### Example
-```
-const FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] =
-&[...]
-static FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] =
-&[...]
-```
-This code can be rewritten as
-```
- const FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...]
- static FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...]
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ref_binding_to_reference.txt b/src/tools/clippy/src/docs/ref_binding_to_reference.txt
deleted file mode 100644
index dc391cd98..000000000
--- a/src/tools/clippy/src/docs/ref_binding_to_reference.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for `ref` bindings which create a reference to a reference.
-
-### Why is this bad?
-The address-of operator at the use site is clearer about the need for a reference.
-
-### Example
-```
-let x = Some("");
-if let Some(ref x) = x {
- // use `x` here
-}
-```
-
-Use instead:
-```
-let x = Some("");
-if let Some(x) = x {
- // use `&x` here
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/ref_option_ref.txt b/src/tools/clippy/src/docs/ref_option_ref.txt
deleted file mode 100644
index 951c7bd7f..000000000
--- a/src/tools/clippy/src/docs/ref_option_ref.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for usage of `&Option<&T>`.
-
-### Why is this bad?
-Since `&` is Copy, it's useless to have a
-reference on `Option<&T>`.
-
-### Known problems
-It may be irrelevant to use this lint on
-public API code as it will make a breaking change to apply it.
-
-### Example
-```
-let x: &Option<&u32> = &Some(&0u32);
-```
-Use instead:
-```
-let x: Option<&u32> = Some(&0u32);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/repeat_once.txt b/src/tools/clippy/src/docs/repeat_once.txt
deleted file mode 100644
index 3ba189c19..000000000
--- a/src/tools/clippy/src/docs/repeat_once.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for usage of `.repeat(1)` and suggest the following method for each types.
-- `.to_string()` for `str`
-- `.clone()` for `String`
-- `.to_vec()` for `slice`
-
-The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if
-they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306))
-
-### Why is this bad?
-For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning
-the string is the intention behind this, `clone()` should be used.
-
-### Example
-```
-fn main() {
- let x = String::from("hello world").repeat(1);
-}
-```
-Use instead:
-```
-fn main() {
- let x = String::from("hello world").clone();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/rest_pat_in_fully_bound_structs.txt b/src/tools/clippy/src/docs/rest_pat_in_fully_bound_structs.txt
deleted file mode 100644
index 40ebbe754..000000000
--- a/src/tools/clippy/src/docs/rest_pat_in_fully_bound_structs.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched.
-
-### Why is this bad?
-Correctness and readability. It's like having a wildcard pattern after
-matching all enum variants explicitly.
-
-### Example
-```
-let a = A { a: 5 };
-
-match a {
- A { a: 5, .. } => {},
- _ => {},
-}
-```
-
-Use instead:
-```
-match a {
- A { a: 5 } => {},
- _ => {},
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/result_large_err.txt b/src/tools/clippy/src/docs/result_large_err.txt
deleted file mode 100644
index e5fab3c5c..000000000
--- a/src/tools/clippy/src/docs/result_large_err.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-### What it does
-Checks for functions that return `Result` with an unusually large
-`Err`-variant.
-
-### Why is this bad?
-A `Result` is at least as large as the `Err`-variant. While we
-expect that variant to be seldomly used, the compiler needs to reserve
-and move that much memory every single time.
-
-### Known problems
-The size determined by Clippy is platform-dependent.
-
-### Examples
-```
-pub enum ParseError {
- UnparsedBytes([u8; 512]),
- UnexpectedEof,
-}
-
-// The `Result` has at least 512 bytes, even in the `Ok`-case
-pub fn parse() -> Result<(), ParseError> {
- Ok(())
-}
-```
-should be
-```
-pub enum ParseError {
- UnparsedBytes(Box<[u8; 512]>),
- UnexpectedEof,
-}
-
-// The `Result` is slightly larger than a pointer
-pub fn parse() -> Result<(), ParseError> {
- Ok(())
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/result_map_or_into_option.txt b/src/tools/clippy/src/docs/result_map_or_into_option.txt
deleted file mode 100644
index 899d98c30..000000000
--- a/src/tools/clippy/src/docs/result_map_or_into_option.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usage of `_.map_or(None, Some)`.
-
-### Why is this bad?
-Readability, this can be written more concisely as
-`_.ok()`.
-
-### Example
-```
-assert_eq!(Some(1), r.map_or(None, Some));
-```
-
-Use instead:
-```
-assert_eq!(Some(1), r.ok());
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/result_map_unit_fn.txt b/src/tools/clippy/src/docs/result_map_unit_fn.txt
deleted file mode 100644
index 3455c5c1f..000000000
--- a/src/tools/clippy/src/docs/result_map_unit_fn.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for usage of `result.map(f)` where f is a function
-or closure that returns the unit type `()`.
-
-### Why is this bad?
-Readability, this can be written more clearly with
-an if let statement
-
-### Example
-```
-let x: Result<String, String> = do_stuff();
-x.map(log_err_msg);
-x.map(|msg| log_err_msg(format_msg(msg)));
-```
-
-The correct use would be:
-
-```
-let x: Result<String, String> = do_stuff();
-if let Ok(msg) = x {
- log_err_msg(msg);
-};
-if let Ok(msg) = x {
- log_err_msg(format_msg(msg));
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/result_unit_err.txt b/src/tools/clippy/src/docs/result_unit_err.txt
deleted file mode 100644
index 7c8ec2ffc..000000000
--- a/src/tools/clippy/src/docs/result_unit_err.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-### What it does
-Checks for public functions that return a `Result`
-with an `Err` type of `()`. It suggests using a custom type that
-implements `std::error::Error`.
-
-### Why is this bad?
-Unit does not implement `Error` and carries no
-further information about what went wrong.
-
-### Known problems
-Of course, this lint assumes that `Result` is used
-for a fallible operation (which is after all the intended use). However
-code may opt to (mis)use it as a basic two-variant-enum. In that case,
-the suggestion is misguided, and the code should use a custom enum
-instead.
-
-### Examples
-```
-pub fn read_u8() -> Result<u8, ()> { Err(()) }
-```
-should become
-```
-use std::fmt;
-
-#[derive(Debug)]
-pub struct EndOfStream;
-
-impl fmt::Display for EndOfStream {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "End of Stream")
- }
-}
-
-impl std::error::Error for EndOfStream { }
-
-pub fn read_u8() -> Result<u8, EndOfStream> { Err(EndOfStream) }
-```
-
-Note that there are crates that simplify creating the error type, e.g.
-[`thiserror`](https://docs.rs/thiserror). \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/return_self_not_must_use.txt b/src/tools/clippy/src/docs/return_self_not_must_use.txt
deleted file mode 100644
index 4a4fd2c6e..000000000
--- a/src/tools/clippy/src/docs/return_self_not_must_use.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-### What it does
-This lint warns when a method returning `Self` doesn't have the `#[must_use]` attribute.
-
-### Why is this bad?
-Methods returning `Self` often create new values, having the `#[must_use]` attribute
-prevents users from "forgetting" to use the newly created value.
-
-The `#[must_use]` attribute can be added to the type itself to ensure that instances
-are never forgotten. Functions returning a type marked with `#[must_use]` will not be
-linted, as the usage is already enforced by the type attribute.
-
-### Limitations
-This lint is only applied on methods taking a `self` argument. It would be mostly noise
-if it was added on constructors for example.
-
-### Example
-```
-pub struct Bar;
-impl Bar {
- // Missing attribute
- pub fn bar(&self) -> Self {
- Self
- }
-}
-```
-
-Use instead:
-```
-// It's better to have the `#[must_use]` attribute on the method like this:
-pub struct Bar;
-impl Bar {
- #[must_use]
- pub fn bar(&self) -> Self {
- Self
- }
-}
-
-// Or on the type definition like this:
-#[must_use]
-pub struct Bar;
-impl Bar {
- pub fn bar(&self) -> Self {
- Self
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/reversed_empty_ranges.txt b/src/tools/clippy/src/docs/reversed_empty_ranges.txt
deleted file mode 100644
index 39f481193..000000000
--- a/src/tools/clippy/src/docs/reversed_empty_ranges.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for range expressions `x..y` where both `x` and `y`
-are constant and `x` is greater or equal to `y`.
-
-### Why is this bad?
-Empty ranges yield no values so iterating them is a no-op.
-Moreover, trying to use a reversed range to index a slice will panic at run-time.
-
-### Example
-```
-fn main() {
- (10..=0).for_each(|x| println!("{}", x));
-
- let arr = [1, 2, 3, 4, 5];
- let sub = &arr[3..1];
-}
-```
-Use instead:
-```
-fn main() {
- (0..=10).rev().for_each(|x| println!("{}", x));
-
- let arr = [1, 2, 3, 4, 5];
- let sub = &arr[1..3];
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/same_functions_in_if_condition.txt b/src/tools/clippy/src/docs/same_functions_in_if_condition.txt
deleted file mode 100644
index a0a90eec6..000000000
--- a/src/tools/clippy/src/docs/same_functions_in_if_condition.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-### What it does
-Checks for consecutive `if`s with the same function call.
-
-### Why is this bad?
-This is probably a copy & paste error.
-Despite the fact that function can have side effects and `if` works as
-intended, such an approach is implicit and can be considered a "code smell".
-
-### Example
-```
-if foo() == bar {
- …
-} else if foo() == bar {
- …
-}
-```
-
-This probably should be:
-```
-if foo() == bar {
- …
-} else if foo() == baz {
- …
-}
-```
-
-or if the original code was not a typo and called function mutates a state,
-consider move the mutation out of the `if` condition to avoid similarity to
-a copy & paste error:
-
-```
-let first = foo();
-if first == bar {
- …
-} else {
- let second = foo();
- if second == bar {
- …
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/same_item_push.txt b/src/tools/clippy/src/docs/same_item_push.txt
deleted file mode 100644
index 7e724073f..000000000
--- a/src/tools/clippy/src/docs/same_item_push.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks whether a for loop is being used to push a constant
-value into a Vec.
-
-### Why is this bad?
-This kind of operation can be expressed more succinctly with
-`vec![item; SIZE]` or `vec.resize(NEW_SIZE, item)` and using these alternatives may also
-have better performance.
-
-### Example
-```
-let item1 = 2;
-let item2 = 3;
-let mut vec: Vec<u8> = Vec::new();
-for _ in 0..20 {
- vec.push(item1);
-}
-for _ in 0..30 {
- vec.push(item2);
-}
-```
-
-Use instead:
-```
-let item1 = 2;
-let item2 = 3;
-let mut vec: Vec<u8> = vec![item1; 20];
-vec.resize(20 + 30, item2);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/same_name_method.txt b/src/tools/clippy/src/docs/same_name_method.txt
deleted file mode 100644
index 792dd717f..000000000
--- a/src/tools/clippy/src/docs/same_name_method.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-It lints if a struct has two methods with the same name:
-one from a trait, another not from trait.
-
-### Why is this bad?
-Confusing.
-
-### Example
-```
-trait T {
- fn foo(&self) {}
-}
-
-struct S;
-
-impl T for S {
- fn foo(&self) {}
-}
-
-impl S {
- fn foo(&self) {}
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/search_is_some.txt b/src/tools/clippy/src/docs/search_is_some.txt
deleted file mode 100644
index 67292d545..000000000
--- a/src/tools/clippy/src/docs/search_is_some.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for an iterator or string search (such as `find()`,
-`position()`, or `rposition()`) followed by a call to `is_some()` or `is_none()`.
-
-### Why is this bad?
-Readability, this can be written more concisely as:
-* `_.any(_)`, or `_.contains(_)` for `is_some()`,
-* `!_.any(_)`, or `!_.contains(_)` for `is_none()`.
-
-### Example
-```
-let vec = vec![1];
-vec.iter().find(|x| **x == 0).is_some();
-
-"hello world".find("world").is_none();
-```
-
-Use instead:
-```
-let vec = vec![1];
-vec.iter().any(|x| *x == 0);
-
-!"hello world".contains("world");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/self_assignment.txt b/src/tools/clippy/src/docs/self_assignment.txt
deleted file mode 100644
index ea60ea077..000000000
--- a/src/tools/clippy/src/docs/self_assignment.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Checks for explicit self-assignments.
-
-### Why is this bad?
-Self-assignments are redundant and unlikely to be
-intentional.
-
-### Known problems
-If expression contains any deref coercions or
-indexing operations they are assumed not to have any side effects.
-
-### Example
-```
-struct Event {
- x: i32,
-}
-
-fn copy_position(a: &mut Event, b: &Event) {
- a.x = a.x;
-}
-```
-
-Should be:
-```
-struct Event {
- x: i32,
-}
-
-fn copy_position(a: &mut Event, b: &Event) {
- a.x = b.x;
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/self_named_constructors.txt b/src/tools/clippy/src/docs/self_named_constructors.txt
deleted file mode 100644
index a01669a84..000000000
--- a/src/tools/clippy/src/docs/self_named_constructors.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Warns when constructors have the same name as their types.
-
-### Why is this bad?
-Repeating the name of the type is redundant.
-
-### Example
-```
-struct Foo {}
-
-impl Foo {
- pub fn foo() -> Foo {
- Foo {}
- }
-}
-```
-Use instead:
-```
-struct Foo {}
-
-impl Foo {
- pub fn new() -> Foo {
- Foo {}
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/self_named_module_files.txt b/src/tools/clippy/src/docs/self_named_module_files.txt
deleted file mode 100644
index 73e805136..000000000
--- a/src/tools/clippy/src/docs/self_named_module_files.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks that module layout uses only `mod.rs` files.
-
-### Why is this bad?
-Having multiple module layout styles in a project can be confusing.
-
-### Example
-```
-src/
- stuff/
- stuff_files.rs
- stuff.rs
- lib.rs
-```
-Use instead:
-```
-src/
- stuff/
- stuff_files.rs
- mod.rs
- lib.rs
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/semicolon_if_nothing_returned.txt b/src/tools/clippy/src/docs/semicolon_if_nothing_returned.txt
deleted file mode 100644
index 30c963ca2..000000000
--- a/src/tools/clippy/src/docs/semicolon_if_nothing_returned.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Looks for blocks of expressions and fires if the last expression returns
-`()` but is not followed by a semicolon.
-
-### Why is this bad?
-The semicolon might be optional but when extending the block with new
-code, it doesn't require a change in previous last line.
-
-### Example
-```
-fn main() {
- println!("Hello world")
-}
-```
-Use instead:
-```
-fn main() {
- println!("Hello world");
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/separated_literal_suffix.txt b/src/tools/clippy/src/docs/separated_literal_suffix.txt
deleted file mode 100644
index 226a6b8a9..000000000
--- a/src/tools/clippy/src/docs/separated_literal_suffix.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Warns if literal suffixes are separated by an underscore.
-To enforce separated literal suffix style,
-see the `unseparated_literal_suffix` lint.
-
-### Why is this bad?
-Suffix style should be consistent.
-
-### Example
-```
-123832_i32
-```
-
-Use instead:
-```
-123832i32
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/serde_api_misuse.txt b/src/tools/clippy/src/docs/serde_api_misuse.txt
deleted file mode 100644
index 8a3c89ac1..000000000
--- a/src/tools/clippy/src/docs/serde_api_misuse.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-### What it does
-Checks for mis-uses of the serde API.
-
-### Why is this bad?
-Serde is very finnicky about how its API should be
-used, but the type system can't be used to enforce it (yet?).
-
-### Example
-Implementing `Visitor::visit_string` but not
-`Visitor::visit_str`. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/shadow_reuse.txt b/src/tools/clippy/src/docs/shadow_reuse.txt
deleted file mode 100644
index 9eb8e7ad1..000000000
--- a/src/tools/clippy/src/docs/shadow_reuse.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for bindings that shadow other bindings already in
-scope, while reusing the original value.
-
-### Why is this bad?
-Not too much, in fact it's a common pattern in Rust
-code. Still, some argue that name shadowing like this hurts readability,
-because a value may be bound to different things depending on position in
-the code.
-
-### Example
-```
-let x = 2;
-let x = x + 1;
-```
-use different variable name:
-```
-let x = 2;
-let y = x + 1;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/shadow_same.txt b/src/tools/clippy/src/docs/shadow_same.txt
deleted file mode 100644
index 3cd96f560..000000000
--- a/src/tools/clippy/src/docs/shadow_same.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for bindings that shadow other bindings already in
-scope, while just changing reference level or mutability.
-
-### Why is this bad?
-Not much, in fact it's a very common pattern in Rust
-code. Still, some may opt to avoid it in their code base, they can set this
-lint to `Warn`.
-
-### Example
-```
-let x = &x;
-```
-
-Use instead:
-```
-let y = &x; // use different variable name
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/shadow_unrelated.txt b/src/tools/clippy/src/docs/shadow_unrelated.txt
deleted file mode 100644
index 436251c52..000000000
--- a/src/tools/clippy/src/docs/shadow_unrelated.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for bindings that shadow other bindings already in
-scope, either without an initialization or with one that does not even use
-the original value.
-
-### Why is this bad?
-Name shadowing can hurt readability, especially in
-large code bases, because it is easy to lose track of the active binding at
-any place in the code. This can be alleviated by either giving more specific
-names to bindings or introducing more scopes to contain the bindings.
-
-### Example
-```
-let x = y;
-let x = z; // shadows the earlier binding
-```
-
-Use instead:
-```
-let x = y;
-let w = z; // use different variable name
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/short_circuit_statement.txt b/src/tools/clippy/src/docs/short_circuit_statement.txt
deleted file mode 100644
index 31492bed0..000000000
--- a/src/tools/clippy/src/docs/short_circuit_statement.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for the use of short circuit boolean conditions as
-a
-statement.
-
-### Why is this bad?
-Using a short circuit boolean condition as a statement
-may hide the fact that the second part is executed or not depending on the
-outcome of the first part.
-
-### Example
-```
-f() && g(); // We should write `if f() { g(); }`.
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/should_implement_trait.txt b/src/tools/clippy/src/docs/should_implement_trait.txt
deleted file mode 100644
index 02e74751a..000000000
--- a/src/tools/clippy/src/docs/should_implement_trait.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for methods that should live in a trait
-implementation of a `std` trait (see [llogiq's blog
-post](http://llogiq.github.io/2015/07/30/traits.html) for further
-information) instead of an inherent implementation.
-
-### Why is this bad?
-Implementing the traits improve ergonomics for users of
-the code, often with very little cost. Also people seeing a `mul(...)`
-method
-may expect `*` to work equally, so you should have good reason to disappoint
-them.
-
-### Example
-```
-struct X;
-impl X {
- fn add(&self, other: &X) -> X {
- // ..
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/significant_drop_in_scrutinee.txt b/src/tools/clippy/src/docs/significant_drop_in_scrutinee.txt
deleted file mode 100644
index f869def0d..000000000
--- a/src/tools/clippy/src/docs/significant_drop_in_scrutinee.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-### What it does
-Check for temporaries returned from function calls in a match scrutinee that have the
-`clippy::has_significant_drop` attribute.
-
-### Why is this bad?
-The `clippy::has_significant_drop` attribute can be added to types whose Drop impls have
-an important side-effect, such as unlocking a mutex, making it important for users to be
-able to accurately understand their lifetimes. When a temporary is returned in a function
-call in a match scrutinee, its lifetime lasts until the end of the match block, which may
-be surprising.
-
-For `Mutex`es this can lead to a deadlock. This happens when the match scrutinee uses a
-function call that returns a `MutexGuard` and then tries to lock again in one of the match
-arms. In that case the `MutexGuard` in the scrutinee will not be dropped until the end of
-the match block and thus will not unlock.
-
-### Example
-```
-let mutex = Mutex::new(State {});
-
-match mutex.lock().unwrap().foo() {
- true => {
- mutex.lock().unwrap().bar(); // Deadlock!
- }
- false => {}
-};
-
-println!("All done!");
-```
-Use instead:
-```
-let mutex = Mutex::new(State {});
-
-let is_foo = mutex.lock().unwrap().foo();
-match is_foo {
- true => {
- mutex.lock().unwrap().bar();
- }
- false => {}
-};
-
-println!("All done!");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/similar_names.txt b/src/tools/clippy/src/docs/similar_names.txt
deleted file mode 100644
index f9eff21b6..000000000
--- a/src/tools/clippy/src/docs/similar_names.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for names that are very similar and thus confusing.
-
-Note: this lint looks for similar names throughout each
-scope. To allow it, you need to allow it on the scope
-level, not on the name that is reported.
-
-### Why is this bad?
-It's hard to distinguish between names that differ only
-by a single character.
-
-### Example
-```
-let checked_exp = something;
-let checked_expr = something_else;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_char_add_str.txt b/src/tools/clippy/src/docs/single_char_add_str.txt
deleted file mode 100644
index cf23dc0c8..000000000
--- a/src/tools/clippy/src/docs/single_char_add_str.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Warns when using `push_str`/`insert_str` with a single-character string literal
-where `push`/`insert` with a `char` would work fine.
-
-### Why is this bad?
-It's less clear that we are pushing a single character.
-
-### Example
-```
-string.insert_str(0, "R");
-string.push_str("R");
-```
-
-Use instead:
-```
-string.insert(0, 'R');
-string.push('R');
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_char_lifetime_names.txt b/src/tools/clippy/src/docs/single_char_lifetime_names.txt
deleted file mode 100644
index 92dd24bf2..000000000
--- a/src/tools/clippy/src/docs/single_char_lifetime_names.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for lifetimes with names which are one character
-long.
-
-### Why is this bad?
-A single character is likely not enough to express the
-purpose of a lifetime. Using a longer name can make code
-easier to understand, especially for those who are new to
-Rust.
-
-### Known problems
-Rust programmers and learning resources tend to use single
-character lifetimes, so this lint is at odds with the
-ecosystem at large. In addition, the lifetime's purpose may
-be obvious or, rarely, expressible in one character.
-
-### Example
-```
-struct DiagnosticCtx<'a> {
- source: &'a str,
-}
-```
-Use instead:
-```
-struct DiagnosticCtx<'src> {
- source: &'src str,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_char_pattern.txt b/src/tools/clippy/src/docs/single_char_pattern.txt
deleted file mode 100644
index 9e5ad1e7d..000000000
--- a/src/tools/clippy/src/docs/single_char_pattern.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for string methods that receive a single-character
-`str` as an argument, e.g., `_.split("x")`.
-
-### Why is this bad?
-Performing these methods using a `char` is faster than
-using a `str`.
-
-### Known problems
-Does not catch multi-byte unicode characters.
-
-### Example
-```
-_.split("x");
-```
-
-Use instead:
-```
-_.split('x');
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_component_path_imports.txt b/src/tools/clippy/src/docs/single_component_path_imports.txt
deleted file mode 100644
index 3a0263881..000000000
--- a/src/tools/clippy/src/docs/single_component_path_imports.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checking for imports with single component use path.
-
-### Why is this bad?
-Import with single component use path such as `use cratename;`
-is not necessary, and thus should be removed.
-
-### Example
-```
-use regex;
-
-fn main() {
- regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
-}
-```
-Better as
-```
-fn main() {
- regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_element_loop.txt b/src/tools/clippy/src/docs/single_element_loop.txt
deleted file mode 100644
index 6f0c15a85..000000000
--- a/src/tools/clippy/src/docs/single_element_loop.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks whether a for loop has a single element.
-
-### Why is this bad?
-There is no reason to have a loop of a
-single element.
-
-### Example
-```
-let item1 = 2;
-for item in &[item1] {
- println!("{}", item);
-}
-```
-
-Use instead:
-```
-let item1 = 2;
-let item = &item1;
-println!("{}", item);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_match.txt b/src/tools/clippy/src/docs/single_match.txt
deleted file mode 100644
index 31dde4da8..000000000
--- a/src/tools/clippy/src/docs/single_match.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for matches with a single arm where an `if let`
-will usually suffice.
-
-### Why is this bad?
-Just readability – `if let` nests less than a `match`.
-
-### Example
-```
-match x {
- Some(ref foo) => bar(foo),
- _ => (),
-}
-```
-
-Use instead:
-```
-if let Some(ref foo) = x {
- bar(foo);
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/single_match_else.txt b/src/tools/clippy/src/docs/single_match_else.txt
deleted file mode 100644
index 29a447af0..000000000
--- a/src/tools/clippy/src/docs/single_match_else.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for matches with two arms where an `if let else` will
-usually suffice.
-
-### Why is this bad?
-Just readability – `if let` nests less than a `match`.
-
-### Known problems
-Personal style preferences may differ.
-
-### Example
-Using `match`:
-
-```
-match x {
- Some(ref foo) => bar(foo),
- _ => bar(&other_ref),
-}
-```
-
-Using `if let` with `else`:
-
-```
-if let Some(ref foo) = x {
- bar(foo);
-} else {
- bar(&other_ref);
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/size_of_in_element_count.txt b/src/tools/clippy/src/docs/size_of_in_element_count.txt
deleted file mode 100644
index d893ec6a2..000000000
--- a/src/tools/clippy/src/docs/size_of_in_element_count.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Detects expressions where
-`size_of::<T>` or `size_of_val::<T>` is used as a
-count of elements of type `T`
-
-### Why is this bad?
-These functions expect a count
-of `T` and not a number of bytes
-
-### Example
-```
-const SIZE: usize = 128;
-let x = [2u8; SIZE];
-let mut y = [2u8; SIZE];
-unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/skip_while_next.txt b/src/tools/clippy/src/docs/skip_while_next.txt
deleted file mode 100644
index 1ec8a3a28..000000000
--- a/src/tools/clippy/src/docs/skip_while_next.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for usage of `_.skip_while(condition).next()`.
-
-### Why is this bad?
-Readability, this can be written more concisely as
-`_.find(!condition)`.
-
-### Example
-```
-vec.iter().skip_while(|x| **x == 0).next();
-```
-
-Use instead:
-```
-vec.iter().find(|x| **x != 0);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/slow_vector_initialization.txt b/src/tools/clippy/src/docs/slow_vector_initialization.txt
deleted file mode 100644
index 53442e179..000000000
--- a/src/tools/clippy/src/docs/slow_vector_initialization.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks slow zero-filled vector initialization
-
-### Why is this bad?
-These structures are non-idiomatic and less efficient than simply using
-`vec![0; len]`.
-
-### Example
-```
-let mut vec1 = Vec::with_capacity(len);
-vec1.resize(len, 0);
-
-let mut vec1 = Vec::with_capacity(len);
-vec1.resize(vec1.capacity(), 0);
-
-let mut vec2 = Vec::with_capacity(len);
-vec2.extend(repeat(0).take(len));
-```
-
-Use instead:
-```
-let mut vec1 = vec![0; len];
-let mut vec2 = vec![0; len];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/stable_sort_primitive.txt b/src/tools/clippy/src/docs/stable_sort_primitive.txt
deleted file mode 100644
index 6465dbee4..000000000
--- a/src/tools/clippy/src/docs/stable_sort_primitive.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-### What it does
-When sorting primitive values (integers, bools, chars, as well
-as arrays, slices, and tuples of such items), it is typically better to
-use an unstable sort than a stable sort.
-
-### Why is this bad?
-Typically, using a stable sort consumes more memory and cpu cycles.
-Because values which compare equal are identical, preserving their
-relative order (the guarantee that a stable sort provides) means
-nothing, while the extra costs still apply.
-
-### Known problems
-
-As pointed out in
-[issue #8241](https://github.com/rust-lang/rust-clippy/issues/8241),
-a stable sort can instead be significantly faster for certain scenarios
-(eg. when a sorted vector is extended with new data and resorted).
-
-For more information and benchmarking results, please refer to the
-issue linked above.
-
-### Example
-```
-let mut vec = vec![2, 1, 3];
-vec.sort();
-```
-Use instead:
-```
-let mut vec = vec![2, 1, 3];
-vec.sort_unstable();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/std_instead_of_alloc.txt b/src/tools/clippy/src/docs/std_instead_of_alloc.txt
deleted file mode 100644
index c2d32704e..000000000
--- a/src/tools/clippy/src/docs/std_instead_of_alloc.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-
-Finds items imported through `std` when available through `alloc`.
-
-### Why is this bad?
-
-Crates which have `no_std` compatibility and require alloc may wish to ensure types are imported from
-alloc to ensure disabling `std` does not cause the crate to fail to compile. This lint is also useful
-for crates migrating to become `no_std` compatible.
-
-### Example
-```
-use std::vec::Vec;
-```
-Use instead:
-```
-use alloc::vec::Vec;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/std_instead_of_core.txt b/src/tools/clippy/src/docs/std_instead_of_core.txt
deleted file mode 100644
index f1e1518c6..000000000
--- a/src/tools/clippy/src/docs/std_instead_of_core.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-
-Finds items imported through `std` when available through `core`.
-
-### Why is this bad?
-
-Crates which have `no_std` compatibility may wish to ensure types are imported from core to ensure
-disabling `std` does not cause the crate to fail to compile. This lint is also useful for crates
-migrating to become `no_std` compatible.
-
-### Example
-```
-use std::hash::Hasher;
-```
-Use instead:
-```
-use core::hash::Hasher;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/str_to_string.txt b/src/tools/clippy/src/docs/str_to_string.txt
deleted file mode 100644
index a24755223..000000000
--- a/src/tools/clippy/src/docs/str_to_string.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-This lint checks for `.to_string()` method calls on values of type `&str`.
-
-### Why is this bad?
-The `to_string` method is also used on other types to convert them to a string.
-When called on a `&str` it turns the `&str` into the owned variant `String`, which can be better
-expressed with `.to_owned()`.
-
-### Example
-```
-// example code where clippy issues a warning
-let _ = "str".to_string();
-```
-Use instead:
-```
-// example code which does not raise clippy warning
-let _ = "str".to_owned();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_add.txt b/src/tools/clippy/src/docs/string_add.txt
deleted file mode 100644
index 23dafd0d0..000000000
--- a/src/tools/clippy/src/docs/string_add.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for all instances of `x + _` where `x` is of type
-`String`, but only if [`string_add_assign`](#string_add_assign) does *not*
-match.
-
-### Why is this bad?
-It's not bad in and of itself. However, this particular
-`Add` implementation is asymmetric (the other operand need not be `String`,
-but `x` does), while addition as mathematically defined is symmetric, also
-the `String::push_str(_)` function is a perfectly good replacement.
-Therefore, some dislike it and wish not to have it in their code.
-
-That said, other people think that string addition, having a long tradition
-in other languages is actually fine, which is why we decided to make this
-particular lint `allow` by default.
-
-### Example
-```
-let x = "Hello".to_owned();
-x + ", World";
-```
-
-Use instead:
-```
-let mut x = "Hello".to_owned();
-x.push_str(", World");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_add_assign.txt b/src/tools/clippy/src/docs/string_add_assign.txt
deleted file mode 100644
index 7438be855..000000000
--- a/src/tools/clippy/src/docs/string_add_assign.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for string appends of the form `x = x + y` (without
-`let`!).
-
-### Why is this bad?
-It's not really bad, but some people think that the
-`.push_str(_)` method is more readable.
-
-### Example
-```
-let mut x = "Hello".to_owned();
-x = x + ", World";
-
-// More readable
-x += ", World";
-x.push_str(", World");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_extend_chars.txt b/src/tools/clippy/src/docs/string_extend_chars.txt
deleted file mode 100644
index 619ea3e11..000000000
--- a/src/tools/clippy/src/docs/string_extend_chars.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for the use of `.extend(s.chars())` where s is a
-`&str` or `String`.
-
-### Why is this bad?
-`.push_str(s)` is clearer
-
-### Example
-```
-let abc = "abc";
-let def = String::from("def");
-let mut s = String::new();
-s.extend(abc.chars());
-s.extend(def.chars());
-```
-The correct use would be:
-```
-let abc = "abc";
-let def = String::from("def");
-let mut s = String::new();
-s.push_str(abc);
-s.push_str(&def);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_from_utf8_as_bytes.txt b/src/tools/clippy/src/docs/string_from_utf8_as_bytes.txt
deleted file mode 100644
index 9102d7347..000000000
--- a/src/tools/clippy/src/docs/string_from_utf8_as_bytes.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Check if the string is transformed to byte array and casted back to string.
-
-### Why is this bad?
-It's unnecessary, the string can be used directly.
-
-### Example
-```
-std::str::from_utf8(&"Hello World!".as_bytes()[6..11]).unwrap();
-```
-
-Use instead:
-```
-&"Hello World!"[6..11];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_lit_as_bytes.txt b/src/tools/clippy/src/docs/string_lit_as_bytes.txt
deleted file mode 100644
index a125b97ed..000000000
--- a/src/tools/clippy/src/docs/string_lit_as_bytes.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-### What it does
-Checks for the `as_bytes` method called on string literals
-that contain only ASCII characters.
-
-### Why is this bad?
-Byte string literals (e.g., `b"foo"`) can be used
-instead. They are shorter but less discoverable than `as_bytes()`.
-
-### Known problems
-`"str".as_bytes()` and the suggested replacement of `b"str"` are not
-equivalent because they have different types. The former is `&[u8]`
-while the latter is `&[u8; 3]`. That means in general they will have a
-different set of methods and different trait implementations.
-
-```
-fn f(v: Vec<u8>) {}
-
-f("...".as_bytes().to_owned()); // works
-f(b"...".to_owned()); // does not work, because arg is [u8; 3] not Vec<u8>
-
-fn g(r: impl std::io::Read) {}
-
-g("...".as_bytes()); // works
-g(b"..."); // does not work
-```
-
-The actual equivalent of `"str".as_bytes()` with the same type is not
-`b"str"` but `&b"str"[..]`, which is a great deal of punctuation and not
-more readable than a function call.
-
-### Example
-```
-let bstr = "a byte string".as_bytes();
-```
-
-Use instead:
-```
-let bstr = b"a byte string";
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_slice.txt b/src/tools/clippy/src/docs/string_slice.txt
deleted file mode 100644
index 3d9e49dd3..000000000
--- a/src/tools/clippy/src/docs/string_slice.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for slice operations on strings
-
-### Why is this bad?
-UTF-8 characters span multiple bytes, and it is easy to inadvertently confuse character
-counts and string indices. This may lead to panics, and should warrant some test cases
-containing wide UTF-8 characters. This lint is most useful in code that should avoid
-panics at all costs.
-
-### Known problems
-Probably lots of false positives. If an index comes from a known valid position (e.g.
-obtained via `char_indices` over the same string), it is totally OK.
-
-# Example
-```
-&"Ölkanne"[1..];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/string_to_string.txt b/src/tools/clippy/src/docs/string_to_string.txt
deleted file mode 100644
index deb7eebe7..000000000
--- a/src/tools/clippy/src/docs/string_to_string.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-This lint checks for `.to_string()` method calls on values of type `String`.
-
-### Why is this bad?
-The `to_string` method is also used on other types to convert them to a string.
-When called on a `String` it only clones the `String`, which can be better expressed with `.clone()`.
-
-### Example
-```
-// example code where clippy issues a warning
-let msg = String::from("Hello World");
-let _ = msg.to_string();
-```
-Use instead:
-```
-// example code which does not raise clippy warning
-let msg = String::from("Hello World");
-let _ = msg.clone();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/strlen_on_c_strings.txt b/src/tools/clippy/src/docs/strlen_on_c_strings.txt
deleted file mode 100644
index 0454abf55..000000000
--- a/src/tools/clippy/src/docs/strlen_on_c_strings.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for usage of `libc::strlen` on a `CString` or `CStr` value,
-and suggest calling `as_bytes().len()` or `to_bytes().len()` respectively instead.
-
-### Why is this bad?
-This avoids calling an unsafe `libc` function.
-Currently, it also avoids calculating the length.
-
-### Example
-```
-use std::ffi::CString;
-let cstring = CString::new("foo").expect("CString::new failed");
-let len = unsafe { libc::strlen(cstring.as_ptr()) };
-```
-Use instead:
-```
-use std::ffi::CString;
-let cstring = CString::new("foo").expect("CString::new failed");
-let len = cstring.as_bytes().len();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/struct_excessive_bools.txt b/src/tools/clippy/src/docs/struct_excessive_bools.txt
deleted file mode 100644
index 9e197c786..000000000
--- a/src/tools/clippy/src/docs/struct_excessive_bools.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-### What it does
-Checks for excessive
-use of bools in structs.
-
-### Why is this bad?
-Excessive bools in a struct
-is often a sign that it's used as a state machine,
-which is much better implemented as an enum.
-If it's not the case, excessive bools usually benefit
-from refactoring into two-variant enums for better
-readability and API.
-
-### Example
-```
-struct S {
- is_pending: bool,
- is_processing: bool,
- is_finished: bool,
-}
-```
-
-Use instead:
-```
-enum S {
- Pending,
- Processing,
- Finished,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suboptimal_flops.txt b/src/tools/clippy/src/docs/suboptimal_flops.txt
deleted file mode 100644
index f1c9c665b..000000000
--- a/src/tools/clippy/src/docs/suboptimal_flops.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-### What it does
-Looks for floating-point expressions that
-can be expressed using built-in methods to improve both
-accuracy and performance.
-
-### Why is this bad?
-Negatively impacts accuracy and performance.
-
-### Example
-```
-use std::f32::consts::E;
-
-let a = 3f32;
-let _ = (2f32).powf(a);
-let _ = E.powf(a);
-let _ = a.powf(1.0 / 2.0);
-let _ = a.log(2.0);
-let _ = a.log(10.0);
-let _ = a.log(E);
-let _ = a.powf(2.0);
-let _ = a * 2.0 + 4.0;
-let _ = if a < 0.0 {
- -a
-} else {
- a
-};
-let _ = if a < 0.0 {
- a
-} else {
- -a
-};
-```
-
-is better expressed as
-
-```
-use std::f32::consts::E;
-
-let a = 3f32;
-let _ = a.exp2();
-let _ = a.exp();
-let _ = a.sqrt();
-let _ = a.log2();
-let _ = a.log10();
-let _ = a.ln();
-let _ = a.powi(2);
-let _ = a.mul_add(2.0, 4.0);
-let _ = a.abs();
-let _ = -a.abs();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_arithmetic_impl.txt b/src/tools/clippy/src/docs/suspicious_arithmetic_impl.txt
deleted file mode 100644
index d67ff2793..000000000
--- a/src/tools/clippy/src/docs/suspicious_arithmetic_impl.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Lints for suspicious operations in impls of arithmetic operators, e.g.
-subtracting elements in an Add impl.
-
-### Why is this bad?
-This is probably a typo or copy-and-paste error and not intended.
-
-### Example
-```
-impl Add for Foo {
- type Output = Foo;
-
- fn add(self, other: Foo) -> Foo {
- Foo(self.0 - other.0)
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_assignment_formatting.txt b/src/tools/clippy/src/docs/suspicious_assignment_formatting.txt
deleted file mode 100644
index b889827cd..000000000
--- a/src/tools/clippy/src/docs/suspicious_assignment_formatting.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for use of the non-existent `=*`, `=!` and `=-`
-operators.
-
-### Why is this bad?
-This is either a typo of `*=`, `!=` or `-=` or
-confusing.
-
-### Example
-```
-a =- 42; // confusing, should it be `a -= 42` or `a = -42`?
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_else_formatting.txt b/src/tools/clippy/src/docs/suspicious_else_formatting.txt
deleted file mode 100644
index 3cf2f7486..000000000
--- a/src/tools/clippy/src/docs/suspicious_else_formatting.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-### What it does
-Checks for formatting of `else`. It lints if the `else`
-is followed immediately by a newline or the `else` seems to be missing.
-
-### Why is this bad?
-This is probably some refactoring remnant, even if the
-code is correct, it might look confusing.
-
-### Example
-```
-if foo {
-} { // looks like an `else` is missing here
-}
-
-if foo {
-} if bar { // looks like an `else` is missing here
-}
-
-if foo {
-} else
-
-{ // this is the `else` block of the previous `if`, but should it be?
-}
-
-if foo {
-} else
-
-if bar { // this is the `else` block of the previous `if`, but should it be?
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_map.txt b/src/tools/clippy/src/docs/suspicious_map.txt
deleted file mode 100644
index d8fa52c43..000000000
--- a/src/tools/clippy/src/docs/suspicious_map.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for calls to `map` followed by a `count`.
-
-### Why is this bad?
-It looks suspicious. Maybe `map` was confused with `filter`.
-If the `map` call is intentional, this should be rewritten
-using `inspect`. Or, if you intend to drive the iterator to
-completion, you can just use `for_each` instead.
-
-### Example
-```
-let _ = (0..3).map(|x| x + 2).count();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_op_assign_impl.txt b/src/tools/clippy/src/docs/suspicious_op_assign_impl.txt
deleted file mode 100644
index 81abfbeca..000000000
--- a/src/tools/clippy/src/docs/suspicious_op_assign_impl.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Lints for suspicious operations in impls of OpAssign, e.g.
-subtracting elements in an AddAssign impl.
-
-### Why is this bad?
-This is probably a typo or copy-and-paste error and not intended.
-
-### Example
-```
-impl AddAssign for Foo {
- fn add_assign(&mut self, other: Foo) {
- *self = *self - other;
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_operation_groupings.txt b/src/tools/clippy/src/docs/suspicious_operation_groupings.txt
deleted file mode 100644
index 81ede5d3d..000000000
--- a/src/tools/clippy/src/docs/suspicious_operation_groupings.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-### What it does
-Checks for unlikely usages of binary operators that are almost
-certainly typos and/or copy/paste errors, given the other usages
-of binary operators nearby.
-
-### Why is this bad?
-They are probably bugs and if they aren't then they look like bugs
-and you should add a comment explaining why you are doing such an
-odd set of operations.
-
-### Known problems
-There may be some false positives if you are trying to do something
-unusual that happens to look like a typo.
-
-### Example
-```
-struct Vec3 {
- x: f64,
- y: f64,
- z: f64,
-}
-
-impl Eq for Vec3 {}
-
-impl PartialEq for Vec3 {
- fn eq(&self, other: &Self) -> bool {
- // This should trigger the lint because `self.x` is compared to `other.y`
- self.x == other.y && self.y == other.y && self.z == other.z
- }
-}
-```
-Use instead:
-```
-// same as above except:
-impl PartialEq for Vec3 {
- fn eq(&self, other: &Self) -> bool {
- // Note we now compare other.x to self.x
- self.x == other.x && self.y == other.y && self.z == other.z
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_splitn.txt b/src/tools/clippy/src/docs/suspicious_splitn.txt
deleted file mode 100644
index 79a3dbfa6..000000000
--- a/src/tools/clippy/src/docs/suspicious_splitn.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for calls to [`splitn`]
-(https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and
-related functions with either zero or one splits.
-
-### Why is this bad?
-These calls don't actually split the value and are
-likely to be intended as a different number.
-
-### Example
-```
-for x in s.splitn(1, ":") {
- // ..
-}
-```
-
-Use instead:
-```
-for x in s.splitn(2, ":") {
- // ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_to_owned.txt b/src/tools/clippy/src/docs/suspicious_to_owned.txt
deleted file mode 100644
index 8cbf61dc7..000000000
--- a/src/tools/clippy/src/docs/suspicious_to_owned.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-### What it does
-Checks for the usage of `_.to_owned()`, on a `Cow<'_, _>`.
-
-### Why is this bad?
-Calling `to_owned()` on a `Cow` creates a clone of the `Cow`
-itself, without taking ownership of the `Cow` contents (i.e.
-it's equivalent to calling `Cow::clone`).
-The similarly named `into_owned` method, on the other hand,
-clones the `Cow` contents, effectively turning any `Cow::Borrowed`
-into a `Cow::Owned`.
-
-Given the potential ambiguity, consider replacing `to_owned`
-with `clone` for better readability or, if getting a `Cow::Owned`
-was the original intent, using `into_owned` instead.
-
-### Example
-```
-let s = "Hello world!";
-let cow = Cow::Borrowed(s);
-
-let data = cow.to_owned();
-assert!(matches!(data, Cow::Borrowed(_)))
-```
-Use instead:
-```
-let s = "Hello world!";
-let cow = Cow::Borrowed(s);
-
-let data = cow.clone();
-assert!(matches!(data, Cow::Borrowed(_)))
-```
-or
-```
-let s = "Hello world!";
-let cow = Cow::Borrowed(s);
-
-let data = cow.into_owned();
-assert!(matches!(data, String))
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/suspicious_unary_op_formatting.txt b/src/tools/clippy/src/docs/suspicious_unary_op_formatting.txt
deleted file mode 100644
index 06fb09db7..000000000
--- a/src/tools/clippy/src/docs/suspicious_unary_op_formatting.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks the formatting of a unary operator on the right hand side
-of a binary operator. It lints if there is no space between the binary and unary operators,
-but there is a space between the unary and its operand.
-
-### Why is this bad?
-This is either a typo in the binary operator or confusing.
-
-### Example
-```
-// &&! looks like a different operator
-if foo &&! bar {}
-```
-
-Use instead:
-```
-if foo && !bar {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/swap_ptr_to_ref.txt b/src/tools/clippy/src/docs/swap_ptr_to_ref.txt
deleted file mode 100644
index 0215d1e8a..000000000
--- a/src/tools/clippy/src/docs/swap_ptr_to_ref.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for calls to `core::mem::swap` where either parameter is derived from a pointer
-
-### Why is this bad?
-When at least one parameter to `swap` is derived from a pointer it may overlap with the
-other. This would then lead to undefined behavior.
-
-### Example
-```
-unsafe fn swap(x: &[*mut u32], y: &[*mut u32]) {
- for (&x, &y) in x.iter().zip(y) {
- core::mem::swap(&mut *x, &mut *y);
- }
-}
-```
-Use instead:
-```
-unsafe fn swap(x: &[*mut u32], y: &[*mut u32]) {
- for (&x, &y) in x.iter().zip(y) {
- core::ptr::swap(x, y);
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/tabs_in_doc_comments.txt b/src/tools/clippy/src/docs/tabs_in_doc_comments.txt
deleted file mode 100644
index f83dbe2b7..000000000
--- a/src/tools/clippy/src/docs/tabs_in_doc_comments.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-### What it does
-Checks doc comments for usage of tab characters.
-
-### Why is this bad?
-The rust style-guide promotes spaces instead of tabs for indentation.
-To keep a consistent view on the source, also doc comments should not have tabs.
-Also, explaining ascii-diagrams containing tabs can get displayed incorrectly when the
-display settings of the author and reader differ.
-
-### Example
-```
-///
-/// Struct to hold two strings:
-/// - first one
-/// - second one
-pub struct DoubleString {
- ///
- /// - First String:
- /// - needs to be inside here
- first_string: String,
- ///
- /// - Second String:
- /// - needs to be inside here
- second_string: String,
-}
-```
-
-Will be converted to:
-```
-///
-/// Struct to hold two strings:
-/// - first one
-/// - second one
-pub struct DoubleString {
- ///
- /// - First String:
- /// - needs to be inside here
- first_string: String,
- ///
- /// - Second String:
- /// - needs to be inside here
- second_string: String,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/temporary_assignment.txt b/src/tools/clippy/src/docs/temporary_assignment.txt
deleted file mode 100644
index 195b42cf0..000000000
--- a/src/tools/clippy/src/docs/temporary_assignment.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for construction of a structure or tuple just to
-assign a value in it.
-
-### Why is this bad?
-Readability. If the structure is only created to be
-updated, why not write the structure you want in the first place?
-
-### Example
-```
-(0, 0).0 = 1
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/to_digit_is_some.txt b/src/tools/clippy/src/docs/to_digit_is_some.txt
deleted file mode 100644
index eee8375ad..000000000
--- a/src/tools/clippy/src/docs/to_digit_is_some.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for `.to_digit(..).is_some()` on `char`s.
-
-### Why is this bad?
-This is a convoluted way of checking if a `char` is a digit. It's
-more straight forward to use the dedicated `is_digit` method.
-
-### Example
-```
-let is_digit = c.to_digit(radix).is_some();
-```
-can be written as:
-```
-let is_digit = c.is_digit(radix);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/to_string_in_format_args.txt b/src/tools/clippy/src/docs/to_string_in_format_args.txt
deleted file mode 100644
index 34b205835..000000000
--- a/src/tools/clippy/src/docs/to_string_in_format_args.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for [`ToString::to_string`](https://doc.rust-lang.org/std/string/trait.ToString.html#tymethod.to_string)
-applied to a type that implements [`Display`](https://doc.rust-lang.org/std/fmt/trait.Display.html)
-in a macro that does formatting.
-
-### Why is this bad?
-Since the type implements `Display`, the use of `to_string` is
-unnecessary.
-
-### Example
-```
-println!("error: something failed at {}", Location::caller().to_string());
-```
-Use instead:
-```
-println!("error: something failed at {}", Location::caller());
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/todo.txt b/src/tools/clippy/src/docs/todo.txt
deleted file mode 100644
index 661eb1ac5..000000000
--- a/src/tools/clippy/src/docs/todo.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-### What it does
-Checks for usage of `todo!`.
-
-### Why is this bad?
-This macro should not be present in production code
-
-### Example
-```
-todo!();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/too_many_arguments.txt b/src/tools/clippy/src/docs/too_many_arguments.txt
deleted file mode 100644
index 4669f9f82..000000000
--- a/src/tools/clippy/src/docs/too_many_arguments.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for functions with too many parameters.
-
-### Why is this bad?
-Functions with lots of parameters are considered bad
-style and reduce readability (“what does the 5th parameter mean?â€). Consider
-grouping some parameters into a new type.
-
-### Example
-```
-fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) {
- // ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/too_many_lines.txt b/src/tools/clippy/src/docs/too_many_lines.txt
deleted file mode 100644
index 425db348b..000000000
--- a/src/tools/clippy/src/docs/too_many_lines.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for functions with a large amount of lines.
-
-### Why is this bad?
-Functions with a lot of lines are harder to understand
-due to having to look at a larger amount of code to understand what the
-function is doing. Consider splitting the body of the function into
-multiple functions.
-
-### Example
-```
-fn im_too_long() {
- println!("");
- // ... 100 more LoC
- println!("");
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/toplevel_ref_arg.txt b/src/tools/clippy/src/docs/toplevel_ref_arg.txt
deleted file mode 100644
index 96a9e2db8..000000000
--- a/src/tools/clippy/src/docs/toplevel_ref_arg.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for function arguments and let bindings denoted as
-`ref`.
-
-### Why is this bad?
-The `ref` declaration makes the function take an owned
-value, but turns the argument into a reference (which means that the value
-is destroyed when exiting the function). This adds not much value: either
-take a reference type, or take an owned value and create references in the
-body.
-
-For let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The
-type of `x` is more obvious with the former.
-
-### Known problems
-If the argument is dereferenced within the function,
-removing the `ref` will lead to errors. This can be fixed by removing the
-dereferences, e.g., changing `*x` to `x` within the function.
-
-### Example
-```
-fn foo(ref _x: u8) {}
-```
-
-Use instead:
-```
-fn foo(_x: &u8) {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/trailing_empty_array.txt b/src/tools/clippy/src/docs/trailing_empty_array.txt
deleted file mode 100644
index db1908cc9..000000000
--- a/src/tools/clippy/src/docs/trailing_empty_array.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Displays a warning when a struct with a trailing zero-sized array is declared without a `repr` attribute.
-
-### Why is this bad?
-Zero-sized arrays aren't very useful in Rust itself, so such a struct is likely being created to pass to C code or in some other situation where control over memory layout matters (for example, in conjunction with manual allocation to make it easy to compute the offset of the array). Either way, `#[repr(C)]` (or another `repr` attribute) is needed.
-
-### Example
-```
-struct RarelyUseful {
- some_field: u32,
- last: [u32; 0],
-}
-```
-
-Use instead:
-```
-#[repr(C)]
-struct MoreOftenUseful {
- some_field: usize,
- last: [u32; 0],
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/trait_duplication_in_bounds.txt b/src/tools/clippy/src/docs/trait_duplication_in_bounds.txt
deleted file mode 100644
index 509736bb3..000000000
--- a/src/tools/clippy/src/docs/trait_duplication_in_bounds.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-### What it does
-Checks for cases where generics are being used and multiple
-syntax specifications for trait bounds are used simultaneously.
-
-### Why is this bad?
-Duplicate bounds makes the code
-less readable than specifying them only once.
-
-### Example
-```
-fn func<T: Clone + Default>(arg: T) where T: Clone + Default {}
-```
-
-Use instead:
-```
-fn func<T: Clone + Default>(arg: T) {}
-
-// or
-
-fn func<T>(arg: T) where T: Clone + Default {}
-```
-
-```
-fn foo<T: Default + Default>(bar: T) {}
-```
-Use instead:
-```
-fn foo<T: Default>(bar: T) {}
-```
-
-```
-fn foo<T>(bar: T) where T: Default + Default {}
-```
-Use instead:
-```
-fn foo<T>(bar: T) where T: Default {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_bytes_to_str.txt b/src/tools/clippy/src/docs/transmute_bytes_to_str.txt
deleted file mode 100644
index 75889b9c7..000000000
--- a/src/tools/clippy/src/docs/transmute_bytes_to_str.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for transmutes from a `&[u8]` to a `&str`.
-
-### Why is this bad?
-Not every byte slice is a valid UTF-8 string.
-
-### Known problems
-- [`from_utf8`] which this lint suggests using is slower than `transmute`
-as it needs to validate the input.
-If you are certain that the input is always a valid UTF-8,
-use [`from_utf8_unchecked`] which is as fast as `transmute`
-but has a semantically meaningful name.
-- You might want to handle errors returned from [`from_utf8`] instead of calling `unwrap`.
-
-[`from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html
-[`from_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked.html
-
-### Example
-```
-let b: &[u8] = &[1_u8, 2_u8];
-unsafe {
- let _: &str = std::mem::transmute(b); // where b: &[u8]
-}
-
-// should be:
-let _ = std::str::from_utf8(b).unwrap();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_float_to_int.txt b/src/tools/clippy/src/docs/transmute_float_to_int.txt
deleted file mode 100644
index 1877e5a46..000000000
--- a/src/tools/clippy/src/docs/transmute_float_to_int.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for transmutes from a float to an integer.
-
-### Why is this bad?
-Transmutes are dangerous and error-prone, whereas `to_bits` is intuitive
-and safe.
-
-### Example
-```
-unsafe {
- let _: u32 = std::mem::transmute(1f32);
-}
-
-// should be:
-let _: u32 = 1f32.to_bits();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_int_to_bool.txt b/src/tools/clippy/src/docs/transmute_int_to_bool.txt
deleted file mode 100644
index 07c10f8d0..000000000
--- a/src/tools/clippy/src/docs/transmute_int_to_bool.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for transmutes from an integer to a `bool`.
-
-### Why is this bad?
-This might result in an invalid in-memory representation of a `bool`.
-
-### Example
-```
-let x = 1_u8;
-unsafe {
- let _: bool = std::mem::transmute(x); // where x: u8
-}
-
-// should be:
-let _: bool = x != 0;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_int_to_char.txt b/src/tools/clippy/src/docs/transmute_int_to_char.txt
deleted file mode 100644
index 836d22d3f..000000000
--- a/src/tools/clippy/src/docs/transmute_int_to_char.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for transmutes from an integer to a `char`.
-
-### Why is this bad?
-Not every integer is a Unicode scalar value.
-
-### Known problems
-- [`from_u32`] which this lint suggests using is slower than `transmute`
-as it needs to validate the input.
-If you are certain that the input is always a valid Unicode scalar value,
-use [`from_u32_unchecked`] which is as fast as `transmute`
-but has a semantically meaningful name.
-- You might want to handle `None` returned from [`from_u32`] instead of calling `unwrap`.
-
-[`from_u32`]: https://doc.rust-lang.org/std/char/fn.from_u32.html
-[`from_u32_unchecked`]: https://doc.rust-lang.org/std/char/fn.from_u32_unchecked.html
-
-### Example
-```
-let x = 1_u32;
-unsafe {
- let _: char = std::mem::transmute(x); // where x: u32
-}
-
-// should be:
-let _ = std::char::from_u32(x).unwrap();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_int_to_float.txt b/src/tools/clippy/src/docs/transmute_int_to_float.txt
deleted file mode 100644
index 75cdc62e9..000000000
--- a/src/tools/clippy/src/docs/transmute_int_to_float.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for transmutes from an integer to a float.
-
-### Why is this bad?
-Transmutes are dangerous and error-prone, whereas `from_bits` is intuitive
-and safe.
-
-### Example
-```
-unsafe {
- let _: f32 = std::mem::transmute(1_u32); // where x: u32
-}
-
-// should be:
-let _: f32 = f32::from_bits(1_u32);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_num_to_bytes.txt b/src/tools/clippy/src/docs/transmute_num_to_bytes.txt
deleted file mode 100644
index a2c39a1b9..000000000
--- a/src/tools/clippy/src/docs/transmute_num_to_bytes.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for transmutes from a number to an array of `u8`
-
-### Why this is bad?
-Transmutes are dangerous and error-prone, whereas `to_ne_bytes`
-is intuitive and safe.
-
-### Example
-```
-unsafe {
- let x: [u8; 8] = std::mem::transmute(1i64);
-}
-
-// should be
-let x: [u8; 8] = 0i64.to_ne_bytes();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_ptr_to_ptr.txt b/src/tools/clippy/src/docs/transmute_ptr_to_ptr.txt
deleted file mode 100644
index 65777db98..000000000
--- a/src/tools/clippy/src/docs/transmute_ptr_to_ptr.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for transmutes from a pointer to a pointer, or
-from a reference to a reference.
-
-### Why is this bad?
-Transmutes are dangerous, and these can instead be
-written as casts.
-
-### Example
-```
-let ptr = &1u32 as *const u32;
-unsafe {
- // pointer-to-pointer transmute
- let _: *const f32 = std::mem::transmute(ptr);
- // ref-ref transmute
- let _: &f32 = std::mem::transmute(&1u32);
-}
-// These can be respectively written:
-let _ = ptr as *const f32;
-let _ = unsafe{ &*(&1u32 as *const u32 as *const f32) };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_ptr_to_ref.txt b/src/tools/clippy/src/docs/transmute_ptr_to_ref.txt
deleted file mode 100644
index aca550f50..000000000
--- a/src/tools/clippy/src/docs/transmute_ptr_to_ref.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Checks for transmutes from a pointer to a reference.
-
-### Why is this bad?
-This can always be rewritten with `&` and `*`.
-
-### Known problems
-- `mem::transmute` in statics and constants is stable from Rust 1.46.0,
-while dereferencing raw pointer is not stable yet.
-If you need to do this in those places,
-you would have to use `transmute` instead.
-
-### Example
-```
-unsafe {
- let _: &T = std::mem::transmute(p); // where p: *const T
-}
-
-// can be written:
-let _: &T = &*p;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmute_undefined_repr.txt b/src/tools/clippy/src/docs/transmute_undefined_repr.txt
deleted file mode 100644
index 5ee6aaf4c..000000000
--- a/src/tools/clippy/src/docs/transmute_undefined_repr.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for transmutes between types which do not have a representation defined relative to
-each other.
-
-### Why is this bad?
-The results of such a transmute are not defined.
-
-### Known problems
-This lint has had multiple problems in the past and was moved to `nursery`. See issue
-[#8496](https://github.com/rust-lang/rust-clippy/issues/8496) for more details.
-
-### Example
-```
-struct Foo<T>(u32, T);
-let _ = unsafe { core::mem::transmute::<Foo<u32>, Foo<i32>>(Foo(0u32, 0u32)) };
-```
-Use instead:
-```
-#[repr(C)]
-struct Foo<T>(u32, T);
-let _ = unsafe { core::mem::transmute::<Foo<u32>, Foo<i32>>(Foo(0u32, 0u32)) };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmutes_expressible_as_ptr_casts.txt b/src/tools/clippy/src/docs/transmutes_expressible_as_ptr_casts.txt
deleted file mode 100644
index b68a8cda9..000000000
--- a/src/tools/clippy/src/docs/transmutes_expressible_as_ptr_casts.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Checks for transmutes that could be a pointer cast.
-
-### Why is this bad?
-Readability. The code tricks people into thinking that
-something complex is going on.
-
-### Example
-
-```
-unsafe { std::mem::transmute::<*const [i32], *const [u16]>(p) };
-```
-Use instead:
-```
-p as *const [u16];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/transmuting_null.txt b/src/tools/clippy/src/docs/transmuting_null.txt
deleted file mode 100644
index f8bacfc0b..000000000
--- a/src/tools/clippy/src/docs/transmuting_null.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for transmute calls which would receive a null pointer.
-
-### Why is this bad?
-Transmuting a null pointer is undefined behavior.
-
-### Known problems
-Not all cases can be detected at the moment of this writing.
-For example, variables which hold a null pointer and are then fed to a `transmute`
-call, aren't detectable yet.
-
-### Example
-```
-let null_ref: &u64 = unsafe { std::mem::transmute(0 as *const u64) };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/trim_split_whitespace.txt b/src/tools/clippy/src/docs/trim_split_whitespace.txt
deleted file mode 100644
index f7e3e7858..000000000
--- a/src/tools/clippy/src/docs/trim_split_whitespace.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Warns about calling `str::trim` (or variants) before `str::split_whitespace`.
-
-### Why is this bad?
-`split_whitespace` already ignores leading and trailing whitespace.
-
-### Example
-```
-" A B C ".trim().split_whitespace();
-```
-Use instead:
-```
-" A B C ".split_whitespace();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/trivial_regex.txt b/src/tools/clippy/src/docs/trivial_regex.txt
deleted file mode 100644
index f71d667fd..000000000
--- a/src/tools/clippy/src/docs/trivial_regex.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for trivial [regex](https://crates.io/crates/regex)
-creation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`).
-
-### Why is this bad?
-Matching the regex can likely be replaced by `==` or
-`str::starts_with`, `str::ends_with` or `std::contains` or other `str`
-methods.
-
-### Known problems
-If the same regex is going to be applied to multiple
-inputs, the precomputations done by `Regex` construction can give
-significantly better performance than any of the `str`-based methods.
-
-### Example
-```
-Regex::new("^foobar")
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/trivially_copy_pass_by_ref.txt b/src/tools/clippy/src/docs/trivially_copy_pass_by_ref.txt
deleted file mode 100644
index f54cce5e2..000000000
--- a/src/tools/clippy/src/docs/trivially_copy_pass_by_ref.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-### What it does
-Checks for functions taking arguments by reference, where
-the argument type is `Copy` and small enough to be more efficient to always
-pass by value.
-
-### Why is this bad?
-In many calling conventions instances of structs will
-be passed through registers if they fit into two or less general purpose
-registers.
-
-### Known problems
-This lint is target register size dependent, it is
-limited to 32-bit to try and reduce portability problems between 32 and
-64-bit, but if you are compiling for 8 or 16-bit targets then the limit
-will be different.
-
-The configuration option `trivial_copy_size_limit` can be set to override
-this limit for a project.
-
-This lint attempts to allow passing arguments by reference if a reference
-to that argument is returned. This is implemented by comparing the lifetime
-of the argument and return value for equality. However, this can cause
-false positives in cases involving multiple lifetimes that are bounded by
-each other.
-
-Also, it does not take account of other similar cases where getting memory addresses
-matters; namely, returning the pointer to the argument in question,
-and passing the argument, as both references and pointers,
-to a function that needs the memory address. For further details, refer to
-[this issue](https://github.com/rust-lang/rust-clippy/issues/5953)
-that explains a real case in which this false positive
-led to an **undefined behavior** introduced with unsafe code.
-
-### Example
-
-```
-fn foo(v: &u32) {}
-```
-
-Use instead:
-```
-fn foo(v: u32) {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/try_err.txt b/src/tools/clippy/src/docs/try_err.txt
deleted file mode 100644
index e3d4ef3a0..000000000
--- a/src/tools/clippy/src/docs/try_err.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for usages of `Err(x)?`.
-
-### Why is this bad?
-The `?` operator is designed to allow calls that
-can fail to be easily chained. For example, `foo()?.bar()` or
-`foo(bar()?)`. Because `Err(x)?` can't be used that way (it will
-always return), it is more clear to write `return Err(x)`.
-
-### Example
-```
-fn foo(fail: bool) -> Result<i32, String> {
- if fail {
- Err("failed")?;
- }
- Ok(0)
-}
-```
-Could be written:
-
-```
-fn foo(fail: bool) -> Result<i32, String> {
- if fail {
- return Err("failed".into());
- }
- Ok(0)
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/type_complexity.txt b/src/tools/clippy/src/docs/type_complexity.txt
deleted file mode 100644
index 69cd87500..000000000
--- a/src/tools/clippy/src/docs/type_complexity.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for types used in structs, parameters and `let`
-declarations above a certain complexity threshold.
-
-### Why is this bad?
-Too complex types make the code less readable. Consider
-using a `type` definition to simplify them.
-
-### Example
-```
-struct Foo {
- inner: Rc<Vec<Vec<Box<(u32, u32, u32, u32)>>>>,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/type_repetition_in_bounds.txt b/src/tools/clippy/src/docs/type_repetition_in_bounds.txt
deleted file mode 100644
index 18ed372fd..000000000
--- a/src/tools/clippy/src/docs/type_repetition_in_bounds.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-This lint warns about unnecessary type repetitions in trait bounds
-
-### Why is this bad?
-Repeating the type for every bound makes the code
-less readable than combining the bounds
-
-### Example
-```
-pub fn foo<T>(t: T) where T: Copy, T: Clone {}
-```
-
-Use instead:
-```
-pub fn foo<T>(t: T) where T: Copy + Clone {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/undocumented_unsafe_blocks.txt b/src/tools/clippy/src/docs/undocumented_unsafe_blocks.txt
deleted file mode 100644
index f3af4753c..000000000
--- a/src/tools/clippy/src/docs/undocumented_unsafe_blocks.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-### What it does
-Checks for `unsafe` blocks and impls without a `// SAFETY: ` comment
-explaining why the unsafe operations performed inside
-the block are safe.
-
-Note the comment must appear on the line(s) preceding the unsafe block
-with nothing appearing in between. The following is ok:
-```
-foo(
- // SAFETY:
- // This is a valid safety comment
- unsafe { *x }
-)
-```
-But neither of these are:
-```
-// SAFETY:
-// This is not a valid safety comment
-foo(
- /* SAFETY: Neither is this */ unsafe { *x },
-);
-```
-
-### Why is this bad?
-Undocumented unsafe blocks and impls can make it difficult to
-read and maintain code, as well as uncover unsoundness
-and bugs.
-
-### Example
-```
-use std::ptr::NonNull;
-let a = &mut 42;
-
-let ptr = unsafe { NonNull::new_unchecked(a) };
-```
-Use instead:
-```
-use std::ptr::NonNull;
-let a = &mut 42;
-
-// SAFETY: references are guaranteed to be non-null.
-let ptr = unsafe { NonNull::new_unchecked(a) };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/undropped_manually_drops.txt b/src/tools/clippy/src/docs/undropped_manually_drops.txt
deleted file mode 100644
index 85e3ec566..000000000
--- a/src/tools/clippy/src/docs/undropped_manually_drops.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`.
-
-### Why is this bad?
-The safe `drop` function does not drop the inner value of a `ManuallyDrop`.
-
-### Known problems
-Does not catch cases if the user binds `std::mem::drop`
-to a different name and calls it that way.
-
-### Example
-```
-struct S;
-drop(std::mem::ManuallyDrop::new(S));
-```
-Use instead:
-```
-struct S;
-unsafe {
- std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S));
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unicode_not_nfc.txt b/src/tools/clippy/src/docs/unicode_not_nfc.txt
deleted file mode 100644
index c660c51da..000000000
--- a/src/tools/clippy/src/docs/unicode_not_nfc.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for string literals that contain Unicode in a form
-that is not equal to its
-[NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms).
-
-### Why is this bad?
-If such a string is compared to another, the results
-may be surprising.
-
-### Example
-You may not see it, but "à"" and "à"" aren't the same string. The
-former when escaped is actually `"a\u{300}"` while the latter is `"\u{e0}"`. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unimplemented.txt b/src/tools/clippy/src/docs/unimplemented.txt
deleted file mode 100644
index 7095594fb..000000000
--- a/src/tools/clippy/src/docs/unimplemented.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-### What it does
-Checks for usage of `unimplemented!`.
-
-### Why is this bad?
-This macro should not be present in production code
-
-### Example
-```
-unimplemented!();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/uninit_assumed_init.txt b/src/tools/clippy/src/docs/uninit_assumed_init.txt
deleted file mode 100644
index cca24093d..000000000
--- a/src/tools/clippy/src/docs/uninit_assumed_init.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for `MaybeUninit::uninit().assume_init()`.
-
-### Why is this bad?
-For most types, this is undefined behavior.
-
-### Known problems
-For now, we accept empty tuples and tuples / arrays
-of `MaybeUninit`. There may be other types that allow uninitialized
-data, but those are not yet rigorously defined.
-
-### Example
-```
-// Beware the UB
-use std::mem::MaybeUninit;
-
-let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
-```
-
-Note that the following is OK:
-
-```
-use std::mem::MaybeUninit;
-
-let _: [MaybeUninit<bool>; 5] = unsafe {
- MaybeUninit::uninit().assume_init()
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/uninit_vec.txt b/src/tools/clippy/src/docs/uninit_vec.txt
deleted file mode 100644
index cd50afe78..000000000
--- a/src/tools/clippy/src/docs/uninit_vec.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-### What it does
-Checks for `set_len()` call that creates `Vec` with uninitialized elements.
-This is commonly caused by calling `set_len()` right after allocating or
-reserving a buffer with `new()`, `default()`, `with_capacity()`, or `reserve()`.
-
-### Why is this bad?
-It creates a `Vec` with uninitialized data, which leads to
-undefined behavior with most safe operations. Notably, uninitialized
-`Vec<u8>` must not be used with generic `Read`.
-
-Moreover, calling `set_len()` on a `Vec` created with `new()` or `default()`
-creates out-of-bound values that lead to heap memory corruption when used.
-
-### Known Problems
-This lint only checks directly adjacent statements.
-
-### Example
-```
-let mut vec: Vec<u8> = Vec::with_capacity(1000);
-unsafe { vec.set_len(1000); }
-reader.read(&mut vec); // undefined behavior!
-```
-
-### How to fix?
-1. Use an initialized buffer:
- ```rust,ignore
- let mut vec: Vec<u8> = vec![0; 1000];
- reader.read(&mut vec);
- ```
-2. Wrap the content in `MaybeUninit`:
- ```rust,ignore
- let mut vec: Vec<MaybeUninit<T>> = Vec::with_capacity(1000);
- vec.set_len(1000); // `MaybeUninit` can be uninitialized
- ```
-3. If you are on 1.60.0 or later, `Vec::spare_capacity_mut()` is available:
- ```rust,ignore
- let mut vec: Vec<u8> = Vec::with_capacity(1000);
- let remaining = vec.spare_capacity_mut(); // `&mut [MaybeUninit<u8>]`
- // perform initialization with `remaining`
- vec.set_len(...); // Safe to call `set_len()` on initialized part
- ``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/uninlined_format_args.txt b/src/tools/clippy/src/docs/uninlined_format_args.txt
deleted file mode 100644
index 3d2966c84..000000000
--- a/src/tools/clippy/src/docs/uninlined_format_args.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-### What it does
-Detect when a variable is not inlined in a format string,
-and suggests to inline it.
-
-### Why is this bad?
-Non-inlined code is slightly more difficult to read and understand,
-as it requires arguments to be matched against the format string.
-The inlined syntax, where allowed, is simpler.
-
-### Example
-```
-format!("{}", var);
-format!("{v:?}", v = var);
-format!("{0} {0}", var);
-format!("{0:1$}", var, width);
-format!("{:.*}", prec, var);
-```
-Use instead:
-```
-format!("{var}");
-format!("{var:?}");
-format!("{var} {var}");
-format!("{var:width$}");
-format!("{var:.prec$}");
-```
-
-### Known Problems
-
-There may be a false positive if the format string is expanded from certain proc macros:
-
-```
-println!(indoc!("{}"), var);
-```
-
-If a format string contains a numbered argument that cannot be inlined
-nothing will be suggested, e.g. `println!("{0}={1}", var, 1+2)`. \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unit_arg.txt b/src/tools/clippy/src/docs/unit_arg.txt
deleted file mode 100644
index eb83403bb..000000000
--- a/src/tools/clippy/src/docs/unit_arg.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-### What it does
-Checks for passing a unit value as an argument to a function without using a
-unit literal (`()`).
-
-### Why is this bad?
-This is likely the result of an accidental semicolon.
-
-### Example
-```
-foo({
- let a = bar();
- baz(a);
-})
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unit_cmp.txt b/src/tools/clippy/src/docs/unit_cmp.txt
deleted file mode 100644
index 6f3d62010..000000000
--- a/src/tools/clippy/src/docs/unit_cmp.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-### What it does
-Checks for comparisons to unit. This includes all binary
-comparisons (like `==` and `<`) and asserts.
-
-### Why is this bad?
-Unit is always equal to itself, and thus is just a
-clumsily written constant. Mostly this happens when someone accidentally
-adds semicolons at the end of the operands.
-
-### Example
-```
-if {
- foo();
-} == {
- bar();
-} {
- baz();
-}
-```
-is equal to
-```
-{
- foo();
- bar();
- baz();
-}
-```
-
-For asserts:
-```
-assert_eq!({ foo(); }, { bar(); });
-```
-will always succeed \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unit_hash.txt b/src/tools/clippy/src/docs/unit_hash.txt
deleted file mode 100644
index a22d29946..000000000
--- a/src/tools/clippy/src/docs/unit_hash.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Detects `().hash(_)`.
-
-### Why is this bad?
-Hashing a unit value doesn't do anything as the implementation of `Hash` for `()` is a no-op.
-
-### Example
-```
-match my_enum {
- Empty => ().hash(&mut state),
- WithValue(x) => x.hash(&mut state),
-}
-```
-Use instead:
-```
-match my_enum {
- Empty => 0_u8.hash(&mut state),
- WithValue(x) => x.hash(&mut state),
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unit_return_expecting_ord.txt b/src/tools/clippy/src/docs/unit_return_expecting_ord.txt
deleted file mode 100644
index 781feac5a..000000000
--- a/src/tools/clippy/src/docs/unit_return_expecting_ord.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for functions that expect closures of type
-Fn(...) -> Ord where the implemented closure returns the unit type.
-The lint also suggests to remove the semi-colon at the end of the statement if present.
-
-### Why is this bad?
-Likely, returning the unit type is unintentional, and
-could simply be caused by an extra semi-colon. Since () implements Ord
-it doesn't cause a compilation error.
-This is the same reasoning behind the unit_cmp lint.
-
-### Known problems
-If returning unit is intentional, then there is no
-way of specifying this without triggering needless_return lint
-
-### Example
-```
-let mut twins = vec!((1, 1), (2, 2));
-twins.sort_by_key(|x| { x.1; });
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_cast.txt b/src/tools/clippy/src/docs/unnecessary_cast.txt
deleted file mode 100644
index 603f26060..000000000
--- a/src/tools/clippy/src/docs/unnecessary_cast.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for casts to the same type, casts of int literals to integer types
-and casts of float literals to float types.
-
-### Why is this bad?
-It's just unnecessary.
-
-### Example
-```
-let _ = 2i32 as i32;
-let _ = 0.5 as f32;
-```
-
-Better:
-
-```
-let _ = 2_i32;
-let _ = 0.5_f32;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_filter_map.txt b/src/tools/clippy/src/docs/unnecessary_filter_map.txt
deleted file mode 100644
index b19341ecf..000000000
--- a/src/tools/clippy/src/docs/unnecessary_filter_map.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for `filter_map` calls that could be replaced by `filter` or `map`.
-More specifically it checks if the closure provided is only performing one of the
-filter or map operations and suggests the appropriate option.
-
-### Why is this bad?
-Complexity. The intent is also clearer if only a single
-operation is being performed.
-
-### Example
-```
-let _ = (0..3).filter_map(|x| if x > 2 { Some(x) } else { None });
-
-// As there is no transformation of the argument this could be written as:
-let _ = (0..3).filter(|&x| x > 2);
-```
-
-```
-let _ = (0..4).filter_map(|x| Some(x + 1));
-
-// As there is no conditional check on the argument this could be written as:
-let _ = (0..4).map(|x| x + 1);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_find_map.txt b/src/tools/clippy/src/docs/unnecessary_find_map.txt
deleted file mode 100644
index f9444dc48..000000000
--- a/src/tools/clippy/src/docs/unnecessary_find_map.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for `find_map` calls that could be replaced by `find` or `map`. More
-specifically it checks if the closure provided is only performing one of the
-find or map operations and suggests the appropriate option.
-
-### Why is this bad?
-Complexity. The intent is also clearer if only a single
-operation is being performed.
-
-### Example
-```
-let _ = (0..3).find_map(|x| if x > 2 { Some(x) } else { None });
-
-// As there is no transformation of the argument this could be written as:
-let _ = (0..3).find(|&x| x > 2);
-```
-
-```
-let _ = (0..4).find_map(|x| Some(x + 1));
-
-// As there is no conditional check on the argument this could be written as:
-let _ = (0..4).map(|x| x + 1).next();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_fold.txt b/src/tools/clippy/src/docs/unnecessary_fold.txt
deleted file mode 100644
index e1b0e65f5..000000000
--- a/src/tools/clippy/src/docs/unnecessary_fold.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for using `fold` when a more succinct alternative exists.
-Specifically, this checks for `fold`s which could be replaced by `any`, `all`,
-`sum` or `product`.
-
-### Why is this bad?
-Readability.
-
-### Example
-```
-(0..3).fold(false, |acc, x| acc || x > 2);
-```
-
-Use instead:
-```
-(0..3).any(|x| x > 2);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_join.txt b/src/tools/clippy/src/docs/unnecessary_join.txt
deleted file mode 100644
index ee4e78601..000000000
--- a/src/tools/clippy/src/docs/unnecessary_join.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for use of `.collect::<Vec<String>>().join("")` on iterators.
-
-### Why is this bad?
-`.collect::<String>()` is more concise and might be more performant
-
-### Example
-```
-let vector = vec!["hello", "world"];
-let output = vector.iter().map(|item| item.to_uppercase()).collect::<Vec<String>>().join("");
-println!("{}", output);
-```
-The correct use would be:
-```
-let vector = vec!["hello", "world"];
-let output = vector.iter().map(|item| item.to_uppercase()).collect::<String>();
-println!("{}", output);
-```
-### Known problems
-While `.collect::<String>()` is sometimes more performant, there are cases where
-using `.collect::<String>()` over `.collect::<Vec<String>>().join("")`
-will prevent loop unrolling and will result in a negative performance impact.
-
-Additionally, differences have been observed between aarch64 and x86_64 assembly output,
-with aarch64 tending to producing faster assembly in more cases when using `.collect::<String>()` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_lazy_evaluations.txt b/src/tools/clippy/src/docs/unnecessary_lazy_evaluations.txt
deleted file mode 100644
index 208188ce9..000000000
--- a/src/tools/clippy/src/docs/unnecessary_lazy_evaluations.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-As the counterpart to `or_fun_call`, this lint looks for unnecessary
-lazily evaluated closures on `Option` and `Result`.
-
-This lint suggests changing the following functions, when eager evaluation results in
-simpler code:
- - `unwrap_or_else` to `unwrap_or`
- - `and_then` to `and`
- - `or_else` to `or`
- - `get_or_insert_with` to `get_or_insert`
- - `ok_or_else` to `ok_or`
-
-### Why is this bad?
-Using eager evaluation is shorter and simpler in some cases.
-
-### Known problems
-It is possible, but not recommended for `Deref` and `Index` to have
-side effects. Eagerly evaluating them can change the semantics of the program.
-
-### Example
-```
-// example code where clippy issues a warning
-let opt: Option<u32> = None;
-
-opt.unwrap_or_else(|| 42);
-```
-Use instead:
-```
-let opt: Option<u32> = None;
-
-opt.unwrap_or(42);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_mut_passed.txt b/src/tools/clippy/src/docs/unnecessary_mut_passed.txt
deleted file mode 100644
index 2f8bdd113..000000000
--- a/src/tools/clippy/src/docs/unnecessary_mut_passed.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Detects passing a mutable reference to a function that only
-requires an immutable reference.
-
-### Why is this bad?
-The mutable reference rules out all other references to
-the value. Also the code misleads about the intent of the call site.
-
-### Example
-```
-vec.push(&mut value);
-```
-
-Use instead:
-```
-vec.push(&value);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_operation.txt b/src/tools/clippy/src/docs/unnecessary_operation.txt
deleted file mode 100644
index 7f455e264..000000000
--- a/src/tools/clippy/src/docs/unnecessary_operation.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for expression statements that can be reduced to a
-sub-expression.
-
-### Why is this bad?
-Expressions by themselves often have no side-effects.
-Having such expressions reduces readability.
-
-### Example
-```
-compute_array()[0];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_owned_empty_strings.txt b/src/tools/clippy/src/docs/unnecessary_owned_empty_strings.txt
deleted file mode 100644
index 8cd9fba60..000000000
--- a/src/tools/clippy/src/docs/unnecessary_owned_empty_strings.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-
-Detects cases of owned empty strings being passed as an argument to a function expecting `&str`
-
-### Why is this bad?
-
-This results in longer and less readable code
-
-### Example
-```
-vec!["1", "2", "3"].join(&String::new());
-```
-Use instead:
-```
-vec!["1", "2", "3"].join("");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_self_imports.txt b/src/tools/clippy/src/docs/unnecessary_self_imports.txt
deleted file mode 100644
index b909cd5a7..000000000
--- a/src/tools/clippy/src/docs/unnecessary_self_imports.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for imports ending in `::{self}`.
-
-### Why is this bad?
-In most cases, this can be written much more cleanly by omitting `::{self}`.
-
-### Known problems
-Removing `::{self}` will cause any non-module items at the same path to also be imported.
-This might cause a naming conflict (https://github.com/rust-lang/rustfmt/issues/3568). This lint makes no attempt
-to detect this scenario and that is why it is a restriction lint.
-
-### Example
-```
-use std::io::{self};
-```
-Use instead:
-```
-use std::io;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_sort_by.txt b/src/tools/clippy/src/docs/unnecessary_sort_by.txt
deleted file mode 100644
index 6913b62c4..000000000
--- a/src/tools/clippy/src/docs/unnecessary_sort_by.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-### What it does
-Detects uses of `Vec::sort_by` passing in a closure
-which compares the two arguments, either directly or indirectly.
-
-### Why is this bad?
-It is more clear to use `Vec::sort_by_key` (or `Vec::sort` if
-possible) than to use `Vec::sort_by` and a more complicated
-closure.
-
-### Known problems
-If the suggested `Vec::sort_by_key` uses Reverse and it isn't already
-imported by a use statement, then it will need to be added manually.
-
-### Example
-```
-vec.sort_by(|a, b| a.foo().cmp(&b.foo()));
-```
-Use instead:
-```
-vec.sort_by_key(|a| a.foo());
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_to_owned.txt b/src/tools/clippy/src/docs/unnecessary_to_owned.txt
deleted file mode 100644
index 5d4213bda..000000000
--- a/src/tools/clippy/src/docs/unnecessary_to_owned.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for unnecessary calls to [`ToOwned::to_owned`](https://doc.rust-lang.org/std/borrow/trait.ToOwned.html#tymethod.to_owned)
-and other `to_owned`-like functions.
-
-### Why is this bad?
-The unnecessary calls result in useless allocations.
-
-### Known problems
-`unnecessary_to_owned` can falsely trigger if `IntoIterator::into_iter` is applied to an
-owned copy of a resource and the resource is later used mutably. See
-[#8148](https://github.com/rust-lang/rust-clippy/issues/8148).
-
-### Example
-```
-let path = std::path::Path::new("x");
-foo(&path.to_string_lossy().to_string());
-fn foo(s: &str) {}
-```
-Use instead:
-```
-let path = std::path::Path::new("x");
-foo(&path.to_string_lossy());
-fn foo(s: &str) {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_unwrap.txt b/src/tools/clippy/src/docs/unnecessary_unwrap.txt
deleted file mode 100644
index 50ae845bb..000000000
--- a/src/tools/clippy/src/docs/unnecessary_unwrap.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for calls of `unwrap[_err]()` that cannot fail.
-
-### Why is this bad?
-Using `if let` or `match` is more idiomatic.
-
-### Example
-```
-if option.is_some() {
- do_something_with(option.unwrap())
-}
-```
-
-Could be written:
-
-```
-if let Some(value) = option {
- do_something_with(value)
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnecessary_wraps.txt b/src/tools/clippy/src/docs/unnecessary_wraps.txt
deleted file mode 100644
index c0a23d492..000000000
--- a/src/tools/clippy/src/docs/unnecessary_wraps.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-### What it does
-Checks for private functions that only return `Ok` or `Some`.
-
-### Why is this bad?
-It is not meaningful to wrap values when no `None` or `Err` is returned.
-
-### Known problems
-There can be false positives if the function signature is designed to
-fit some external requirement.
-
-### Example
-```
-fn get_cool_number(a: bool, b: bool) -> Option<i32> {
- if a && b {
- return Some(50);
- }
- if a {
- Some(0)
- } else {
- Some(10)
- }
-}
-```
-Use instead:
-```
-fn get_cool_number(a: bool, b: bool) -> i32 {
- if a && b {
- return 50;
- }
- if a {
- 0
- } else {
- 10
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unneeded_field_pattern.txt b/src/tools/clippy/src/docs/unneeded_field_pattern.txt
deleted file mode 100644
index 3cd00a0f3..000000000
--- a/src/tools/clippy/src/docs/unneeded_field_pattern.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for structure field patterns bound to wildcards.
-
-### Why is this bad?
-Using `..` instead is shorter and leaves the focus on
-the fields that are actually bound.
-
-### Example
-```
-let f = Foo { a: 0, b: 0, c: 0 };
-
-match f {
- Foo { a: _, b: 0, .. } => {},
- Foo { a: _, b: _, c: _ } => {},
-}
-```
-
-Use instead:
-```
-let f = Foo { a: 0, b: 0, c: 0 };
-
-match f {
- Foo { b: 0, .. } => {},
- Foo { .. } => {},
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unneeded_wildcard_pattern.txt b/src/tools/clippy/src/docs/unneeded_wildcard_pattern.txt
deleted file mode 100644
index 817061efd..000000000
--- a/src/tools/clippy/src/docs/unneeded_wildcard_pattern.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-### What it does
-Checks for tuple patterns with a wildcard
-pattern (`_`) is next to a rest pattern (`..`).
-
-_NOTE_: While `_, ..` means there is at least one element left, `..`
-means there are 0 or more elements left. This can make a difference
-when refactoring, but shouldn't result in errors in the refactored code,
-since the wildcard pattern isn't used anyway.
-
-### Why is this bad?
-The wildcard pattern is unneeded as the rest pattern
-can match that element as well.
-
-### Example
-```
-match t {
- TupleStruct(0, .., _) => (),
- _ => (),
-}
-```
-
-Use instead:
-```
-match t {
- TupleStruct(0, ..) => (),
- _ => (),
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unnested_or_patterns.txt b/src/tools/clippy/src/docs/unnested_or_patterns.txt
deleted file mode 100644
index 49c45d4ee..000000000
--- a/src/tools/clippy/src/docs/unnested_or_patterns.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for unnested or-patterns, e.g., `Some(0) | Some(2)` and
-suggests replacing the pattern with a nested one, `Some(0 | 2)`.
-
-Another way to think of this is that it rewrites patterns in
-*disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*.
-
-### Why is this bad?
-In the example above, `Some` is repeated, which unnecessarily complicates the pattern.
-
-### Example
-```
-fn main() {
- if let Some(0) | Some(2) = Some(0) {}
-}
-```
-Use instead:
-```
-fn main() {
- if let Some(0 | 2) = Some(0) {}
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unreachable.txt b/src/tools/clippy/src/docs/unreachable.txt
deleted file mode 100644
index 10469ca77..000000000
--- a/src/tools/clippy/src/docs/unreachable.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-### What it does
-Checks for usage of `unreachable!`.
-
-### Why is this bad?
-This macro can cause code to panic
-
-### Example
-```
-unreachable!();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unreadable_literal.txt b/src/tools/clippy/src/docs/unreadable_literal.txt
deleted file mode 100644
index e168f90a8..000000000
--- a/src/tools/clippy/src/docs/unreadable_literal.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-Warns if a long integral or floating-point constant does
-not contain underscores.
-
-### Why is this bad?
-Reading long numbers is difficult without separators.
-
-### Example
-```
-61864918973511
-```
-
-Use instead:
-```
-61_864_918_973_511
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unsafe_derive_deserialize.txt b/src/tools/clippy/src/docs/unsafe_derive_deserialize.txt
deleted file mode 100644
index f56c48044..000000000
--- a/src/tools/clippy/src/docs/unsafe_derive_deserialize.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-### What it does
-Checks for deriving `serde::Deserialize` on a type that
-has methods using `unsafe`.
-
-### Why is this bad?
-Deriving `serde::Deserialize` will create a constructor
-that may violate invariants hold by another constructor.
-
-### Example
-```
-use serde::Deserialize;
-
-#[derive(Deserialize)]
-pub struct Foo {
- // ..
-}
-
-impl Foo {
- pub fn new() -> Self {
- // setup here ..
- }
-
- pub unsafe fn parts() -> (&str, &str) {
- // assumes invariants hold
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unsafe_removed_from_name.txt b/src/tools/clippy/src/docs/unsafe_removed_from_name.txt
deleted file mode 100644
index 6f55c1815..000000000
--- a/src/tools/clippy/src/docs/unsafe_removed_from_name.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for imports that remove "unsafe" from an item's
-name.
-
-### Why is this bad?
-Renaming makes it less clear which traits and
-structures are unsafe.
-
-### Example
-```
-use std::cell::{UnsafeCell as TotallySafeCell};
-
-extern crate crossbeam;
-use crossbeam::{spawn_unsafe as spawn};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unseparated_literal_suffix.txt b/src/tools/clippy/src/docs/unseparated_literal_suffix.txt
deleted file mode 100644
index d80248e34..000000000
--- a/src/tools/clippy/src/docs/unseparated_literal_suffix.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Warns if literal suffixes are not separated by an
-underscore.
-To enforce unseparated literal suffix style,
-see the `separated_literal_suffix` lint.
-
-### Why is this bad?
-Suffix style should be consistent.
-
-### Example
-```
-123832i32
-```
-
-Use instead:
-```
-123832_i32
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unsound_collection_transmute.txt b/src/tools/clippy/src/docs/unsound_collection_transmute.txt
deleted file mode 100644
index 29db9258e..000000000
--- a/src/tools/clippy/src/docs/unsound_collection_transmute.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for transmutes between collections whose
-types have different ABI, size or alignment.
-
-### Why is this bad?
-This is undefined behavior.
-
-### Known problems
-Currently, we cannot know whether a type is a
-collection, so we just lint the ones that come with `std`.
-
-### Example
-```
-// different size, therefore likely out-of-bounds memory access
-// You absolutely do not want this in your code!
-unsafe {
- std::mem::transmute::<_, Vec<u32>>(vec![2_u16])
-};
-```
-
-You must always iterate, map and collect the values:
-
-```
-vec![2_u16].into_iter().map(u32::from).collect::<Vec<_>>();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_async.txt b/src/tools/clippy/src/docs/unused_async.txt
deleted file mode 100644
index 26def11aa..000000000
--- a/src/tools/clippy/src/docs/unused_async.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for functions that are declared `async` but have no `.await`s inside of them.
-
-### Why is this bad?
-Async functions with no async code create overhead, both mentally and computationally.
-Callers of async methods either need to be calling from an async function themselves or run it on an executor, both of which
-causes runtime overhead and hassle for the caller.
-
-### Example
-```
-async fn get_random_number() -> i64 {
- 4 // Chosen by fair dice roll. Guaranteed to be random.
-}
-let number_future = get_random_number();
-```
-
-Use instead:
-```
-fn get_random_number_improved() -> i64 {
- 4 // Chosen by fair dice roll. Guaranteed to be random.
-}
-let number_future = async { get_random_number_improved() };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_format_specs.txt b/src/tools/clippy/src/docs/unused_format_specs.txt
deleted file mode 100644
index 77be3a2fb..000000000
--- a/src/tools/clippy/src/docs/unused_format_specs.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Detects [formatting parameters] that have no effect on the output of
-`format!()`, `println!()` or similar macros.
-
-### Why is this bad?
-Shorter format specifiers are easier to read, it may also indicate that
-an expected formatting operation such as adding padding isn't happening.
-
-### Example
-```
-println!("{:.}", 1.0);
-
-println!("not padded: {:5}", format_args!("..."));
-```
-Use instead:
-```
-println!("{}", 1.0);
-
-println!("not padded: {}", format_args!("..."));
-// OR
-println!("padded: {:5}", format!("..."));
-```
-
-[formatting parameters]: https://doc.rust-lang.org/std/fmt/index.html#formatting-parameters \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_io_amount.txt b/src/tools/clippy/src/docs/unused_io_amount.txt
deleted file mode 100644
index fbc4c299c..000000000
--- a/src/tools/clippy/src/docs/unused_io_amount.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-### What it does
-Checks for unused written/read amount.
-
-### Why is this bad?
-`io::Write::write(_vectored)` and
-`io::Read::read(_vectored)` are not guaranteed to
-process the entire buffer. They return how many bytes were processed, which
-might be smaller
-than a given buffer's length. If you don't need to deal with
-partial-write/read, use
-`write_all`/`read_exact` instead.
-
-When working with asynchronous code (either with the `futures`
-crate or with `tokio`), a similar issue exists for
-`AsyncWriteExt::write()` and `AsyncReadExt::read()` : these
-functions are also not guaranteed to process the entire
-buffer. Your code should either handle partial-writes/reads, or
-call the `write_all`/`read_exact` methods on those traits instead.
-
-### Known problems
-Detects only common patterns.
-
-### Examples
-```
-use std::io;
-fn foo<W: io::Write>(w: &mut W) -> io::Result<()> {
- // must be `w.write_all(b"foo")?;`
- w.write(b"foo")?;
- Ok(())
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_peekable.txt b/src/tools/clippy/src/docs/unused_peekable.txt
deleted file mode 100644
index 268de1ce3..000000000
--- a/src/tools/clippy/src/docs/unused_peekable.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for the creation of a `peekable` iterator that is never `.peek()`ed
-
-### Why is this bad?
-Creating a peekable iterator without using any of its methods is likely a mistake,
-or just a leftover after a refactor.
-
-### Example
-```
-let collection = vec![1, 2, 3];
-let iter = collection.iter().peekable();
-
-for item in iter {
- // ...
-}
-```
-
-Use instead:
-```
-let collection = vec![1, 2, 3];
-let iter = collection.iter();
-
-for item in iter {
- // ...
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_rounding.txt b/src/tools/clippy/src/docs/unused_rounding.txt
deleted file mode 100644
index 70947acee..000000000
--- a/src/tools/clippy/src/docs/unused_rounding.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-
-Detects cases where a whole-number literal float is being rounded, using
-the `floor`, `ceil`, or `round` methods.
-
-### Why is this bad?
-
-This is unnecessary and confusing to the reader. Doing this is probably a mistake.
-
-### Example
-```
-let x = 1f32.ceil();
-```
-Use instead:
-```
-let x = 1f32;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_self.txt b/src/tools/clippy/src/docs/unused_self.txt
deleted file mode 100644
index a8d0fc759..000000000
--- a/src/tools/clippy/src/docs/unused_self.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks methods that contain a `self` argument but don't use it
-
-### Why is this bad?
-It may be clearer to define the method as an associated function instead
-of an instance method if it doesn't require `self`.
-
-### Example
-```
-struct A;
-impl A {
- fn method(&self) {}
-}
-```
-
-Could be written:
-
-```
-struct A;
-impl A {
- fn method() {}
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unused_unit.txt b/src/tools/clippy/src/docs/unused_unit.txt
deleted file mode 100644
index 48d16ca65..000000000
--- a/src/tools/clippy/src/docs/unused_unit.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for unit (`()`) expressions that can be removed.
-
-### Why is this bad?
-Such expressions add no value, but can make the code
-less readable. Depending on formatting they can make a `break` or `return`
-statement look like a function call.
-
-### Example
-```
-fn return_unit() -> () {
- ()
-}
-```
-is equivalent to
-```
-fn return_unit() {}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unusual_byte_groupings.txt b/src/tools/clippy/src/docs/unusual_byte_groupings.txt
deleted file mode 100644
index 9a1f132a6..000000000
--- a/src/tools/clippy/src/docs/unusual_byte_groupings.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Warns if hexadecimal or binary literals are not grouped
-by nibble or byte.
-
-### Why is this bad?
-Negatively impacts readability.
-
-### Example
-```
-let x: u32 = 0xFFF_FFF;
-let y: u8 = 0b01_011_101;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unwrap_in_result.txt b/src/tools/clippy/src/docs/unwrap_in_result.txt
deleted file mode 100644
index 7497dd863..000000000
--- a/src/tools/clippy/src/docs/unwrap_in_result.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-### What it does
-Checks for functions of type `Result` that contain `expect()` or `unwrap()`
-
-### Why is this bad?
-These functions promote recoverable errors to non-recoverable errors which may be undesirable in code bases which wish to avoid panics.
-
-### Known problems
-This can cause false positives in functions that handle both recoverable and non recoverable errors.
-
-### Example
-Before:
-```
-fn divisible_by_3(i_str: String) -> Result<(), String> {
- let i = i_str
- .parse::<i32>()
- .expect("cannot divide the input by three");
-
- if i % 3 != 0 {
- Err("Number is not divisible by 3")?
- }
-
- Ok(())
-}
-```
-
-After:
-```
-fn divisible_by_3(i_str: String) -> Result<(), String> {
- let i = i_str
- .parse::<i32>()
- .map_err(|e| format!("cannot divide the input by three: {}", e))?;
-
- if i % 3 != 0 {
- Err("Number is not divisible by 3")?
- }
-
- Ok(())
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unwrap_or_else_default.txt b/src/tools/clippy/src/docs/unwrap_or_else_default.txt
deleted file mode 100644
index 34b4cf088..000000000
--- a/src/tools/clippy/src/docs/unwrap_or_else_default.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for usages of `_.unwrap_or_else(Default::default)` on `Option` and
-`Result` values.
-
-### Why is this bad?
-Readability, these can be written as `_.unwrap_or_default`, which is
-simpler and more concise.
-
-### Examples
-```
-x.unwrap_or_else(Default::default);
-x.unwrap_or_else(u32::default);
-```
-
-Use instead:
-```
-x.unwrap_or_default();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/unwrap_used.txt b/src/tools/clippy/src/docs/unwrap_used.txt
deleted file mode 100644
index 9b4713df5..000000000
--- a/src/tools/clippy/src/docs/unwrap_used.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-### What it does
-Checks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s.
-
-### Why is this bad?
-It is better to handle the `None` or `Err` case,
-or at least call `.expect(_)` with a more helpful message. Still, for a lot of
-quick-and-dirty code, `unwrap` is a good choice, which is why this lint is
-`Allow` by default.
-
-`result.unwrap()` will let the thread panic on `Err` values.
-Normally, you want to implement more sophisticated error handling,
-and propagate errors upwards with `?` operator.
-
-Even if you want to panic on errors, not all `Error`s implement good
-messages on display. Therefore, it may be beneficial to look at the places
-where they may get displayed. Activate this lint to do just that.
-
-### Examples
-```
-option.unwrap();
-result.unwrap();
-```
-
-Use instead:
-```
-option.expect("more helpful message");
-result.expect("more helpful message");
-```
-
-If [expect_used](#expect_used) is enabled, instead:
-```
-option?;
-
-// or
-
-result?;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/upper_case_acronyms.txt b/src/tools/clippy/src/docs/upper_case_acronyms.txt
deleted file mode 100644
index a1e39c7e1..000000000
--- a/src/tools/clippy/src/docs/upper_case_acronyms.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for fully capitalized names and optionally names containing a capitalized acronym.
-
-### Why is this bad?
-In CamelCase, acronyms count as one word.
-See [naming conventions](https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case)
-for more.
-
-By default, the lint only triggers on fully-capitalized names.
-You can use the `upper-case-acronyms-aggressive: true` config option to enable linting
-on all camel case names
-
-### Known problems
-When two acronyms are contiguous, the lint can't tell where
-the first acronym ends and the second starts, so it suggests to lowercase all of
-the letters in the second acronym.
-
-### Example
-```
-struct HTTPResponse;
-```
-Use instead:
-```
-struct HttpResponse;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/use_debug.txt b/src/tools/clippy/src/docs/use_debug.txt
deleted file mode 100644
index 94d4a6fd2..000000000
--- a/src/tools/clippy/src/docs/use_debug.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for use of `Debug` formatting. The purpose of this
-lint is to catch debugging remnants.
-
-### Why is this bad?
-The purpose of the `Debug` trait is to facilitate
-debugging Rust code. It should not be used in user-facing output.
-
-### Example
-```
-println!("{:?}", foo);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/use_self.txt b/src/tools/clippy/src/docs/use_self.txt
deleted file mode 100644
index bd37ed1e0..000000000
--- a/src/tools/clippy/src/docs/use_self.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-### What it does
-Checks for unnecessary repetition of structure name when a
-replacement with `Self` is applicable.
-
-### Why is this bad?
-Unnecessary repetition. Mixed use of `Self` and struct
-name
-feels inconsistent.
-
-### Known problems
-- Unaddressed false negative in fn bodies of trait implementations
-- False positive with associated types in traits (#4140)
-
-### Example
-```
-struct Foo;
-impl Foo {
- fn new() -> Foo {
- Foo {}
- }
-}
-```
-could be
-```
-struct Foo;
-impl Foo {
- fn new() -> Self {
- Self {}
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/used_underscore_binding.txt b/src/tools/clippy/src/docs/used_underscore_binding.txt
deleted file mode 100644
index ed67c41eb..000000000
--- a/src/tools/clippy/src/docs/used_underscore_binding.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-### What it does
-Checks for the use of bindings with a single leading
-underscore.
-
-### Why is this bad?
-A single leading underscore is usually used to indicate
-that a binding will not be used. Using such a binding breaks this
-expectation.
-
-### Known problems
-The lint does not work properly with desugaring and
-macro, it has been allowed in the mean time.
-
-### Example
-```
-let _x = 0;
-let y = _x + 1; // Here we are using `_x`, even though it has a leading
- // underscore. We should rename `_x` to `x`
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_asref.txt b/src/tools/clippy/src/docs/useless_asref.txt
deleted file mode 100644
index f777cd377..000000000
--- a/src/tools/clippy/src/docs/useless_asref.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for usage of `.as_ref()` or `.as_mut()` where the
-types before and after the call are the same.
-
-### Why is this bad?
-The call is unnecessary.
-
-### Example
-```
-let x: &[i32] = &[1, 2, 3, 4, 5];
-do_stuff(x.as_ref());
-```
-The correct use would be:
-```
-let x: &[i32] = &[1, 2, 3, 4, 5];
-do_stuff(x);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_attribute.txt b/src/tools/clippy/src/docs/useless_attribute.txt
deleted file mode 100644
index e02d4c907..000000000
--- a/src/tools/clippy/src/docs/useless_attribute.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-### What it does
-Checks for `extern crate` and `use` items annotated with
-lint attributes.
-
-This lint permits lint attributes for lints emitted on the items themself.
-For `use` items these lints are:
-* deprecated
-* unreachable_pub
-* unused_imports
-* clippy::enum_glob_use
-* clippy::macro_use_imports
-* clippy::wildcard_imports
-
-For `extern crate` items these lints are:
-* `unused_imports` on items with `#[macro_use]`
-
-### Why is this bad?
-Lint attributes have no effect on crate imports. Most
-likely a `!` was forgotten.
-
-### Example
-```
-#[deny(dead_code)]
-extern crate foo;
-#[forbid(dead_code)]
-use foo::bar;
-```
-
-Use instead:
-```
-#[allow(unused_imports)]
-use foo::baz;
-#[allow(unused_imports)]
-#[macro_use]
-extern crate baz;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_conversion.txt b/src/tools/clippy/src/docs/useless_conversion.txt
deleted file mode 100644
index 06000a7ad..000000000
--- a/src/tools/clippy/src/docs/useless_conversion.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls
-which uselessly convert to the same type.
-
-### Why is this bad?
-Redundant code.
-
-### Example
-```
-// format!() returns a `String`
-let s: String = format!("hello").into();
-```
-
-Use instead:
-```
-let s: String = format!("hello");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_format.txt b/src/tools/clippy/src/docs/useless_format.txt
deleted file mode 100644
index eb4819da1..000000000
--- a/src/tools/clippy/src/docs/useless_format.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for the use of `format!("string literal with no
-argument")` and `format!("{}", foo)` where `foo` is a string.
-
-### Why is this bad?
-There is no point of doing that. `format!("foo")` can
-be replaced by `"foo".to_owned()` if you really need a `String`. The even
-worse `&format!("foo")` is often encountered in the wild. `format!("{}",
-foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()`
-if `foo: &str`.
-
-### Examples
-```
-let foo = "foo";
-format!("{}", foo);
-```
-
-Use instead:
-```
-let foo = "foo";
-foo.to_owned();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_let_if_seq.txt b/src/tools/clippy/src/docs/useless_let_if_seq.txt
deleted file mode 100644
index c6dcd57eb..000000000
--- a/src/tools/clippy/src/docs/useless_let_if_seq.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-### What it does
-Checks for variable declarations immediately followed by a
-conditional affectation.
-
-### Why is this bad?
-This is not idiomatic Rust.
-
-### Example
-```
-let foo;
-
-if bar() {
- foo = 42;
-} else {
- foo = 0;
-}
-
-let mut baz = None;
-
-if bar() {
- baz = Some(42);
-}
-```
-
-should be written
-
-```
-let foo = if bar() {
- 42
-} else {
- 0
-};
-
-let baz = if bar() {
- Some(42)
-} else {
- None
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_transmute.txt b/src/tools/clippy/src/docs/useless_transmute.txt
deleted file mode 100644
index 1d3a17588..000000000
--- a/src/tools/clippy/src/docs/useless_transmute.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-### What it does
-Checks for transmutes to the original type of the object
-and transmutes that could be a cast.
-
-### Why is this bad?
-Readability. The code tricks people into thinking that
-something complex is going on.
-
-### Example
-```
-core::intrinsics::transmute(t); // where the result type is the same as `t`'s
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/useless_vec.txt b/src/tools/clippy/src/docs/useless_vec.txt
deleted file mode 100644
index ee5afc99e..000000000
--- a/src/tools/clippy/src/docs/useless_vec.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-Checks for usage of `&vec![..]` when using `&[..]` would
-be possible.
-
-### Why is this bad?
-This is less efficient.
-
-### Example
-```
-fn foo(_x: &[u8]) {}
-
-foo(&vec![1, 2]);
-```
-
-Use instead:
-```
-foo(&[1, 2]);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/vec_box.txt b/src/tools/clippy/src/docs/vec_box.txt
deleted file mode 100644
index 701b1c9ce..000000000
--- a/src/tools/clippy/src/docs/vec_box.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-### What it does
-Checks for use of `Vec<Box<T>>` where T: Sized anywhere in the code.
-Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.
-
-### Why is this bad?
-`Vec` already keeps its contents in a separate area on
-the heap. So if you `Box` its contents, you just add another level of indirection.
-
-### Known problems
-Vec<Box<T: Sized>> makes sense if T is a large type (see [#3530](https://github.com/rust-lang/rust-clippy/issues/3530),
-1st comment).
-
-### Example
-```
-struct X {
- values: Vec<Box<i32>>,
-}
-```
-
-Better:
-
-```
-struct X {
- values: Vec<i32>,
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/vec_init_then_push.txt b/src/tools/clippy/src/docs/vec_init_then_push.txt
deleted file mode 100644
index 445f28747..000000000
--- a/src/tools/clippy/src/docs/vec_init_then_push.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-### What it does
-Checks for calls to `push` immediately after creating a new `Vec`.
-
-If the `Vec` is created using `with_capacity` this will only lint if the capacity is a
-constant and the number of pushes is greater than or equal to the initial capacity.
-
-If the `Vec` is extended after the initial sequence of pushes and it was default initialized
-then this will only lint after there were at least four pushes. This number may change in
-the future.
-
-### Why is this bad?
-The `vec![]` macro is both more performant and easier to read than
-multiple `push` calls.
-
-### Example
-```
-let mut v = Vec::new();
-v.push(0);
-```
-Use instead:
-```
-let v = vec![0];
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/vec_resize_to_zero.txt b/src/tools/clippy/src/docs/vec_resize_to_zero.txt
deleted file mode 100644
index 0b9268677..000000000
--- a/src/tools/clippy/src/docs/vec_resize_to_zero.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Finds occurrences of `Vec::resize(0, an_int)`
-
-### Why is this bad?
-This is probably an argument inversion mistake.
-
-### Example
-```
-vec!(1, 2, 3, 4, 5).resize(0, 5)
-```
-
-Use instead:
-```
-vec!(1, 2, 3, 4, 5).clear()
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/verbose_bit_mask.txt b/src/tools/clippy/src/docs/verbose_bit_mask.txt
deleted file mode 100644
index 87a847029..000000000
--- a/src/tools/clippy/src/docs/verbose_bit_mask.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for bit masks that can be replaced by a call
-to `trailing_zeros`
-
-### Why is this bad?
-`x.trailing_zeros() > 4` is much clearer than `x & 15
-== 0`
-
-### Known problems
-llvm generates better code for `x & 15 == 0` on x86
-
-### Example
-```
-if x & 0b1111 == 0 { }
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/verbose_file_reads.txt b/src/tools/clippy/src/docs/verbose_file_reads.txt
deleted file mode 100644
index 9703df423..000000000
--- a/src/tools/clippy/src/docs/verbose_file_reads.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for use of File::read_to_end and File::read_to_string.
-
-### Why is this bad?
-`fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values.
-See also: [fs::read docs](https://doc.rust-lang.org/std/fs/fn.read.html), [fs::read_to_string docs](https://doc.rust-lang.org/std/fs/fn.read_to_string.html)
-
-### Example
-```
-let mut f = File::open("foo.txt").unwrap();
-let mut bytes = Vec::new();
-f.read_to_end(&mut bytes).unwrap();
-```
-Can be written more concisely as
-```
-let mut bytes = fs::read("foo.txt").unwrap();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/vtable_address_comparisons.txt b/src/tools/clippy/src/docs/vtable_address_comparisons.txt
deleted file mode 100644
index 4a34e4ba7..000000000
--- a/src/tools/clippy/src/docs/vtable_address_comparisons.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-Checks for comparisons with an address of a trait vtable.
-
-### Why is this bad?
-Comparing trait objects pointers compares an vtable addresses which
-are not guaranteed to be unique and could vary between different code generation units.
-Furthermore vtables for different types could have the same address after being merged
-together.
-
-### Example
-```
-let a: Rc<dyn Trait> = ...
-let b: Rc<dyn Trait> = ...
-if Rc::ptr_eq(&a, &b) {
- ...
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/while_immutable_condition.txt b/src/tools/clippy/src/docs/while_immutable_condition.txt
deleted file mode 100644
index 71800701f..000000000
--- a/src/tools/clippy/src/docs/while_immutable_condition.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks whether variables used within while loop condition
-can be (and are) mutated in the body.
-
-### Why is this bad?
-If the condition is unchanged, entering the body of the loop
-will lead to an infinite loop.
-
-### Known problems
-If the `while`-loop is in a closure, the check for mutation of the
-condition variables in the body can cause false negatives. For example when only `Upvar` `a` is
-in the condition and only `Upvar` `b` gets mutated in the body, the lint will not trigger.
-
-### Example
-```
-let i = 0;
-while i > 10 {
- println!("let me loop forever!");
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/while_let_loop.txt b/src/tools/clippy/src/docs/while_let_loop.txt
deleted file mode 100644
index ab7bf6097..000000000
--- a/src/tools/clippy/src/docs/while_let_loop.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Detects `loop + match` combinations that are easier
-written as a `while let` loop.
-
-### Why is this bad?
-The `while let` loop is usually shorter and more
-readable.
-
-### Known problems
-Sometimes the wrong binding is displayed ([#383](https://github.com/rust-lang/rust-clippy/issues/383)).
-
-### Example
-```
-loop {
- let x = match y {
- Some(x) => x,
- None => break,
- };
- // .. do something with x
-}
-// is easier written as
-while let Some(x) = y {
- // .. do something with x
-};
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/while_let_on_iterator.txt b/src/tools/clippy/src/docs/while_let_on_iterator.txt
deleted file mode 100644
index af053c541..000000000
--- a/src/tools/clippy/src/docs/while_let_on_iterator.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-### What it does
-Checks for `while let` expressions on iterators.
-
-### Why is this bad?
-Readability. A simple `for` loop is shorter and conveys
-the intent better.
-
-### Example
-```
-while let Some(val) = iter.next() {
- ..
-}
-```
-
-Use instead:
-```
-for val in &mut iter {
- ..
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wildcard_dependencies.txt b/src/tools/clippy/src/docs/wildcard_dependencies.txt
deleted file mode 100644
index 2affaf974..000000000
--- a/src/tools/clippy/src/docs/wildcard_dependencies.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-### What it does
-Checks for wildcard dependencies in the `Cargo.toml`.
-
-### Why is this bad?
-[As the edition guide says](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html),
-it is highly unlikely that you work with any possible version of your dependency,
-and wildcard dependencies would cause unnecessary breakage in the ecosystem.
-
-### Example
-```
-[dependencies]
-regex = "*"
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wildcard_enum_match_arm.txt b/src/tools/clippy/src/docs/wildcard_enum_match_arm.txt
deleted file mode 100644
index 09807c01c..000000000
--- a/src/tools/clippy/src/docs/wildcard_enum_match_arm.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-### What it does
-Checks for wildcard enum matches using `_`.
-
-### Why is this bad?
-New enum variants added by library updates can be missed.
-
-### Known problems
-Suggested replacements may be incorrect if guards exhaustively cover some
-variants, and also may not use correct path to enum if it's not present in the current scope.
-
-### Example
-```
-match x {
- Foo::A(_) => {},
- _ => {},
-}
-```
-
-Use instead:
-```
-match x {
- Foo::A(_) => {},
- Foo::B(_) => {},
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wildcard_imports.txt b/src/tools/clippy/src/docs/wildcard_imports.txt
deleted file mode 100644
index bd56aa5b0..000000000
--- a/src/tools/clippy/src/docs/wildcard_imports.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-### What it does
-Checks for wildcard imports `use _::*`.
-
-### Why is this bad?
-wildcard imports can pollute the namespace. This is especially bad if
-you try to import something through a wildcard, that already has been imported by name from
-a different source:
-
-```
-use crate1::foo; // Imports a function named foo
-use crate2::*; // Has a function named foo
-
-foo(); // Calls crate1::foo
-```
-
-This can lead to confusing error messages at best and to unexpected behavior at worst.
-
-### Exceptions
-Wildcard imports are allowed from modules named `prelude`. Many crates (including the standard library)
-provide modules named "prelude" specifically designed for wildcard import.
-
-`use super::*` is allowed in test modules. This is defined as any module with "test" in the name.
-
-These exceptions can be disabled using the `warn-on-all-wildcard-imports` configuration flag.
-
-### Known problems
-If macros are imported through the wildcard, this macro is not included
-by the suggestion and has to be added by hand.
-
-Applying the suggestion when explicit imports of the things imported with a glob import
-exist, may result in `unused_imports` warnings.
-
-### Example
-```
-use crate1::*;
-
-foo();
-```
-
-Use instead:
-```
-use crate1::foo;
-
-foo();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wildcard_in_or_patterns.txt b/src/tools/clippy/src/docs/wildcard_in_or_patterns.txt
deleted file mode 100644
index 70468ca41..000000000
--- a/src/tools/clippy/src/docs/wildcard_in_or_patterns.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-### What it does
-Checks for wildcard pattern used with others patterns in same match arm.
-
-### Why is this bad?
-Wildcard pattern already covers any other pattern as it will match anyway.
-It makes the code less readable, especially to spot wildcard pattern use in match arm.
-
-### Example
-```
-match s {
- "a" => {},
- "bar" | _ => {},
-}
-```
-
-Use instead:
-```
-match s {
- "a" => {},
- _ => {},
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/write_literal.txt b/src/tools/clippy/src/docs/write_literal.txt
deleted file mode 100644
index a7a884d08..000000000
--- a/src/tools/clippy/src/docs/write_literal.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-### What it does
-This lint warns about the use of literals as `write!`/`writeln!` args.
-
-### Why is this bad?
-Using literals as `writeln!` args is inefficient
-(c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary
-(i.e., just put the literal in the format string)
-
-### Example
-```
-writeln!(buf, "{}", "foo");
-```
-
-Use instead:
-```
-writeln!(buf, "foo");
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/write_with_newline.txt b/src/tools/clippy/src/docs/write_with_newline.txt
deleted file mode 100644
index 22845fd65..000000000
--- a/src/tools/clippy/src/docs/write_with_newline.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-### What it does
-This lint warns when you use `write!()` with a format
-string that
-ends in a newline.
-
-### Why is this bad?
-You should use `writeln!()` instead, which appends the
-newline.
-
-### Example
-```
-write!(buf, "Hello {}!\n", name);
-```
-
-Use instead:
-```
-writeln!(buf, "Hello {}!", name);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/writeln_empty_string.txt b/src/tools/clippy/src/docs/writeln_empty_string.txt
deleted file mode 100644
index 3b3aeb79a..000000000
--- a/src/tools/clippy/src/docs/writeln_empty_string.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### What it does
-This lint warns when you use `writeln!(buf, "")` to
-print a newline.
-
-### Why is this bad?
-You should use `writeln!(buf)`, which is simpler.
-
-### Example
-```
-writeln!(buf, "");
-```
-
-Use instead:
-```
-writeln!(buf);
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wrong_self_convention.txt b/src/tools/clippy/src/docs/wrong_self_convention.txt
deleted file mode 100644
index d6b69ab87..000000000
--- a/src/tools/clippy/src/docs/wrong_self_convention.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-### What it does
-Checks for methods with certain name prefixes and which
-doesn't match how self is taken. The actual rules are:
-
-|Prefix |Postfix |`self` taken | `self` type |
-|-------|------------|-------------------------------|--------------|
-|`as_` | none |`&self` or `&mut self` | any |
-|`from_`| none | none | any |
-|`into_`| none |`self` | any |
-|`is_` | none |`&mut self` or `&self` or none | any |
-|`to_` | `_mut` |`&mut self` | any |
-|`to_` | not `_mut` |`self` | `Copy` |
-|`to_` | not `_mut` |`&self` | not `Copy` |
-
-Note: Clippy doesn't trigger methods with `to_` prefix in:
-- Traits definition.
-Clippy can not tell if a type that implements a trait is `Copy` or not.
-- Traits implementation, when `&self` is taken.
-The method signature is controlled by the trait and often `&self` is required for all types that implement the trait
-(see e.g. the `std::string::ToString` trait).
-
-Clippy allows `Pin<&Self>` and `Pin<&mut Self>` if `&self` and `&mut self` is required.
-
-Please find more info here:
-https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv
-
-### Why is this bad?
-Consistency breeds readability. If you follow the
-conventions, your users won't be surprised that they, e.g., need to supply a
-mutable reference to a `as_..` function.
-
-### Example
-```
-impl X {
- fn as_str(self) -> &'static str {
- // ..
- }
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/wrong_transmute.txt b/src/tools/clippy/src/docs/wrong_transmute.txt
deleted file mode 100644
index 9fc71e0e3..000000000
--- a/src/tools/clippy/src/docs/wrong_transmute.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for transmutes that can't ever be correct on any
-architecture.
-
-### Why is this bad?
-It's basically guaranteed to be undefined behavior.
-
-### Known problems
-When accessing C, users might want to store pointer
-sized objects in `extradata` arguments to save an allocation.
-
-### Example
-```
-let ptr: *const T = core::intrinsics::transmute('x')
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/zero_divided_by_zero.txt b/src/tools/clippy/src/docs/zero_divided_by_zero.txt
deleted file mode 100644
index 394de20c0..000000000
--- a/src/tools/clippy/src/docs/zero_divided_by_zero.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-### What it does
-Checks for `0.0 / 0.0`.
-
-### Why is this bad?
-It's less readable than `f32::NAN` or `f64::NAN`.
-
-### Example
-```
-let nan = 0.0f32 / 0.0;
-```
-
-Use instead:
-```
-let nan = f32::NAN;
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/zero_prefixed_literal.txt b/src/tools/clippy/src/docs/zero_prefixed_literal.txt
deleted file mode 100644
index 5c5588725..000000000
--- a/src/tools/clippy/src/docs/zero_prefixed_literal.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-### What it does
-Warns if an integral constant literal starts with `0`.
-
-### Why is this bad?
-In some languages (including the infamous C language
-and most of its
-family), this marks an octal constant. In Rust however, this is a decimal
-constant. This could
-be confusing for both the writer and a reader of the constant.
-
-### Example
-
-In Rust:
-```
-fn main() {
- let a = 0123;
- println!("{}", a);
-}
-```
-
-prints `123`, while in C:
-
-```
-#include <stdio.h>
-
-int main() {
- int a = 0123;
- printf("%d\n", a);
-}
-```
-
-prints `83` (as `83 == 0o123` while `123 == 0o173`). \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/zero_ptr.txt b/src/tools/clippy/src/docs/zero_ptr.txt
deleted file mode 100644
index e768a0236..000000000
--- a/src/tools/clippy/src/docs/zero_ptr.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-### 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
-```
-let a = 0 as *const u32;
-```
-
-Use instead:
-```
-let a = std::ptr::null::<u32>();
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/zero_sized_map_values.txt b/src/tools/clippy/src/docs/zero_sized_map_values.txt
deleted file mode 100644
index 0502bdbf3..000000000
--- a/src/tools/clippy/src/docs/zero_sized_map_values.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-### What it does
-Checks for maps with zero-sized value types anywhere in the code.
-
-### Why is this bad?
-Since there is only a single value for a zero-sized type, a map
-containing zero sized values is effectively a set. Using a set in that case improves
-readability and communicates intent more clearly.
-
-### Known problems
-* A zero-sized type cannot be recovered later if it contains private fields.
-* This lints the signature of public items
-
-### Example
-```
-fn unique_words(text: &str) -> HashMap<&str, ()> {
- todo!();
-}
-```
-Use instead:
-```
-fn unique_words(text: &str) -> HashSet<&str> {
- todo!();
-}
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/docs/zst_offset.txt b/src/tools/clippy/src/docs/zst_offset.txt
deleted file mode 100644
index 5810455ee..000000000
--- a/src/tools/clippy/src/docs/zst_offset.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-### What it does
-Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to
-zero-sized types
-
-### Why is this bad?
-This is a no-op, and likely unintended
-
-### Example
-```
-unsafe { (&() as *const ()).offset(1) };
-``` \ No newline at end of file
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index b12208ac6..9ec4df8e6 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -1,5 +1,7 @@
#![feature(rustc_private)]
+#![feature(let_chains)]
#![feature(once_cell)]
+#![feature(lint_reasons)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
// warn on lints, that are included in `rust-lang/rust`s bootstrap
#![warn(rust_2018_idioms, unused_lifetimes)]
@@ -23,8 +25,8 @@ use std::borrow::Cow;
use std::env;
use std::ops::Deref;
use std::panic;
-use std::path::{Path, PathBuf};
-use std::process::{exit, Command};
+use std::path::Path;
+use std::process::exit;
use std::sync::LazyLock;
/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
@@ -71,6 +73,37 @@ fn track_clippy_args(parse_sess: &mut ParseSess, args_env_var: &Option<String>)
));
}
+/// Track files that may be accessed at runtime in `file_depinfo` so that cargo will re-run clippy
+/// when any of them are modified
+fn track_files(parse_sess: &mut ParseSess, conf_path_string: Option<String>) {
+ let file_depinfo = parse_sess.file_depinfo.get_mut();
+
+ // Used by `clippy::cargo` lints and to determine the MSRV. `cargo clippy` executes `clippy-driver`
+ // with the current directory set to `CARGO_MANIFEST_DIR` so a relative path is fine
+ if Path::new("Cargo.toml").exists() {
+ file_depinfo.insert(Symbol::intern("Cargo.toml"));
+ }
+
+ // `clippy.toml`
+ if let Some(path) = conf_path_string {
+ file_depinfo.insert(Symbol::intern(&path));
+ }
+
+ // During development track the `clippy-driver` executable so that cargo will re-run clippy whenever
+ // it is rebuilt
+ #[expect(
+ clippy::collapsible_if,
+ reason = "Due to a bug in let_chains this if statement can't be collapsed"
+ )]
+ if cfg!(debug_assertions) {
+ if let Ok(current_exe) = env::current_exe()
+ && let Some(current_exe) = current_exe.to_str()
+ {
+ file_depinfo.insert(Symbol::intern(current_exe));
+ }
+ }
+}
+
struct DefaultCallbacks;
impl rustc_driver::Callbacks for DefaultCallbacks {}
@@ -97,10 +130,18 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
// JUSTIFICATION: necessary in clippy driver to set `mir_opt_level`
#[allow(rustc::bad_opt_access)]
fn config(&mut self, config: &mut interface::Config) {
+ let conf_path = clippy_lints::lookup_conf_file();
+ let conf_path_string = if let Ok(Some(path)) = &conf_path {
+ path.to_str().map(String::from)
+ } else {
+ None
+ };
+
let previous = config.register_lints.take();
let clippy_args_var = self.clippy_args_var.take();
config.parse_sess_created = Some(Box::new(move |parse_sess| {
track_clippy_args(parse_sess, &clippy_args_var);
+ track_files(parse_sess, conf_path_string);
}));
config.register_lints = Some(Box::new(move |sess, lint_store| {
// technically we're ~guaranteed that this is none but might as well call anything that
@@ -109,7 +150,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
(previous)(sess, lint_store);
}
- let conf = clippy_lints::read_conf(sess);
+ let conf = clippy_lints::read_conf(sess, &conf_path);
clippy_lints::register_plugins(lint_store, sess, &conf);
clippy_lints::register_pre_expansion_lints(lint_store, sess, &conf);
clippy_lints::register_renamed(lint_store);
@@ -179,6 +220,7 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
false,
None,
false,
+ false,
));
let handler = rustc_errors::Handler::with_emitter(true, None, emitter);
@@ -209,17 +251,6 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
interface::try_print_query_stack(&handler, num_frames);
}
-fn toolchain_path(home: Option<String>, toolchain: Option<String>) -> Option<PathBuf> {
- home.and_then(|home| {
- toolchain.map(|toolchain| {
- let mut path = PathBuf::from(home);
- path.push("toolchains");
- path.push(toolchain);
- path
- })
- })
-}
-
#[allow(clippy::too_many_lines)]
pub fn main() {
rustc_driver::init_rustc_env_logger();
@@ -227,50 +258,12 @@ pub fn main() {
exit(rustc_driver::catch_with_exit_code(move || {
let mut orig_args: Vec<String> = env::args().collect();
- // Get the sysroot, looking from most specific to this invocation to the least:
- // - command line
- // - runtime environment
- // - SYSROOT
- // - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
- // - sysroot from rustc in the path
- // - compile-time environment
- // - SYSROOT
- // - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
- let sys_root_arg = arg_value(&orig_args, "--sysroot", |_| true);
- let have_sys_root_arg = sys_root_arg.is_some();
- let sys_root = sys_root_arg
- .map(PathBuf::from)
- .or_else(|| std::env::var("SYSROOT").ok().map(PathBuf::from))
- .or_else(|| {
- let home = std::env::var("RUSTUP_HOME")
- .or_else(|_| std::env::var("MULTIRUST_HOME"))
- .ok();
- let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
- .or_else(|_| std::env::var("MULTIRUST_TOOLCHAIN"))
- .ok();
- toolchain_path(home, toolchain)
- })
- .or_else(|| {
- Command::new("rustc")
- .arg("--print")
- .arg("sysroot")
- .output()
- .ok()
- .and_then(|out| String::from_utf8(out.stdout).ok())
- .map(|s| PathBuf::from(s.trim()))
- })
- .or_else(|| option_env!("SYSROOT").map(PathBuf::from))
- .or_else(|| {
- let home = option_env!("RUSTUP_HOME")
- .or(option_env!("MULTIRUST_HOME"))
- .map(ToString::to_string);
- let toolchain = option_env!("RUSTUP_TOOLCHAIN")
- .or(option_env!("MULTIRUST_TOOLCHAIN"))
- .map(ToString::to_string);
- toolchain_path(home, toolchain)
- })
- .map(|pb| pb.to_string_lossy().to_string())
- .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");
+ let sys_root_env = std::env::var("SYSROOT").ok();
+ let pass_sysroot_env_if_given = |args: &mut Vec<String>, sys_root_env| {
+ if let Some(sys_root) = sys_root_env {
+ args.extend(vec!["--sysroot".into(), sys_root]);
+ };
+ };
// make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc"
// for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver
@@ -279,11 +272,8 @@ pub fn main() {
orig_args.remove(pos);
orig_args[0] = "rustc".to_string();
- // if we call "rustc", we need to pass --sysroot here as well
let mut args: Vec<String> = orig_args.clone();
- if !have_sys_root_arg {
- args.extend(vec!["--sysroot".into(), sys_root]);
- };
+ pass_sysroot_env_if_given(&mut args, sys_root_env);
return rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run();
}
@@ -308,13 +298,8 @@ pub fn main() {
exit(0);
}
- // this conditional check for the --sysroot flag is there so users can call
- // `clippy_driver` directly
- // without having to pass --sysroot or anything
let mut args: Vec<String> = orig_args.clone();
- if !have_sys_root_arg {
- args.extend(vec!["--sysroot".into(), sys_root]);
- };
+ pass_sysroot_env_if_given(&mut args, sys_root_env);
let mut no_deps = false;
let clippy_args_var = env::var("CLIPPY_ARGS").ok();
diff --git a/src/tools/clippy/src/main.rs b/src/tools/clippy/src/main.rs
index fce3cdfc4..d418d2daa 100644
--- a/src/tools/clippy/src/main.rs
+++ b/src/tools/clippy/src/main.rs
@@ -7,8 +7,6 @@ use std::env;
use std::path::PathBuf;
use std::process::{self, Command};
-mod docs;
-
const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.
Usage:
@@ -60,7 +58,7 @@ pub fn main() {
if let Some(pos) = env::args().position(|a| a == "--explain") {
if let Some(mut lint) = env::args().nth(pos + 1) {
lint.make_ascii_lowercase();
- docs::explain(&lint.strip_prefix("clippy::").unwrap_or(&lint).replace('-', "_"));
+ clippy_lints::explain(&lint.strip_prefix("clippy::").unwrap_or(&lint).replace('-', "_"));
} else {
show_help();
}
diff --git a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_both_diff/src/main.stderr b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_both_diff/src/main.stderr
index 9a7d802dc..163f8bb35 100644
--- a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_both_diff/src/main.stderr
+++ b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_both_diff/src/main.stderr
@@ -12,5 +12,11 @@ note: the lint level is defined here
LL | #![deny(clippy::use_self)]
| ^^^^^^^^^^^^^^^^
-error: aborting due to previous error; 1 warning emitted
+error: unnecessary structure name repetition
+ --> $DIR/main.rs:7:9
+ |
+LL | Foo
+ | ^^^ help: use the applicable keyword: `Self`
+
+error: aborting due to 2 previous errors; 1 warning emitted
diff --git a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_both_same/src/main.stderr b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_both_same/src/main.stderr
index a280e1bac..259d39b12 100644
--- a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_both_same/src/main.stderr
+++ b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_both_same/src/main.stderr
@@ -10,5 +10,11 @@ note: the lint level is defined here
LL | #![deny(clippy::use_self)]
| ^^^^^^^^^^^^^^^^
-error: aborting due to previous error
+error: unnecessary structure name repetition
+ --> $DIR/main.rs:7:9
+ |
+LL | Foo
+ | ^^^ help: use the applicable keyword: `Self`
+
+error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_cargo/src/main.stderr b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_cargo/src/main.stderr
index a280e1bac..259d39b12 100644
--- a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_cargo/src/main.stderr
+++ b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_cargo/src/main.stderr
@@ -10,5 +10,11 @@ note: the lint level is defined here
LL | #![deny(clippy::use_self)]
| ^^^^^^^^^^^^^^^^
-error: aborting due to previous error
+error: unnecessary structure name repetition
+ --> $DIR/main.rs:7:9
+ |
+LL | Foo
+ | ^^^ help: use the applicable keyword: `Self`
+
+error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_clippy/src/main.stderr b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_clippy/src/main.stderr
index a280e1bac..259d39b12 100644
--- a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_clippy/src/main.stderr
+++ b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_clippy/src/main.stderr
@@ -10,5 +10,11 @@ note: the lint level is defined here
LL | #![deny(clippy::use_self)]
| ^^^^^^^^^^^^^^^^
-error: aborting due to previous error
+error: unnecessary structure name repetition
+ --> $DIR/main.rs:7:9
+ |
+LL | Foo
+ | ^^^ help: use the applicable keyword: `Self`
+
+error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_file_attr/src/main.stderr b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_file_attr/src/main.stderr
index 88f6e0092..97e6c3d5a 100644
--- a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_file_attr/src/main.stderr
+++ b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_file_attr/src/main.stderr
@@ -10,5 +10,11 @@ note: the lint level is defined here
LL | #![deny(clippy::use_self)]
| ^^^^^^^^^^^^^^^^
-error: aborting due to previous error
+error: unnecessary structure name repetition
+ --> $DIR/main.rs:12:9
+ |
+LL | Foo
+ | ^^^ help: use the applicable keyword: `Self`
+
+error: aborting due to 2 previous errors
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
index 5057a0183..4be04f77f 100644
--- a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
@@ -2,6 +2,7 @@
// normalize-stderr-test: "Clippy version: .*" -> "Clippy version: foo"
// normalize-stderr-test: "internal_lints.rs:\d*:\d*" -> "internal_lints.rs"
// normalize-stderr-test: "', .*clippy_lints" -> "', clippy_lints"
+// normalize-stderr-test: "'rustc'" -> "'<unnamed>'"
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
index 07c594101..2ba589066 100644
--- a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
@@ -1,4 +1,4 @@
-thread 'rustc' panicked at 'Would you like some help with that?', clippy_lints/src/utils/internal_lints/produce_ice.rs:28:9
+thread '<unnamed>' panicked at 'Would you like some help with that?', clippy_lints/src/utils/internal_lints/produce_ice.rs:28:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: internal compiler error: unexpected panic
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 900a8fffd..08634063a 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
@@ -11,9 +11,9 @@ extern crate rustc_middle;
#[macro_use]
extern crate rustc_session;
use clippy_utils::extract_msrv_attr;
+use clippy_utils::msrvs::Msrv;
use rustc_hir::Expr;
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
-use rustc_semver::RustcVersion;
declare_lint! {
pub TEST_LINT,
@@ -22,7 +22,7 @@ declare_lint! {
}
struct Pass {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl_lint_pass!(Pass => [TEST_LINT]);
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 4bc8164db..f8af77e6d 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
@@ -11,9 +11,9 @@ extern crate rustc_middle;
#[macro_use]
extern crate rustc_session;
use clippy_utils::extract_msrv_attr;
+use clippy_utils::msrvs::Msrv;
use rustc_hir::Expr;
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
-use rustc_semver::RustcVersion;
declare_lint! {
pub TEST_LINT,
@@ -22,7 +22,7 @@ declare_lint! {
}
struct Pass {
- msrv: Option<RustcVersion>,
+ msrv: Msrv,
}
impl_lint_pass!(Pass => [TEST_LINT]);
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 cbbb46523..e474f370a 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
@@ -48,14 +48,14 @@ fn _f<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, did: DefId, expr: &Expr<'_>) {
let _ = is_type_lang_item(cx, ty, LangItem::OwnedBox);
let _ = is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit);
- let _ = cx.tcx.lang_items().require(LangItem::OwnedBox).ok() == Some(did);
+ let _ = cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did);
let _ = cx.tcx.is_diagnostic_item(sym::Option, did);
- let _ = cx.tcx.lang_items().require(LangItem::OptionSome).ok() == Some(did);
+ let _ = cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did);
let _ = is_trait_method(cx, expr, sym::AsRef);
let _ = is_path_diagnostic_item(cx, expr, sym::Option);
- let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().require(LangItem::IteratorNext).ok() == Some(id));
+ let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id));
let _ = is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome);
}
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 a99a8f71f..3ca29f099 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
@@ -57,7 +57,7 @@ error: use of a def path to a `LangItem`
--> $DIR/unnecessary_def_path.rs:51:13
|
LL | let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().require(LangItem::OwnedBox).ok() == Some(did)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
@@ -69,7 +69,7 @@ error: use of a def path to a `LangItem`
--> $DIR/unnecessary_def_path.rs:53:13
|
LL | let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().require(LangItem::OptionSome).ok() == Some(did)`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did)`
|
= help: if this `DefId` came from a constructor expression or pattern then the parent `DefId` should be used instead
@@ -89,7 +89,7 @@ error: use of a def path to a `LangItem`
--> $DIR/unnecessary_def_path.rs:58: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().require(LangItem::IteratorNext).ok() == Some(id))`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
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 af46d87bf..2a240cc24 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
@@ -1,10 +1,10 @@
-error: hardcoded path to a language item
- --> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
+error: hardcoded path to a diagnostic item
+ --> $DIR/unnecessary_def_path_hardcoded_path.rs:10:36
|
-LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: convert all references to use `LangItem::DerefMut`
+ = help: convert all references to use `sym::Deref`
= note: `-D clippy::unnecessary-def-path` implied by `-D warnings`
error: hardcoded path to a diagnostic item
@@ -15,13 +15,13 @@ LL | const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref",
|
= help: convert all references to use `sym::deref_method`
-error: hardcoded path to a diagnostic item
- --> $DIR/unnecessary_def_path_hardcoded_path.rs:10:36
+error: hardcoded path to a language item
+ --> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
|
-LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = help: convert all references to use `sym::Deref`
+ = help: convert all references to use `LangItem::DerefMut`
error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/clippy.toml b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/clippy.toml
new file mode 100644
index 000000000..b95e806aa
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/clippy.toml
@@ -0,0 +1 @@
+allow-mixed-uninlined-format-args = false
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
new file mode 100644
index 000000000..aa8b45b5f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+#![warn(clippy::uninlined_format_args)]
+
+fn main() {
+ let local_i32 = 1;
+ let local_f64 = 2.0;
+ let local_opt: Option<i32> = Some(3);
+
+ println!("val='{local_i32}'");
+ println!("Hello x is {local_f64:.local_i32$}");
+ println!("Hello {local_i32} is {local_f64:.*}", 5);
+ println!("Hello {local_i32} is {local_f64:.*}", 5);
+ println!("{local_i32}, {}", local_opt.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
new file mode 100644
index 000000000..ad2e4863e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+#![warn(clippy::uninlined_format_args)]
+
+fn main() {
+ let local_i32 = 1;
+ let local_f64 = 2.0;
+ let local_opt: Option<i32> = Some(3);
+
+ println!("val='{}'", local_i32);
+ println!("Hello {} is {:.*}", "x", local_i32, local_f64);
+ println!("Hello {} is {:.*}", local_i32, 5, local_f64);
+ println!("Hello {} is {2:.*}", local_i32, 5, local_f64);
+ println!("{}, {}", local_i32, local_opt.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
new file mode 100644
index 000000000..ee9417621
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr
@@ -0,0 +1,76 @@
+error: variables can be used directly in the `format!` string
+ --> $DIR/uninlined_format_args.rs:9:5
+ |
+LL | println!("val='{}'", local_i32);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::uninlined-format-args` implied by `-D warnings`
+help: change this to
+ |
+LL - println!("val='{}'", local_i32);
+LL + println!("val='{local_i32}'");
+ |
+
+error: literal with an empty format string
+ --> $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: try this
+ |
+LL - println!("Hello {} is {:.*}", "x", local_i32, local_f64);
+LL + println!("Hello x is {:.*}", local_i32, local_f64);
+ |
+
+error: variables can be used directly in the `format!` string
+ --> $DIR/uninlined_format_args.rs:10:5
+ |
+LL | println!("Hello {} is {:.*}", "x", local_i32, local_f64);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: change this to
+ |
+LL - println!("Hello {} is {:.*}", "x", local_i32, local_f64);
+LL + println!("Hello {} is {local_f64:.local_i32$}", "x");
+ |
+
+error: variables can be used directly in the `format!` string
+ --> $DIR/uninlined_format_args.rs:11:5
+ |
+LL | println!("Hello {} is {:.*}", local_i32, 5, local_f64);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: change this to
+ |
+LL - println!("Hello {} is {:.*}", local_i32, 5, local_f64);
+LL + println!("Hello {local_i32} is {local_f64:.*}", 5);
+ |
+
+error: variables can be used directly in the `format!` string
+ --> $DIR/uninlined_format_args.rs:12:5
+ |
+LL | println!("Hello {} is {2:.*}", local_i32, 5, local_f64);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: change this to
+ |
+LL - println!("Hello {} is {2:.*}", local_i32, 5, local_f64);
+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
+ |
+LL | println!("{}, {}", local_i32, local_opt.unwrap());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: change this to
+ |
+LL - println!("{}, {}", local_i32, local_opt.unwrap());
+LL + println!("{local_i32}, {}", local_opt.unwrap());
+ |
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs b/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs
index 1aed09b7c..e8a023ab1 100644
--- a/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs
+++ b/src/tools/clippy/tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs
@@ -1,6 +1,6 @@
#![warn(clippy::arithmetic_side_effects)]
-use core::ops::Add;
+use core::ops::{Add, Neg};
#[derive(Clone, Copy)]
struct Point {
@@ -16,9 +16,18 @@ impl Add for Point {
}
}
+impl Neg for Point {
+ type Output = Self;
+
+ fn neg(self) -> Self::Output {
+ todo!()
+ }
+}
+
fn main() {
let _ = Point { x: 1, y: 0 } + Point { x: 2, y: 3 };
let point: Point = Point { x: 1, y: 0 };
let _ = point + point;
+ let _ = -point;
}
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 4c7599843..825aa1487 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
@@ -4,7 +4,7 @@ error: `std::string::String` may not be held across an `await` point per `clippy
LL | let _x = String::from("hello");
| ^^
|
- = note: strings are bad
+ = note: strings are bad (from clippy.toml)
= note: `-D clippy::await-holding-invalid-type` implied by `-D warnings`
error: `std::net::Ipv4Addr` may not be held across an `await` point per `clippy.toml`
@@ -19,7 +19,7 @@ error: `std::string::String` may not be held across an `await` point per `clippy
LL | let _x = String::from("hi!");
| ^^
|
- = note: strings are bad
+ = note: strings are bad (from clippy.toml)
error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs
index 22dcd3ae9..bff97d97d 100644
--- a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs
+++ b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs
@@ -16,14 +16,19 @@ fn main() {
expect_result();
}
-#[test]
-fn test_expect_option() {
- let opt = Some(0);
- let _ = opt.expect("");
-}
+#[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("");
-#[test]
-fn test_expect_result() {
- let res: Result<u8, ()> = Ok(0);
- let _ = res.expect("");
+ util();
+ }
+
+ fn util() {
+ let _a: u8 = 4.try_into().unwrap();
+ let _a: u8 = 5.try_into().expect("");
+ }
}
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 28a08599c..1e9bb48c3 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
@@ -1,4 +1,4 @@
-error: used `expect()` on `an Option` value
+error: used `expect()` on an `Option` value
--> $DIR/expect_used.rs:6:13
|
LL | let _ = opt.expect("");
@@ -7,7 +7,7 @@ LL | let _ = opt.expect("");
= help: if this value is `None`, it will panic
= note: `-D clippy::expect-used` implied by `-D warnings`
-error: used `expect()` on `a Result` value
+error: used `expect()` on a `Result` value
--> $DIR/expect_used.rs:11:13
|
LL | let _ = res.expect("");
diff --git a/src/tools/clippy/tests/ui-toml/mut_key/clippy.toml b/src/tools/clippy/tests/ui-toml/mut_key/clippy.toml
new file mode 100644
index 000000000..6d33e192e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/mut_key/clippy.toml
@@ -0,0 +1 @@
+ignore-interior-mutability = ["mut_key::Counted"] \ No newline at end of file
diff --git a/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs b/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs
new file mode 100644
index 000000000..667c51cb4
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs
@@ -0,0 +1,53 @@
+// compile-flags: --crate-name mut_key
+
+#![warn(clippy::mutable_key_type)]
+
+use std::cmp::{Eq, PartialEq};
+use std::collections::{HashMap, HashSet};
+use std::hash::{Hash, Hasher};
+use std::ops::Deref;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+struct Counted<T> {
+ count: AtomicUsize,
+ val: T,
+}
+
+impl<T: Clone> Clone for Counted<T> {
+ fn clone(&self) -> Self {
+ Self {
+ count: AtomicUsize::new(0),
+ val: self.val.clone(),
+ }
+ }
+}
+
+impl<T: PartialEq> PartialEq for Counted<T> {
+ fn eq(&self, other: &Self) -> bool {
+ self.val == other.val
+ }
+}
+impl<T: PartialEq + Eq> Eq for Counted<T> {}
+
+impl<T: Hash> Hash for Counted<T> {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.val.hash(state);
+ }
+}
+
+impl<T> Deref for Counted<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ self.count.fetch_add(1, Ordering::AcqRel);
+ &self.val
+ }
+}
+
+// This is not linted because `"mut_key::Counted"` is in
+// `arc_like_types` in `clippy.toml`
+fn should_not_take_this_arg(_v: HashSet<Counted<String>>) {}
+
+fn main() {
+ should_not_take_this_arg(HashSet::new());
+}
diff --git a/src/tools/clippy/tests/ui-toml/print_macro/clippy.toml b/src/tools/clippy/tests/ui-toml/print_macro/clippy.toml
new file mode 100644
index 000000000..40b1dda5b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/print_macro/clippy.toml
@@ -0,0 +1 @@
+allow-print-in-tests = true
diff --git a/src/tools/clippy/tests/ui-toml/print_macro/print_macro.rs b/src/tools/clippy/tests/ui-toml/print_macro/print_macro.rs
new file mode 100644
index 000000000..5aefb6a6b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/print_macro/print_macro.rs
@@ -0,0 +1,20 @@
+// compile-flags: --test
+#![warn(clippy::print_stdout)]
+#![warn(clippy::print_stderr)]
+
+fn foo(n: u32) {
+ print!("{n}");
+ eprint!("{n}");
+}
+
+#[test]
+pub fn foo1() {
+ print!("{}", 1);
+ eprint!("{}", 1);
+}
+
+#[cfg(test)]
+fn foo3() {
+ print!("{}", 1);
+ eprint!("{}", 1);
+}
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
new file mode 100644
index 000000000..d4b1ae84f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/print_macro/print_macro.stderr
@@ -0,0 +1,18 @@
+error: use of `print!`
+ --> $DIR/print_macro.rs:6:5
+ |
+LL | print!("{n}");
+ | ^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::print-stdout` implied by `-D warnings`
+
+error: use of `eprint!`
+ --> $DIR/print_macro.rs:7:5
+ |
+LL | eprint!("{n}");
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::print-stderr` implied by `-D warnings`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/clippy.toml b/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/clippy.toml
index 28774db62..41dbd5068 100644
--- a/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/clippy.toml
@@ -8,4 +8,10 @@ disallowed-methods = [
{ path = "regex::Regex::is_match", reason = "no matching allowed" },
# can use an inline table but omit reason
{ path = "regex::Regex::new" },
+ # local paths
+ "conf_disallowed_methods::local_fn",
+ "conf_disallowed_methods::local_mod::f",
+ "conf_disallowed_methods::Struct::method",
+ "conf_disallowed_methods::Trait::provided_method",
+ "conf_disallowed_methods::Trait::implemented_method",
]
diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs b/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs
index b483f1600..2f3160c83 100644
--- a/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs
+++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs
@@ -1,3 +1,5 @@
+// compile-flags: --crate-name conf_disallowed_methods
+
#![warn(clippy::disallowed_methods)]
extern crate futures;
@@ -6,6 +8,27 @@ extern crate regex;
use futures::stream::{empty, select_all};
use regex::Regex;
+fn local_fn() {}
+
+struct Struct;
+
+impl Struct {
+ fn method(&self) {}
+}
+
+trait Trait {
+ fn provided_method(&self) {}
+ fn implemented_method(&self);
+}
+
+impl Trait for Struct {
+ fn implemented_method(&self) {}
+}
+
+mod local_mod {
+ pub fn f() {}
+}
+
fn main() {
let re = Regex::new(r"ab.*c").unwrap();
re.is_match("abc");
@@ -26,4 +49,11 @@ fn main() {
// resolve ambiguity between `futures::stream::select_all` the module and the function
let same_name_as_module = select_all(vec![empty::<()>()]);
+
+ local_fn();
+ local_mod::f();
+ let s = Struct;
+ s.method();
+ s.provided_method();
+ s.implemented_method();
}
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 6d78c32e1..148d1cae5 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
@@ -1,5 +1,5 @@
error: use of a disallowed method `regex::Regex::new`
- --> $DIR/conf_disallowed_methods.rs:10:14
+ --> $DIR/conf_disallowed_methods.rs:33:14
|
LL | let re = Regex::new(r"ab.*c").unwrap();
| ^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | let re = Regex::new(r"ab.*c").unwrap();
= note: `-D clippy::disallowed-methods` implied by `-D warnings`
error: use of a disallowed method `regex::Regex::is_match`
- --> $DIR/conf_disallowed_methods.rs:11:5
+ --> $DIR/conf_disallowed_methods.rs:34:5
|
LL | re.is_match("abc");
| ^^^^^^^^^^^^^^^^^^
@@ -15,46 +15,76 @@ LL | re.is_match("abc");
= note: no matching allowed (from clippy.toml)
error: use of a disallowed method `std::iter::Iterator::sum`
- --> $DIR/conf_disallowed_methods.rs:14:5
+ --> $DIR/conf_disallowed_methods.rs:37:5
|
LL | a.iter().sum::<i32>();
| ^^^^^^^^^^^^^^^^^^^^^
error: use of a disallowed method `slice::sort_unstable`
- --> $DIR/conf_disallowed_methods.rs:16:5
+ --> $DIR/conf_disallowed_methods.rs:39:5
|
LL | a.sort_unstable();
| ^^^^^^^^^^^^^^^^^
error: use of a disallowed method `f32::clamp`
- --> $DIR/conf_disallowed_methods.rs:18:13
+ --> $DIR/conf_disallowed_methods.rs:41:13
|
LL | let _ = 2.0f32.clamp(3.0f32, 4.0f32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: use of a disallowed method `regex::Regex::new`
- --> $DIR/conf_disallowed_methods.rs:21:61
+ --> $DIR/conf_disallowed_methods.rs:44:61
|
LL | let indirect: fn(&str) -> Result<Regex, regex::Error> = Regex::new;
| ^^^^^^^^^^
error: use of a disallowed method `f32::clamp`
- --> $DIR/conf_disallowed_methods.rs:24:28
+ --> $DIR/conf_disallowed_methods.rs:47:28
|
LL | let in_call = Box::new(f32::clamp);
| ^^^^^^^^^^
error: use of a disallowed method `regex::Regex::new`
- --> $DIR/conf_disallowed_methods.rs:25:53
+ --> $DIR/conf_disallowed_methods.rs:48:53
|
LL | let in_method_call = ["^", "$"].into_iter().map(Regex::new);
| ^^^^^^^^^^
error: use of a disallowed method `futures::stream::select_all`
- --> $DIR/conf_disallowed_methods.rs:28:31
+ --> $DIR/conf_disallowed_methods.rs:51:31
|
LL | let same_name_as_module = select_all(vec![empty::<()>()]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 9 previous errors
+error: use of a disallowed method `conf_disallowed_methods::local_fn`
+ --> $DIR/conf_disallowed_methods.rs:53:5
+ |
+LL | local_fn();
+ | ^^^^^^^^^^
+
+error: use of a disallowed method `conf_disallowed_methods::local_mod::f`
+ --> $DIR/conf_disallowed_methods.rs:54:5
+ |
+LL | local_mod::f();
+ | ^^^^^^^^^^^^^^
+
+error: use of a disallowed method `conf_disallowed_methods::Struct::method`
+ --> $DIR/conf_disallowed_methods.rs:56:5
+ |
+LL | s.method();
+ | ^^^^^^^^^^
+
+error: use of a disallowed method `conf_disallowed_methods::Trait::provided_method`
+ --> $DIR/conf_disallowed_methods.rs:57:5
+ |
+LL | s.provided_method();
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: use of a disallowed method `conf_disallowed_methods::Trait::implemented_method`
+ --> $DIR/conf_disallowed_methods.rs:58:5
+ |
+LL | s.implemented_method();
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 14 previous errors
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 82ee80541..01a5e962c 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
@@ -1,6 +1,8 @@
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of
allow-dbg-in-tests
allow-expect-in-tests
+ allow-mixed-uninlined-format-args
+ allow-print-in-tests
allow-unwrap-in-tests
allowed-scripts
arithmetic-side-effects-allowed
@@ -20,8 +22,10 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie
enforced-import-renames
enum-variant-name-threshold
enum-variant-size-threshold
+ ignore-interior-mutability
large-error-threshold
literal-representation-threshold
+ matches-for-let-else
max-fn-params-bools
max-include-file-size
max-struct-bools
diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs
index 0e82fb20e..bc8e8c1f0 100644
--- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs
+++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs
@@ -66,8 +66,21 @@ fn main() {
}
}
-#[test]
-fn test() {
- let boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
- let _ = boxed_slice.get(1).unwrap();
+#[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]).get(1).unwrap();
+ }
}
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 681b5eaf5..94b5ef663 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
@@ -10,7 +10,7 @@ note: the lint level is defined here
LL | #![deny(clippy::get_unwrap)]
| ^^^^^^^^^^^^^^^^^^
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:35:17
|
LL | let _ = boxed_slice.get(1).unwrap();
@@ -25,7 +25,7 @@ error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more co
LL | let _ = some_slice.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_slice[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:36:17
|
LL | let _ = some_slice.get(0).unwrap();
@@ -39,7 +39,7 @@ error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more conc
LL | let _ = some_vec.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vec[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:37:17
|
LL | let _ = some_vec.get(0).unwrap();
@@ -53,7 +53,7 @@ error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more
LL | let _ = some_vecdeque.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vecdeque[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:38:17
|
LL | let _ = some_vecdeque.get(0).unwrap();
@@ -67,7 +67,7 @@ error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more
LL | let _ = some_hashmap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_hashmap[&1]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:39:17
|
LL | let _ = some_hashmap.get(&1).unwrap();
@@ -81,7 +81,7 @@ error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more
LL | let _ = some_btreemap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_btreemap[&1]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:40:17
|
LL | let _ = some_btreemap.get(&1).unwrap();
@@ -95,7 +95,7 @@ error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more co
LL | let _: u8 = *boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[1]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:44:22
|
LL | let _: u8 = *boxed_slice.get(1).unwrap();
@@ -109,7 +109,7 @@ error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and mor
LL | *boxed_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:49:10
|
LL | *boxed_slice.get_mut(0).unwrap() = 1;
@@ -123,7 +123,7 @@ error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and mor
LL | *some_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_slice[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:50:10
|
LL | *some_slice.get_mut(0).unwrap() = 1;
@@ -137,7 +137,7 @@ error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more
LL | *some_vec.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:51:10
|
LL | *some_vec.get_mut(0).unwrap() = 1;
@@ -151,7 +151,7 @@ error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and
LL | *some_vecdeque.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vecdeque[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:52:10
|
LL | *some_vecdeque.get_mut(0).unwrap() = 1;
@@ -165,7 +165,7 @@ error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more conc
LL | let _ = some_vec.get(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:64:17
|
LL | let _ = some_vec.get(0..1).unwrap().to_vec();
@@ -179,7 +179,7 @@ error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_used.rs:65:17
|
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
@@ -188,10 +188,10 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
- --> $DIR/unwrap_used.rs:72:13
+ --> $DIR/unwrap_used.rs:84:17
|
-LL | let _ = boxed_slice.get(1).unwrap();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&boxed_slice[1]`
+LL | let _ = Box::new([0]).get(1).unwrap();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&Box::new([0])[1]`
error: aborting due to 27 previous errors
diff --git a/src/tools/clippy/tests/ui-toml/vec_box_sized/test.rs b/src/tools/clippy/tests/ui-toml/vec_box_sized/test.rs
index bf04bee16..4c46deb58 100644
--- a/src/tools/clippy/tests/ui-toml/vec_box_sized/test.rs
+++ b/src/tools/clippy/tests/ui-toml/vec_box_sized/test.rs
@@ -7,8 +7,9 @@ struct C {
}
struct Foo(Vec<Box<u8>>);
-struct Bar(Vec<Box<u32>>);
-struct Baz(Vec<Box<(u32, u32)>>);
+struct Bar(Vec<Box<u16>>);
+struct Quux(Vec<Box<u32>>);
+struct Baz(Vec<Box<(u16, u16)>>);
struct BarBaz(Vec<Box<S>>);
struct FooBarBaz(Vec<Box<C>>);
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 cf194de3c..55de68f8e 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
@@ -9,11 +9,11 @@ LL | struct Foo(Vec<Box<u8>>);
error: `Vec<T>` is already on the heap, the boxing is unnecessary
--> $DIR/test.rs:10:12
|
-LL | struct Bar(Vec<Box<u32>>);
- | ^^^^^^^^^^^^^ help: try: `Vec<u32>`
+LL | struct Bar(Vec<Box<u16>>);
+ | ^^^^^^^^^^^^^ help: try: `Vec<u16>`
error: `Vec<T>` is already on the heap, the boxing is unnecessary
- --> $DIR/test.rs:13:18
+ --> $DIR/test.rs:14:18
|
LL | struct FooBarBaz(Vec<Box<C>>);
| ^^^^^^^^^^^ help: try: `Vec<C>`
diff --git a/src/tools/clippy/tests/ui/almost_complete_letter_range.fixed b/src/tools/clippy/tests/ui/almost_complete_letter_range.fixed
index 079b7c000..adcbd4d51 100644
--- a/src/tools/clippy/tests/ui/almost_complete_letter_range.fixed
+++ b/src/tools/clippy/tests/ui/almost_complete_letter_range.fixed
@@ -2,7 +2,6 @@
// edition:2018
// aux-build:macro_rules.rs
-#![feature(custom_inner_attributes)]
#![feature(exclusive_range_pattern)]
#![feature(stmt_expr_attributes)]
#![warn(clippy::almost_complete_letter_range)]
@@ -62,16 +61,16 @@ fn main() {
b!();
}
+#[clippy::msrv = "1.25"]
fn _under_msrv() {
- #![clippy::msrv = "1.25"]
let _ = match 'a' {
'a'...'z' => 1,
_ => 2,
};
}
+#[clippy::msrv = "1.26"]
fn _meets_msrv() {
- #![clippy::msrv = "1.26"]
let _ = 'a'..='z';
let _ = match 'a' {
'a'..='z' => 1,
diff --git a/src/tools/clippy/tests/ui/almost_complete_letter_range.rs b/src/tools/clippy/tests/ui/almost_complete_letter_range.rs
index a66900a97..9979316ec 100644
--- a/src/tools/clippy/tests/ui/almost_complete_letter_range.rs
+++ b/src/tools/clippy/tests/ui/almost_complete_letter_range.rs
@@ -2,7 +2,6 @@
// edition:2018
// aux-build:macro_rules.rs
-#![feature(custom_inner_attributes)]
#![feature(exclusive_range_pattern)]
#![feature(stmt_expr_attributes)]
#![warn(clippy::almost_complete_letter_range)]
@@ -62,16 +61,16 @@ fn main() {
b!();
}
+#[clippy::msrv = "1.25"]
fn _under_msrv() {
- #![clippy::msrv = "1.25"]
let _ = match 'a' {
'a'..'z' => 1,
_ => 2,
};
}
+#[clippy::msrv = "1.26"]
fn _meets_msrv() {
- #![clippy::msrv = "1.26"]
let _ = 'a'..'z';
let _ = match 'a' {
'a'..'z' => 1,
diff --git a/src/tools/clippy/tests/ui/almost_complete_letter_range.stderr b/src/tools/clippy/tests/ui/almost_complete_letter_range.stderr
index 3de44c72c..9abf6d6c5 100644
--- a/src/tools/clippy/tests/ui/almost_complete_letter_range.stderr
+++ b/src/tools/clippy/tests/ui/almost_complete_letter_range.stderr
@@ -1,5 +1,5 @@
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:30:17
+ --> $DIR/almost_complete_letter_range.rs:29:17
|
LL | let _ = ('a') ..'z';
| ^^^^^^--^^^
@@ -9,7 +9,7 @@ LL | let _ = ('a') ..'z';
= note: `-D clippy::almost-complete-letter-range` implied by `-D warnings`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:31:17
+ --> $DIR/almost_complete_letter_range.rs:30:17
|
LL | let _ = 'A' .. ('Z');
| ^^^^--^^^^^^
@@ -17,7 +17,7 @@ LL | let _ = 'A' .. ('Z');
| help: use an inclusive range: `..=`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:37:13
+ --> $DIR/almost_complete_letter_range.rs:36:13
|
LL | let _ = (b'a')..(b'z');
| ^^^^^^--^^^^^^
@@ -25,7 +25,7 @@ LL | let _ = (b'a')..(b'z');
| help: use an inclusive range: `..=`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:38:13
+ --> $DIR/almost_complete_letter_range.rs:37:13
|
LL | let _ = b'A'..b'Z';
| ^^^^--^^^^
@@ -33,7 +33,7 @@ LL | let _ = b'A'..b'Z';
| help: use an inclusive range: `..=`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:43:13
+ --> $DIR/almost_complete_letter_range.rs:42:13
|
LL | let _ = a!()..'z';
| ^^^^--^^^
@@ -41,7 +41,7 @@ LL | let _ = a!()..'z';
| help: use an inclusive range: `..=`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:46:9
+ --> $DIR/almost_complete_letter_range.rs:45:9
|
LL | b'a'..b'z' if true => 1,
| ^^^^--^^^^
@@ -49,7 +49,7 @@ LL | b'a'..b'z' if true => 1,
| help: use an inclusive range: `..=`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:47:9
+ --> $DIR/almost_complete_letter_range.rs:46:9
|
LL | b'A'..b'Z' if true => 2,
| ^^^^--^^^^
@@ -57,7 +57,7 @@ LL | b'A'..b'Z' if true => 2,
| help: use an inclusive range: `..=`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:54:9
+ --> $DIR/almost_complete_letter_range.rs:53:9
|
LL | 'a'..'z' if true => 1,
| ^^^--^^^
@@ -65,7 +65,7 @@ LL | 'a'..'z' if true => 1,
| help: use an inclusive range: `..=`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:55:9
+ --> $DIR/almost_complete_letter_range.rs:54:9
|
LL | 'A'..'Z' if true => 2,
| ^^^--^^^
@@ -73,7 +73,7 @@ LL | 'A'..'Z' if true => 2,
| help: use an inclusive range: `..=`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:23:17
+ --> $DIR/almost_complete_letter_range.rs:22:17
|
LL | let _ = 'a'..'z';
| ^^^--^^^
@@ -86,7 +86,7 @@ LL | b!();
= note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:68:9
+ --> $DIR/almost_complete_letter_range.rs:67:9
|
LL | 'a'..'z' => 1,
| ^^^--^^^
@@ -94,7 +94,7 @@ LL | 'a'..'z' => 1,
| help: use an inclusive range: `...`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:75:13
+ --> $DIR/almost_complete_letter_range.rs:74:13
|
LL | let _ = 'a'..'z';
| ^^^--^^^
@@ -102,7 +102,7 @@ LL | let _ = 'a'..'z';
| help: use an inclusive range: `..=`
error: almost complete ascii letter range
- --> $DIR/almost_complete_letter_range.rs:77:9
+ --> $DIR/almost_complete_letter_range.rs:76:9
|
LL | 'a'..'z' => 1,
| ^^^--^^^
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
index b25e68f13..b5ed8988a 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
@@ -150,8 +150,12 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri
_n = 23 + 85;
// Unary
- _n = -1;
- _n = -(-1);
+ _n = -2147483647;
+ _n = -i32::MAX;
+ _n = -i32::MIN;
+ _n = -&2147483647;
+ _n = -&i32::MAX;
+ _n = -&i32::MIN;
}
pub fn runtime_ops() {
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
index 0f06e22ba..0259a0824 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
@@ -19,331 +19,331 @@ LL | let _ = inferred_string + "";
| ^^^^^^^^^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:161:5
+ --> $DIR/arithmetic_side_effects.rs:165:5
|
LL | _n += 1;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:162:5
+ --> $DIR/arithmetic_side_effects.rs:166:5
|
LL | _n += &1;
| ^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:163:5
+ --> $DIR/arithmetic_side_effects.rs:167:5
|
LL | _n -= 1;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:164:5
+ --> $DIR/arithmetic_side_effects.rs:168:5
|
LL | _n -= &1;
| ^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:165:5
+ --> $DIR/arithmetic_side_effects.rs:169:5
|
LL | _n /= 0;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:166:5
+ --> $DIR/arithmetic_side_effects.rs:170:5
|
LL | _n /= &0;
| ^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:167:5
+ --> $DIR/arithmetic_side_effects.rs:171:5
|
LL | _n %= 0;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:168:5
+ --> $DIR/arithmetic_side_effects.rs:172:5
|
LL | _n %= &0;
| ^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:169:5
+ --> $DIR/arithmetic_side_effects.rs:173:5
|
LL | _n *= 2;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:170:5
+ --> $DIR/arithmetic_side_effects.rs:174:5
|
LL | _n *= &2;
| ^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:173:10
+ --> $DIR/arithmetic_side_effects.rs:177:10
|
LL | _n = _n + 1;
| ^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:174:10
+ --> $DIR/arithmetic_side_effects.rs:178:10
|
LL | _n = _n + &1;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:175:10
+ --> $DIR/arithmetic_side_effects.rs:179:10
|
LL | _n = 1 + _n;
| ^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:176:10
+ --> $DIR/arithmetic_side_effects.rs:180:10
|
LL | _n = &1 + _n;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:177:10
+ --> $DIR/arithmetic_side_effects.rs:181:10
|
LL | _n = _n - 1;
| ^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:178:10
+ --> $DIR/arithmetic_side_effects.rs:182:10
|
LL | _n = _n - &1;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:179:10
+ --> $DIR/arithmetic_side_effects.rs:183:10
|
LL | _n = 1 - _n;
| ^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:180:10
+ --> $DIR/arithmetic_side_effects.rs:184:10
|
LL | _n = &1 - _n;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:181:10
+ --> $DIR/arithmetic_side_effects.rs:185:10
|
LL | _n = _n / 0;
| ^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:182:10
+ --> $DIR/arithmetic_side_effects.rs:186:10
|
LL | _n = _n / &0;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:183:10
+ --> $DIR/arithmetic_side_effects.rs:187:10
|
LL | _n = _n % 0;
| ^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:184:10
+ --> $DIR/arithmetic_side_effects.rs:188:10
|
LL | _n = _n % &0;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:185:10
+ --> $DIR/arithmetic_side_effects.rs:189:10
|
LL | _n = _n * 2;
| ^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:186:10
+ --> $DIR/arithmetic_side_effects.rs:190:10
|
LL | _n = _n * &2;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:187:10
+ --> $DIR/arithmetic_side_effects.rs:191:10
|
LL | _n = 2 * _n;
| ^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:188:10
+ --> $DIR/arithmetic_side_effects.rs:192:10
|
LL | _n = &2 * _n;
| ^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:189:10
+ --> $DIR/arithmetic_side_effects.rs:193:10
|
LL | _n = 23 + &85;
| ^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:190:10
+ --> $DIR/arithmetic_side_effects.rs:194:10
|
LL | _n = &23 + 85;
| ^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:191:10
+ --> $DIR/arithmetic_side_effects.rs:195:10
|
LL | _n = &23 + &85;
| ^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:194:13
+ --> $DIR/arithmetic_side_effects.rs:198:13
|
LL | let _ = Custom + 0;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:195:13
+ --> $DIR/arithmetic_side_effects.rs:199:13
|
LL | let _ = Custom + 1;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:196:13
+ --> $DIR/arithmetic_side_effects.rs:200:13
|
LL | let _ = Custom + 2;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:197:13
+ --> $DIR/arithmetic_side_effects.rs:201:13
|
LL | let _ = Custom + 0.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:198:13
+ --> $DIR/arithmetic_side_effects.rs:202:13
|
LL | let _ = Custom + 1.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:199:13
+ --> $DIR/arithmetic_side_effects.rs:203:13
|
LL | let _ = Custom + 2.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:200:13
+ --> $DIR/arithmetic_side_effects.rs:204:13
|
LL | let _ = Custom - 0;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:201:13
+ --> $DIR/arithmetic_side_effects.rs:205:13
|
LL | let _ = Custom - 1;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:202:13
+ --> $DIR/arithmetic_side_effects.rs:206:13
|
LL | let _ = Custom - 2;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:203:13
+ --> $DIR/arithmetic_side_effects.rs:207:13
|
LL | let _ = Custom - 0.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:204:13
+ --> $DIR/arithmetic_side_effects.rs:208:13
|
LL | let _ = Custom - 1.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:205:13
+ --> $DIR/arithmetic_side_effects.rs:209:13
|
LL | let _ = Custom - 2.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:206:13
+ --> $DIR/arithmetic_side_effects.rs:210:13
|
LL | let _ = Custom / 0;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:207:13
+ --> $DIR/arithmetic_side_effects.rs:211:13
|
LL | let _ = Custom / 1;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:208:13
+ --> $DIR/arithmetic_side_effects.rs:212:13
|
LL | let _ = Custom / 2;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:209:13
+ --> $DIR/arithmetic_side_effects.rs:213:13
|
LL | let _ = Custom / 0.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:210:13
+ --> $DIR/arithmetic_side_effects.rs:214:13
|
LL | let _ = Custom / 1.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:211:13
+ --> $DIR/arithmetic_side_effects.rs:215:13
|
LL | let _ = Custom / 2.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:212:13
+ --> $DIR/arithmetic_side_effects.rs:216:13
|
LL | let _ = Custom * 0;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:213:13
+ --> $DIR/arithmetic_side_effects.rs:217:13
|
LL | let _ = Custom * 1;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:214:13
+ --> $DIR/arithmetic_side_effects.rs:218:13
|
LL | let _ = Custom * 2;
| ^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:215:13
+ --> $DIR/arithmetic_side_effects.rs:219:13
|
LL | let _ = Custom * 0.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:216:13
+ --> $DIR/arithmetic_side_effects.rs:220:13
|
LL | let _ = Custom * 1.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:217:13
+ --> $DIR/arithmetic_side_effects.rs:221:13
|
LL | let _ = Custom * 2.0;
| ^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:220:10
+ --> $DIR/arithmetic_side_effects.rs:224:10
|
LL | _n = -_n;
| ^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> $DIR/arithmetic_side_effects.rs:221:10
+ --> $DIR/arithmetic_side_effects.rs:225:10
|
LL | _n = -&_n;
| ^^^^
diff --git a/src/tools/clippy/tests/ui/async_yields_async.stderr b/src/tools/clippy/tests/ui/async_yields_async.stderr
index b0c4215e7..92ba35929 100644
--- a/src/tools/clippy/tests/ui/async_yields_async.stderr
+++ b/src/tools/clippy/tests/ui/async_yields_async.stderr
@@ -2,14 +2,14 @@ error: an async construct yields a type which is itself awaitable
--> $DIR/async_yields_async.rs:39:9
|
LL | let _h = async {
- | ____________________-
-LL | | async {
- | |_________^
+ | _____________________-
+LL | | async {
+ | | _________^
LL | || 3
LL | || }
| ||_________^ awaitable value not awaited
-LL | | };
- | |_____- outer async construct
+LL | | };
+ | |______- outer async construct
|
= note: `-D clippy::async-yields-async` implied by `-D warnings`
help: consider awaiting this value
@@ -36,14 +36,14 @@ error: an async construct yields a type which is itself awaitable
--> $DIR/async_yields_async.rs:50:9
|
LL | let _j = async || {
- | _______________________-
-LL | | async {
- | |_________^
+ | ________________________-
+LL | | async {
+ | | _________^
LL | || 3
LL | || }
| ||_________^ awaitable value not awaited
-LL | | };
- | |_____- outer async construct
+LL | | };
+ | |______- outer async construct
|
help: consider awaiting this value
|
diff --git a/src/tools/clippy/tests/ui/author/blocks.stdout b/src/tools/clippy/tests/ui/author/blocks.stdout
index 9de0550d8..c6acf24c2 100644
--- a/src/tools/clippy/tests/ui/author/blocks.stdout
+++ b/src/tools/clippy/tests/ui/author/blocks.stdout
@@ -45,7 +45,7 @@ if let ExprKind::Closure(CaptureBy::Value, fn_decl, body_id, _, None) = expr.kin
&& expr1 = &cx.tcx.hir().body(body_id).value
&& let ExprKind::Call(func, args) = expr1.kind
&& let ExprKind::Path(ref qpath) = func.kind
- && matches!(qpath, QPath::LangItem(LangItem::FromGenerator, _))
+ && matches!(qpath, QPath::LangItem(LangItem::IdentityFuture, _))
&& args.len() == 1
&& let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = args[0].kind
&& let FnRetTy::DefaultReturn(_) = fn_decl1.output
diff --git a/src/tools/clippy/tests/ui/auxiliary/doc_unsafe_macros.rs b/src/tools/clippy/tests/ui/auxiliary/doc_unsafe_macros.rs
index 869672d1e..3d917e3dc 100644
--- a/src/tools/clippy/tests/ui/auxiliary/doc_unsafe_macros.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/doc_unsafe_macros.rs
@@ -6,3 +6,11 @@ macro_rules! undocd_unsafe {
}
};
}
+#[macro_export]
+macro_rules! undocd_safe {
+ () => {
+ pub fn vey_oy() {
+ unimplemented!();
+ }
+ };
+}
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 d055f1752..554745368 100644
--- a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs
+++ b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs
@@ -1,3 +1,5 @@
+// compile-flags: -W clippy::restriction
+
#![warn(clippy::blanket_clippy_restriction_lints)]
//! Test that the whole restriction group is not enabled
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 e83eb4d60..2bf89ab69 100644
--- a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr
+++ b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr
@@ -1,27 +1,32 @@
-error: restriction lints are not meant to be all enabled
- --> $DIR/blanket_clippy_restriction_lints.rs:4:9
+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: try enabling only the lints you really need
- = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings`
+ = help: enable the restriction lints you need individually
-error: restriction lints are not meant to be all enabled
- --> $DIR/blanket_clippy_restriction_lints.rs:5:9
+error: `clippy::restriction` is not meant to be enabled as a group
+ --> $DIR/blanket_clippy_restriction_lints.rs:7:9
|
LL | #![deny(clippy::restriction)]
| ^^^^^^^^^^^^^^^^^^^
|
- = help: try enabling only the lints you really need
+ = help: enable the restriction lints you need individually
-error: restriction lints are not meant to be all enabled
- --> $DIR/blanket_clippy_restriction_lints.rs:6:11
+error: `clippy::restriction` is not meant to be enabled as a group
+ --> $DIR/blanket_clippy_restriction_lints.rs:8:11
|
LL | #![forbid(clippy::restriction)]
| ^^^^^^^^^^^^^^^^^^^
|
- = help: try enabling only the lints you really need
+ = help: enable the restriction lints you need individually
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
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 2c8339cdd..37d3e3286 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,6 @@
// run-rustfix
+#![feature(let_chains)]
#![warn(clippy::bool_to_int_with_if)]
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
@@ -76,6 +77,8 @@ fn main() {
123
};
+ pub const SHOULD_NOT_LINT: usize = if true { 1 } else { 0 };
+
some_fn(a);
}
@@ -89,3 +92,22 @@ fn side_effect() {}
fn cond(a: bool, b: bool) -> bool {
a || b
}
+
+enum Enum {
+ A,
+ B,
+}
+
+fn if_let(a: Enum, b: Enum) {
+ if let Enum::A = a {
+ 1
+ } else {
+ 0
+ };
+
+ if let Enum::A = a && let Enum::B = b {
+ 1
+ } else {
+ 0
+ };
+}
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 5d9496f01..ebdf86fd1 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,6 @@
// run-rustfix
+#![feature(let_chains)]
#![warn(clippy::bool_to_int_with_if)]
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
@@ -108,6 +109,8 @@ fn main() {
123
};
+ pub const SHOULD_NOT_LINT: usize = if true { 1 } else { 0 };
+
some_fn(a);
}
@@ -121,3 +124,22 @@ fn side_effect() {}
fn cond(a: bool, b: bool) -> bool {
a || b
}
+
+enum Enum {
+ A,
+ B,
+}
+
+fn if_let(a: Enum, b: Enum) {
+ if let Enum::A = a {
+ 1
+ } else {
+ 0
+ };
+
+ if let Enum::A = a && let Enum::B = b {
+ 1
+ } else {
+ 0
+ };
+}
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 4cb5531be..5cfb75cc0 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:15:5
+ --> $DIR/bool_to_int_with_if.rs:16:5
|
LL | / if a {
LL | | 1
@@ -12,7 +12,7 @@ LL | | };
= note: `-D clippy::bool-to-int-with-if` implied by `-D warnings`
error: boolean to int conversion using if
- --> $DIR/bool_to_int_with_if.rs:20:5
+ --> $DIR/bool_to_int_with_if.rs:21:5
|
LL | / if a {
LL | | 0
@@ -24,7 +24,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:25:5
+ --> $DIR/bool_to_int_with_if.rs:26:5
|
LL | / if !a {
LL | | 1
@@ -36,7 +36,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:30:5
+ --> $DIR/bool_to_int_with_if.rs:31:5
|
LL | / if a || b {
LL | | 1
@@ -48,7 +48,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:35:5
+ --> $DIR/bool_to_int_with_if.rs:36:5
|
LL | / if cond(a, b) {
LL | | 1
@@ -60,7 +60,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:40:5
+ --> $DIR/bool_to_int_with_if.rs:41:5
|
LL | / if x + y < 4 {
LL | | 1
@@ -72,7 +72,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:49:12
+ --> $DIR/bool_to_int_with_if.rs:50:12
|
LL | } else if b {
| ____________^
@@ -85,7 +85,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:58:12
+ --> $DIR/bool_to_int_with_if.rs:59:12
|
LL | } else if b {
| ____________^
@@ -98,7 +98,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:116:5
+ --> $DIR/bool_to_int_with_if.rs:119:5
|
LL | if a { 1 } else { 0 }
| ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)`
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs
index eefeb1dec..7c5786424 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs
@@ -42,7 +42,7 @@ impl<T> StaticRef<T> {
impl<T> std::ops::Deref for StaticRef<T> {
type Target = T;
- fn deref(&self) -> &'static T {
+ fn deref(&self) -> &T {
unsafe { &*self.ptr }
}
}
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 e6bf944c7..8676b562b 100644
--- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::cast_abs_to_unsigned)]
#![allow(clippy::uninlined_format_args, unused)]
@@ -33,16 +32,14 @@ fn main() {
let _ = (x as i64 - y as i64).unsigned_abs() as u32;
}
+#[clippy::msrv = "1.50"]
fn msrv_1_50() {
- #![clippy::msrv = "1.50"]
-
let x: i32 = 10;
assert_eq!(10u32, x.abs() as u32);
}
+#[clippy::msrv = "1.51"]
fn msrv_1_51() {
- #![clippy::msrv = "1.51"]
-
let x: i32 = 10;
assert_eq!(10u32, x.unsigned_abs());
}
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 c87320b52..5775af874 100644
--- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::cast_abs_to_unsigned)]
#![allow(clippy::uninlined_format_args, unused)]
@@ -33,16 +32,14 @@ fn main() {
let _ = (x as i64 - y as i64).abs() as u32;
}
+#[clippy::msrv = "1.50"]
fn msrv_1_50() {
- #![clippy::msrv = "1.50"]
-
let x: i32 = 10;
assert_eq!(10u32, x.abs() as u32);
}
+#[clippy::msrv = "1.51"]
fn msrv_1_51() {
- #![clippy::msrv = "1.51"]
-
let x: i32 = 10;
assert_eq!(10u32, x.abs() as u32);
}
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 1b39c554b..4668554f4 100644
--- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
@@ -1,5 +1,5 @@
error: casting the result of `i32::abs()` to u32
- --> $DIR/cast_abs_to_unsigned.rs:9:18
+ --> $DIR/cast_abs_to_unsigned.rs:8:18
|
LL | let y: u32 = x.abs() as u32;
| ^^^^^^^^^^^^^^ help: replace with: `x.unsigned_abs()`
@@ -7,103 +7,103 @@ LL | let y: u32 = x.abs() as u32;
= note: `-D clippy::cast-abs-to-unsigned` implied by `-D warnings`
error: casting the result of `i32::abs()` to usize
- --> $DIR/cast_abs_to_unsigned.rs:13:20
+ --> $DIR/cast_abs_to_unsigned.rs:12: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:14:20
+ --> $DIR/cast_abs_to_unsigned.rs:13: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:15:13
+ --> $DIR/cast_abs_to_unsigned.rs:14: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:18:13
+ --> $DIR/cast_abs_to_unsigned.rs:17: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:19:13
+ --> $DIR/cast_abs_to_unsigned.rs:18: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:20:13
+ --> $DIR/cast_abs_to_unsigned.rs:19: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:21:13
+ --> $DIR/cast_abs_to_unsigned.rs:20: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:22:13
+ --> $DIR/cast_abs_to_unsigned.rs:21: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:23:13
+ --> $DIR/cast_abs_to_unsigned.rs:22: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:26:13
+ --> $DIR/cast_abs_to_unsigned.rs:25: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:27:13
+ --> $DIR/cast_abs_to_unsigned.rs:26: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:28:13
+ --> $DIR/cast_abs_to_unsigned.rs:27: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:29:13
+ --> $DIR/cast_abs_to_unsigned.rs:28: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:30:13
+ --> $DIR/cast_abs_to_unsigned.rs:29: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:31:13
+ --> $DIR/cast_abs_to_unsigned.rs:30: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:33:13
+ --> $DIR/cast_abs_to_unsigned.rs:32: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:47:23
+ --> $DIR/cast_abs_to_unsigned.rs:44:23
|
LL | assert_eq!(10u32, x.abs() as u32);
| ^^^^^^^^^^^^^^ help: replace with: `x.unsigned_abs()`
diff --git a/src/tools/clippy/tests/ui/cast_lossless_bool.fixed b/src/tools/clippy/tests/ui/cast_lossless_bool.fixed
index af13b755e..13b3cf838 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_bool.fixed
+++ b/src/tools/clippy/tests/ui/cast_lossless_bool.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(dead_code)]
#![warn(clippy::cast_lossless)]
@@ -42,14 +41,12 @@ mod cast_lossless_in_impl {
}
}
+#[clippy::msrv = "1.27"]
fn msrv_1_27() {
- #![clippy::msrv = "1.27"]
-
let _ = true as u8;
}
+#[clippy::msrv = "1.28"]
fn msrv_1_28() {
- #![clippy::msrv = "1.28"]
-
let _ = u8::from(true);
}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_bool.rs b/src/tools/clippy/tests/ui/cast_lossless_bool.rs
index 3b06af899..3eed21355 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_bool.rs
+++ b/src/tools/clippy/tests/ui/cast_lossless_bool.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(dead_code)]
#![warn(clippy::cast_lossless)]
@@ -42,14 +41,12 @@ mod cast_lossless_in_impl {
}
}
+#[clippy::msrv = "1.27"]
fn msrv_1_27() {
- #![clippy::msrv = "1.27"]
-
let _ = true as u8;
}
+#[clippy::msrv = "1.28"]
fn msrv_1_28() {
- #![clippy::msrv = "1.28"]
-
let _ = true as u8;
}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_bool.stderr b/src/tools/clippy/tests/ui/cast_lossless_bool.stderr
index 768b033d1..ce240b70f 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_bool.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_bool.stderr
@@ -1,5 +1,5 @@
error: casting `bool` to `u8` is more cleanly stated with `u8::from(_)`
- --> $DIR/cast_lossless_bool.rs:9:13
+ --> $DIR/cast_lossless_bool.rs:8:13
|
LL | let _ = true as u8;
| ^^^^^^^^^^ help: try: `u8::from(true)`
@@ -7,79 +7,79 @@ LL | let _ = true as u8;
= note: `-D clippy::cast-lossless` implied by `-D warnings`
error: casting `bool` to `u16` is more cleanly stated with `u16::from(_)`
- --> $DIR/cast_lossless_bool.rs:10:13
+ --> $DIR/cast_lossless_bool.rs:9: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:11:13
+ --> $DIR/cast_lossless_bool.rs:10: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:12:13
+ --> $DIR/cast_lossless_bool.rs:11: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:13:13
+ --> $DIR/cast_lossless_bool.rs:12: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:14:13
+ --> $DIR/cast_lossless_bool.rs:13: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:16:13
+ --> $DIR/cast_lossless_bool.rs:15: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:17:13
+ --> $DIR/cast_lossless_bool.rs:16: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:18:13
+ --> $DIR/cast_lossless_bool.rs:17: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:19:13
+ --> $DIR/cast_lossless_bool.rs:18: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:20:13
+ --> $DIR/cast_lossless_bool.rs:19: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:21:13
+ --> $DIR/cast_lossless_bool.rs:20: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:24:13
+ --> $DIR/cast_lossless_bool.rs:23: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:54:13
+ --> $DIR/cast_lossless_bool.rs:51:13
|
LL | let _ = true as u8;
| ^^^^^^^^^^ help: try: `u8::from(true)`
diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed
index 8a5645b22..b970b1209 100644
--- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed
+++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed
@@ -1,5 +1,5 @@
// run-rustfix
-#![feature(stmt_expr_attributes, custom_inner_attributes)]
+#![feature(stmt_expr_attributes)]
#![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]
#![warn(clippy::deprecated_cfg_attr)]
@@ -30,16 +30,14 @@ mod foo {
pub fn f() {}
}
+#[clippy::msrv = "1.29"]
fn msrv_1_29() {
- #![clippy::msrv = "1.29"]
-
#[cfg_attr(rustfmt, rustfmt::skip)]
1+29;
}
+#[clippy::msrv = "1.30"]
fn msrv_1_30() {
- #![clippy::msrv = "1.30"]
-
#[rustfmt::skip]
1+30;
}
diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs
index 2fb140efa..0a8e6a89d 100644
--- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs
+++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs
@@ -1,5 +1,5 @@
// run-rustfix
-#![feature(stmt_expr_attributes, custom_inner_attributes)]
+#![feature(stmt_expr_attributes)]
#![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]
#![warn(clippy::deprecated_cfg_attr)]
@@ -30,16 +30,14 @@ mod foo {
pub fn f() {}
}
+#[clippy::msrv = "1.29"]
fn msrv_1_29() {
- #![clippy::msrv = "1.29"]
-
#[cfg_attr(rustfmt, rustfmt::skip)]
1+29;
}
+#[clippy::msrv = "1.30"]
fn msrv_1_30() {
- #![clippy::msrv = "1.30"]
-
#[cfg_attr(rustfmt, rustfmt::skip)]
1+30;
}
diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.stderr b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.stderr
index 08df7b2b3..524a2bf72 100644
--- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.stderr
+++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.stderr
@@ -13,7 +13,7 @@ LL | #[cfg_attr(rustfmt, rustfmt_skip)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `#[rustfmt::skip]`
error: `cfg_attr` is deprecated for rustfmt and got replaced by tool attributes
- --> $DIR/cfg_attr_rustfmt.rs:43:5
+ --> $DIR/cfg_attr_rustfmt.rs:41:5
|
LL | #[cfg_attr(rustfmt, rustfmt::skip)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `#[rustfmt::skip]`
diff --git a/src/tools/clippy/tests/ui/checked_conversions.fixed b/src/tools/clippy/tests/ui/checked_conversions.fixed
index f936957cb..e279ba314 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.fixed
+++ b/src/tools/clippy/tests/ui/checked_conversions.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(
clippy::cast_lossless,
unused,
@@ -78,16 +77,14 @@ pub const fn issue_8898(i: u32) -> bool {
i <= i32::MAX as u32
}
+#[clippy::msrv = "1.33"]
fn msrv_1_33() {
- #![clippy::msrv = "1.33"]
-
let value: i64 = 33;
let _ = value <= (u32::MAX as i64) && value >= 0;
}
+#[clippy::msrv = "1.34"]
fn msrv_1_34() {
- #![clippy::msrv = "1.34"]
-
let value: i64 = 34;
let _ = u32::try_from(value).is_ok();
}
diff --git a/src/tools/clippy/tests/ui/checked_conversions.rs b/src/tools/clippy/tests/ui/checked_conversions.rs
index 77aec713f..9d7a40995 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.rs
+++ b/src/tools/clippy/tests/ui/checked_conversions.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(
clippy::cast_lossless,
unused,
@@ -78,16 +77,14 @@ pub const fn issue_8898(i: u32) -> bool {
i <= i32::MAX as u32
}
+#[clippy::msrv = "1.33"]
fn msrv_1_33() {
- #![clippy::msrv = "1.33"]
-
let value: i64 = 33;
let _ = value <= (u32::MAX as i64) && value >= 0;
}
+#[clippy::msrv = "1.34"]
fn msrv_1_34() {
- #![clippy::msrv = "1.34"]
-
let value: i64 = 34;
let _ = value <= (u32::MAX as i64) && value >= 0;
}
diff --git a/src/tools/clippy/tests/ui/checked_conversions.stderr b/src/tools/clippy/tests/ui/checked_conversions.stderr
index b2bf7af8d..273ead73b 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.stderr
+++ b/src/tools/clippy/tests/ui/checked_conversions.stderr
@@ -1,5 +1,5 @@
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:17:13
+ --> $DIR/checked_conversions.rs:16:13
|
LL | let _ = value <= (u32::max_value() as i64) && value >= 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
@@ -7,97 +7,97 @@ LL | let _ = value <= (u32::max_value() as i64) && value >= 0;
= note: `-D clippy::checked-conversions` implied by `-D warnings`
error: checked cast can be simplified
- --> $DIR/checked_conversions.rs:18:13
+ --> $DIR/checked_conversions.rs:17: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:22:13
+ --> $DIR/checked_conversions.rs:21: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:23:13
+ --> $DIR/checked_conversions.rs:22: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:27:13
+ --> $DIR/checked_conversions.rs:26: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:28:13
+ --> $DIR/checked_conversions.rs:27: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:34:13
+ --> $DIR/checked_conversions.rs:33: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:35:13
+ --> $DIR/checked_conversions.rs:34: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:39:13
+ --> $DIR/checked_conversions.rs:38: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:40:13
+ --> $DIR/checked_conversions.rs:39: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:46:13
+ --> $DIR/checked_conversions.rs:45: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:47:13
+ --> $DIR/checked_conversions.rs:46: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:51:13
+ --> $DIR/checked_conversions.rs:50: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:52:13
+ --> $DIR/checked_conversions.rs:51: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:56:13
+ --> $DIR/checked_conversions.rs:55: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:57:13
+ --> $DIR/checked_conversions.rs:56: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:92:13
+ --> $DIR/checked_conversions.rs:89: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/cloned_instead_of_copied.fixed b/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed
index 42ed232d1..ecbfc1fee 100644
--- a/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed
+++ b/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::cloned_instead_of_copied)]
#![allow(unused)]
@@ -17,23 +16,20 @@ fn main() {
let _ = Some(&String::new()).cloned();
}
+#[clippy::msrv = "1.34"]
fn msrv_1_34() {
- #![clippy::msrv = "1.34"]
-
let _ = [1].iter().cloned();
let _ = Some(&1).cloned();
}
+#[clippy::msrv = "1.35"]
fn msrv_1_35() {
- #![clippy::msrv = "1.35"]
-
let _ = [1].iter().cloned();
let _ = Some(&1).copied(); // Option::copied needs 1.35
}
+#[clippy::msrv = "1.36"]
fn msrv_1_36() {
- #![clippy::msrv = "1.36"]
-
let _ = [1].iter().copied(); // Iterator::copied needs 1.36
let _ = Some(&1).copied();
}
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 471bd9654..163dc3ddd 100644
--- a/src/tools/clippy/tests/ui/cloned_instead_of_copied.rs
+++ b/src/tools/clippy/tests/ui/cloned_instead_of_copied.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::cloned_instead_of_copied)]
#![allow(unused)]
@@ -17,23 +16,20 @@ fn main() {
let _ = Some(&String::new()).cloned();
}
+#[clippy::msrv = "1.34"]
fn msrv_1_34() {
- #![clippy::msrv = "1.34"]
-
let _ = [1].iter().cloned();
let _ = Some(&1).cloned();
}
+#[clippy::msrv = "1.35"]
fn msrv_1_35() {
- #![clippy::msrv = "1.35"]
-
let _ = [1].iter().cloned();
let _ = Some(&1).cloned(); // Option::copied needs 1.35
}
+#[clippy::msrv = "1.36"]
fn msrv_1_36() {
- #![clippy::msrv = "1.36"]
-
let _ = [1].iter().cloned(); // Iterator::copied needs 1.36
let _ = Some(&1).cloned();
}
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 914c9a91e..e0361acd9 100644
--- a/src/tools/clippy/tests/ui/cloned_instead_of_copied.stderr
+++ b/src/tools/clippy/tests/ui/cloned_instead_of_copied.stderr
@@ -1,5 +1,5 @@
error: used `cloned` where `copied` could be used instead
- --> $DIR/cloned_instead_of_copied.rs:9:24
+ --> $DIR/cloned_instead_of_copied.rs:8:24
|
LL | let _ = [1].iter().cloned();
| ^^^^^^ help: try: `copied`
@@ -7,43 +7,43 @@ LL | let _ = [1].iter().cloned();
= note: `-D clippy::cloned-instead-of-copied` implied by `-D warnings`
error: used `cloned` where `copied` could be used instead
- --> $DIR/cloned_instead_of_copied.rs:10:31
+ --> $DIR/cloned_instead_of_copied.rs:9: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:10: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:11: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:12: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:31:22
+ --> $DIR/cloned_instead_of_copied.rs:28: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:37:24
+ --> $DIR/cloned_instead_of_copied.rs:33: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:38:22
+ --> $DIR/cloned_instead_of_copied.rs:34:22
|
LL | let _ = Some(&1).cloned();
| ^^^^^^ help: try: `copied`
diff --git a/src/tools/clippy/tests/ui/cognitive_complexity.rs b/src/tools/clippy/tests/ui/cognitive_complexity.rs
index 912e6788a..07bdaff00 100644
--- a/src/tools/clippy/tests/ui/cognitive_complexity.rs
+++ b/src/tools/clippy/tests/ui/cognitive_complexity.rs
@@ -393,3 +393,19 @@ impl Moo {
}
}
}
+
+#[clippy::cognitive_complexity = "1"]
+mod issue9300 {
+ async fn a() {
+ let a = 0;
+ if a == 0 {}
+ }
+
+ pub struct S;
+ impl S {
+ pub async fn async_method() {
+ 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 d7f2f24e5..5824631fa 100644
--- a/src/tools/clippy/tests/ui/cognitive_complexity.stderr
+++ b/src/tools/clippy/tests/ui/cognitive_complexity.stderr
@@ -135,5 +135,21 @@ LL | fn moo(&self) {
|
= help: you could split it up into multiple smaller functions
-error: aborting due to 17 previous errors
+error: the function has a cognitive complexity of (2/1)
+ --> $DIR/cognitive_complexity.rs:399:14
+ |
+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
+ |
+LL | pub async fn async_method() {
+ | ^^^^^^^^^^^^
+ |
+ = help: you could split it up into multiple smaller functions
+
+error: aborting due to 19 previous errors
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2774.stderr b/src/tools/clippy/tests/ui/crashes/ice-2774.stderr
index 0c2d48f93..1f26c7f4d 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2774.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-2774.stderr
@@ -1,4 +1,4 @@
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+error: the following explicit lifetimes could be elided: 'a
--> $DIR/ice-2774.rs:15:1
|
LL | pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) {
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
index 878897c41..4506d1550 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
@@ -23,6 +23,11 @@ error[E0308]: mismatched types
|
LL | Some(reference) = cache.data.get(key) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
+ |
+help: consider adding `let`
+ |
+LL | let Some(reference) = cache.data.get(key) {
+ | +++
error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/crashes/ice-9746.rs b/src/tools/clippy/tests/ui/crashes/ice-9746.rs
new file mode 100644
index 000000000..fbd373c70
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-9746.rs
@@ -0,0 +1,15 @@
+//! <https://github.com/rust-lang/rust-clippy/issues/9746#issuecomment-1297132880>
+
+trait Trait {}
+
+struct Struct<'a> {
+ _inner: &'a Struct<'a>,
+}
+
+impl Trait for Struct<'_> {}
+
+fn example<'a>(s: &'a Struct) -> Box<Box<dyn Trait + 'a>> {
+ Box::new(Box::new(Struct { _inner: s }))
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
index d68bbe788..875d5ab4f 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
+++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
@@ -1,4 +1,4 @@
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes_impl_trait.rs:15:5
|
LL | fn baz<'a>(&'a self) -> impl Foo + 'a {
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs b/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs
index 4a5c597dd..e1c9fe30a 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs
+++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs
@@ -1,6 +1,5 @@
// compile-flags: -Clink-arg=-nostartfiles
// ignore-macos
-// ignore-windows
#![feature(lang_items, start, libc)]
#![no_std]
diff --git a/src/tools/clippy/tests/ui/doc_errors.stderr b/src/tools/clippy/tests/ui/doc_errors.stderr
index c7b616e28..d74f2dbfe 100644
--- a/src/tools/clippy/tests/ui/doc_errors.stderr
+++ b/src/tools/clippy/tests/ui/doc_errors.stderr
@@ -1,52 +1,40 @@
error: docs for function returning `Result` missing `# Errors` section
--> $DIR/doc_errors.rs:7:1
|
-LL | / pub fn pub_fn_missing_errors_header() -> Result<(), ()> {
-LL | | unimplemented!();
-LL | | }
- | |_^
+LL | pub fn pub_fn_missing_errors_header() -> Result<(), ()> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::missing-errors-doc` implied by `-D warnings`
error: docs for function returning `Result` missing `# Errors` section
--> $DIR/doc_errors.rs:11:1
|
-LL | / pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> {
-LL | | unimplemented!();
-LL | | }
- | |_^
+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
|
-LL | / pub fn pub_fn_returning_io_result() -> io::Result<()> {
-LL | | unimplemented!();
-LL | | }
- | |_^
+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
|
-LL | / pub async fn async_pub_fn_returning_io_result() -> io::Result<()> {
-LL | | unimplemented!();
-LL | | }
- | |_^
+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
|
-LL | / pub fn pub_method_missing_errors_header() -> Result<(), ()> {
-LL | | unimplemented!();
-LL | | }
- | |_____^
+LL | pub fn pub_method_missing_errors_header() -> Result<(), ()> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: docs for function returning `Result` missing `# Errors` section
--> $DIR/doc_errors.rs:56:5
|
-LL | / pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> {
-LL | | unimplemented!();
-LL | | }
- | |_____^
+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
diff --git a/src/tools/clippy/tests/ui/doc_unsafe.stderr b/src/tools/clippy/tests/ui/doc_unsafe.stderr
index 904b88eae..a86e19137 100644
--- a/src/tools/clippy/tests/ui/doc_unsafe.stderr
+++ b/src/tools/clippy/tests/ui/doc_unsafe.stderr
@@ -1,20 +1,16 @@
error: unsafe function's docs miss `# Safety` section
--> $DIR/doc_unsafe.rs:9:1
|
-LL | / pub unsafe fn destroy_the_planet() {
-LL | | unimplemented!();
-LL | | }
- | |_^
+LL | pub unsafe fn destroy_the_planet() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::missing-safety-doc` implied by `-D warnings`
error: unsafe function's docs miss `# Safety` section
--> $DIR/doc_unsafe.rs:32:5
|
-LL | / pub unsafe fn republished() {
-LL | | unimplemented!();
-LL | | }
- | |_____^
+LL | pub unsafe fn republished() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsafe function's docs miss `# Safety` section
--> $DIR/doc_unsafe.rs:40:5
@@ -25,29 +21,23 @@ LL | unsafe fn woefully_underdocumented(self);
error: docs for unsafe trait missing `# Safety` section
--> $DIR/doc_unsafe.rs:46:1
|
-LL | / pub unsafe trait UnsafeTrait {
-LL | | fn method();
-LL | | }
- | |_^
+LL | pub unsafe trait UnsafeTrait {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsafe function's docs miss `# Safety` section
--> $DIR/doc_unsafe.rs:76:5
|
-LL | / pub unsafe fn more_undocumented_unsafe() -> Self {
-LL | | unimplemented!();
-LL | | }
- | |_____^
+LL | pub unsafe fn more_undocumented_unsafe() -> Self {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsafe function's docs miss `# Safety` section
--> $DIR/doc_unsafe.rs:92:9
|
-LL | / pub unsafe fn whee() {
-LL | | unimplemented!()
-LL | | }
- | |_________^
+LL | pub unsafe fn whee() {
+ | ^^^^^^^^^^^^^^^^^^^^
...
-LL | very_unsafe!();
- | -------------- in this macro invocation
+LL | very_unsafe!();
+ | -------------- in this macro invocation
|
= note: this error originates in the macro `very_unsafe` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/src/tools/clippy/tests/ui/eq_op.rs b/src/tools/clippy/tests/ui/eq_op.rs
index 422f94865..e73795502 100644
--- a/src/tools/clippy/tests/ui/eq_op.rs
+++ b/src/tools/clippy/tests/ui/eq_op.rs
@@ -2,6 +2,7 @@
#![warn(clippy::eq_op)]
#![allow(clippy::double_parens, clippy::identity_op, clippy::nonminimal_bool)]
+#![allow(clippy::suspicious_xor_used_as_pow)]
fn main() {
// simple values and comparisons
diff --git a/src/tools/clippy/tests/ui/eq_op.stderr b/src/tools/clippy/tests/ui/eq_op.stderr
index 313ceed2b..d365ab27e 100644
--- a/src/tools/clippy/tests/ui/eq_op.stderr
+++ b/src/tools/clippy/tests/ui/eq_op.stderr
@@ -1,5 +1,5 @@
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:8:13
+ --> $DIR/eq_op.rs:9:13
|
LL | let _ = 1 == 1;
| ^^^^^^
@@ -7,163 +7,163 @@ LL | let _ = 1 == 1;
= note: `-D clippy::eq-op` implied by `-D warnings`
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:9:13
+ --> $DIR/eq_op.rs:10:13
|
LL | let _ = "no" == "no";
| ^^^^^^^^^^^^
error: equal expressions as operands to `!=`
- --> $DIR/eq_op.rs:11:13
+ --> $DIR/eq_op.rs:12:13
|
LL | let _ = false != false;
| ^^^^^^^^^^^^^^
error: equal expressions as operands to `<`
- --> $DIR/eq_op.rs:12:13
+ --> $DIR/eq_op.rs:13:13
|
LL | let _ = 1.5 < 1.5;
| ^^^^^^^^^
error: equal expressions as operands to `>=`
- --> $DIR/eq_op.rs:13:13
+ --> $DIR/eq_op.rs:14:13
|
LL | let _ = 1u64 >= 1u64;
| ^^^^^^^^^^^^
error: equal expressions as operands to `&`
- --> $DIR/eq_op.rs:16:13
+ --> $DIR/eq_op.rs:17:13
|
LL | let _ = (1u32 as u64) & (1u32 as u64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `^`
- --> $DIR/eq_op.rs:19:17
+ --> $DIR/eq_op.rs:20:17
|
LL | let _ = 1 ^ ((((((1))))));
| ^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `<`
- --> $DIR/eq_op.rs:23:13
+ --> $DIR/eq_op.rs:24:13
|
LL | let _ = (-(2) < -(2));
| ^^^^^^^^^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:24:13
+ --> $DIR/eq_op.rs:25:13
|
LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&`
- --> $DIR/eq_op.rs:24:14
+ --> $DIR/eq_op.rs:25:14
|
LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
| ^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&`
- --> $DIR/eq_op.rs:24:35
+ --> $DIR/eq_op.rs:25:35
|
LL | let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));
| ^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:25:13
+ --> $DIR/eq_op.rs:26:13
|
LL | let _ = (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `!=`
- --> $DIR/eq_op.rs:28:13
+ --> $DIR/eq_op.rs:29:13
|
LL | let _ = ([1] != [1]);
| ^^^^^^^^^^^^
error: equal expressions as operands to `!=`
- --> $DIR/eq_op.rs:29:13
+ --> $DIR/eq_op.rs:30:13
|
LL | let _ = ((1, 2) != (1, 2));
| ^^^^^^^^^^^^^^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:33:13
+ --> $DIR/eq_op.rs:34:13
|
LL | let _ = 1 + 1 == 2;
| ^^^^^^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:34:13
+ --> $DIR/eq_op.rs:35:13
|
LL | let _ = 1 - 1 == 0;
| ^^^^^^^^^^
error: equal expressions as operands to `-`
- --> $DIR/eq_op.rs:34:13
+ --> $DIR/eq_op.rs:35:13
|
LL | let _ = 1 - 1 == 0;
| ^^^^^
error: equal expressions as operands to `-`
- --> $DIR/eq_op.rs:36:13
+ --> $DIR/eq_op.rs:37:13
|
LL | let _ = 1 - 1;
| ^^^^^
error: equal expressions as operands to `/`
- --> $DIR/eq_op.rs:37:13
+ --> $DIR/eq_op.rs:38:13
|
LL | let _ = 1 / 1;
| ^^^^^
error: equal expressions as operands to `&&`
- --> $DIR/eq_op.rs:38:13
+ --> $DIR/eq_op.rs:39:13
|
LL | let _ = true && true;
| ^^^^^^^^^^^^
error: equal expressions as operands to `||`
- --> $DIR/eq_op.rs:40:13
+ --> $DIR/eq_op.rs:41:13
|
LL | let _ = true || true;
| ^^^^^^^^^^^^
error: equal expressions as operands to `&&`
- --> $DIR/eq_op.rs:45:13
+ --> $DIR/eq_op.rs:46:13
|
LL | let _ = a == b && b == a;
| ^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&&`
- --> $DIR/eq_op.rs:46:13
+ --> $DIR/eq_op.rs:47:13
|
LL | let _ = a != b && b != a;
| ^^^^^^^^^^^^^^^^
error: equal expressions as operands to `&&`
- --> $DIR/eq_op.rs:47:13
+ --> $DIR/eq_op.rs:48:13
|
LL | let _ = a < b && b > a;
| ^^^^^^^^^^^^^^
error: equal expressions as operands to `&&`
- --> $DIR/eq_op.rs:48:13
+ --> $DIR/eq_op.rs:49:13
|
LL | let _ = a <= b && b >= a;
| ^^^^^^^^^^^^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:51:13
+ --> $DIR/eq_op.rs:52:13
|
LL | let _ = a == a;
| ^^^^^^
error: equal expressions as operands to `/`
- --> $DIR/eq_op.rs:61:20
+ --> $DIR/eq_op.rs:62:20
|
LL | const D: u32 = A / A;
| ^^^^^
error: equal expressions as operands to `==`
- --> $DIR/eq_op.rs:92:5
+ --> $DIR/eq_op.rs:93: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/equatable_if_let.fixed b/src/tools/clippy/tests/ui/equatable_if_let.fixed
index 687efdada..9af2ba962 100644
--- a/src/tools/clippy/tests/ui/equatable_if_let.fixed
+++ b/src/tools/clippy/tests/ui/equatable_if_let.fixed
@@ -23,6 +23,11 @@ struct Struct {
b: bool,
}
+struct NoPartialEqStruct {
+ a: i32,
+ b: bool,
+}
+
enum NotPartialEq {
A,
B,
@@ -47,6 +52,7 @@ fn main() {
let e = Enum::UnitVariant;
let f = NotPartialEq::A;
let g = NotStructuralEq::A;
+ let h = NoPartialEqStruct { a: 2, b: false };
// true
@@ -66,10 +72,11 @@ fn main() {
if let Some(3 | 4) = c {}
if let Struct { a, b: false } = d {}
if let Struct { a: 2, b: x } = d {}
- if let NotPartialEq::A = f {}
+ if matches!(f, NotPartialEq::A) {}
if g == NotStructuralEq::A {}
- if let Some(NotPartialEq::A) = Some(f) {}
+ if matches!(Some(f), Some(NotPartialEq::A)) {}
if Some(g) == Some(NotStructuralEq::A) {}
+ if matches!(h, NoPartialEqStruct { a: 2, b: false }) {}
macro_rules! m1 {
(x) => {
diff --git a/src/tools/clippy/tests/ui/equatable_if_let.rs b/src/tools/clippy/tests/ui/equatable_if_let.rs
index 8c467d14d..c3626c081 100644
--- a/src/tools/clippy/tests/ui/equatable_if_let.rs
+++ b/src/tools/clippy/tests/ui/equatable_if_let.rs
@@ -23,6 +23,11 @@ struct Struct {
b: bool,
}
+struct NoPartialEqStruct {
+ a: i32,
+ b: bool,
+}
+
enum NotPartialEq {
A,
B,
@@ -47,6 +52,7 @@ fn main() {
let e = Enum::UnitVariant;
let f = NotPartialEq::A;
let g = NotStructuralEq::A;
+ let h = NoPartialEqStruct { a: 2, b: false };
// true
@@ -70,6 +76,7 @@ fn main() {
if let NotStructuralEq::A = g {}
if let Some(NotPartialEq::A) = Some(f) {}
if let Some(NotStructuralEq::A) = Some(g) {}
+ if let NoPartialEqStruct { a: 2, b: false } = h {}
macro_rules! m1 {
(x) => {
diff --git a/src/tools/clippy/tests/ui/equatable_if_let.stderr b/src/tools/clippy/tests/ui/equatable_if_let.stderr
index 9c4c3cc36..40ca75b8d 100644
--- a/src/tools/clippy/tests/ui/equatable_if_let.stderr
+++ b/src/tools/clippy/tests/ui/equatable_if_let.stderr
@@ -1,5 +1,5 @@
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:53:8
+ --> $DIR/equatable_if_let.rs:59:8
|
LL | if let 2 = a {}
| ^^^^^^^^^ help: try: `a == 2`
@@ -7,64 +7,82 @@ LL | if let 2 = a {}
= note: `-D clippy::equatable-if-let` implied by `-D warnings`
error: this pattern matching can be expressed using equality
- --> $DIR/equatable_if_let.rs:54:8
+ --> $DIR/equatable_if_let.rs:60: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:55:8
+ --> $DIR/equatable_if_let.rs:61: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:56:8
+ --> $DIR/equatable_if_let.rs:62: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:57:8
+ --> $DIR/equatable_if_let.rs:63: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:58:8
+ --> $DIR/equatable_if_let.rs:64: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:59:8
+ --> $DIR/equatable_if_let.rs:65: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:60:8
+ --> $DIR/equatable_if_let.rs:66: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:75: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:70:8
+ --> $DIR/equatable_if_let.rs:76: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:77: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:72:8
+ --> $DIR/equatable_if_let.rs:78:8
|
LL | if let Some(NotStructuralEq::A) = Some(g) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)`
-error: this pattern matching can be expressed using equality
+error: this pattern matching can be expressed using `matches!`
--> $DIR/equatable_if_let.rs:79: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:86:8
+ |
LL | if let m1!(x) = "abc" {
| ^^^^^^^^^^^^^^^^^^ help: try: `"abc" == m1!(x)`
-error: aborting due to 11 previous errors
+error: aborting due to 14 previous errors
diff --git a/src/tools/clippy/tests/ui/err_expect.fixed b/src/tools/clippy/tests/ui/err_expect.fixed
index 3bac738ac..b63cbd8a8 100644
--- a/src/tools/clippy/tests/ui/err_expect.fixed
+++ b/src/tools/clippy/tests/ui/err_expect.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(unused)]
struct MyTypeNonDebug;
@@ -16,16 +15,14 @@ fn main() {
test_non_debug.err().expect("Testing non debug type");
}
+#[clippy::msrv = "1.16"]
fn msrv_1_16() {
- #![clippy::msrv = "1.16"]
-
let x: Result<u32, &str> = Ok(16);
x.err().expect("16");
}
+#[clippy::msrv = "1.17"]
fn msrv_1_17() {
- #![clippy::msrv = "1.17"]
-
let x: Result<u32, &str> = Ok(17);
x.expect_err("17");
}
diff --git a/src/tools/clippy/tests/ui/err_expect.rs b/src/tools/clippy/tests/ui/err_expect.rs
index 6e7c47d9a..c081a745f 100644
--- a/src/tools/clippy/tests/ui/err_expect.rs
+++ b/src/tools/clippy/tests/ui/err_expect.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(unused)]
struct MyTypeNonDebug;
@@ -16,16 +15,14 @@ fn main() {
test_non_debug.err().expect("Testing non debug type");
}
+#[clippy::msrv = "1.16"]
fn msrv_1_16() {
- #![clippy::msrv = "1.16"]
-
let x: Result<u32, &str> = Ok(16);
x.err().expect("16");
}
+#[clippy::msrv = "1.17"]
fn msrv_1_17() {
- #![clippy::msrv = "1.17"]
-
let x: Result<u32, &str> = Ok(17);
x.err().expect("17");
}
diff --git a/src/tools/clippy/tests/ui/err_expect.stderr b/src/tools/clippy/tests/ui/err_expect.stderr
index 91a6cf8de..82c0754cf 100644
--- a/src/tools/clippy/tests/ui/err_expect.stderr
+++ b/src/tools/clippy/tests/ui/err_expect.stderr
@@ -1,5 +1,5 @@
error: called `.err().expect()` on a `Result` value
- --> $DIR/err_expect.rs:13:16
+ --> $DIR/err_expect.rs:12:16
|
LL | test_debug.err().expect("Testing debug type");
| ^^^^^^^^^^^^ help: try: `expect_err`
@@ -7,7 +7,7 @@ LL | test_debug.err().expect("Testing debug type");
= note: `-D clippy::err-expect` implied by `-D warnings`
error: called `.err().expect()` on a `Result` value
- --> $DIR/err_expect.rs:30:7
+ --> $DIR/err_expect.rs:27:7
|
LL | x.err().expect("17");
| ^^^^^^^^^^^^ help: try: `expect_err`
diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed
index a9cc80aaa..dc129591e 100644
--- a/src/tools/clippy/tests/ui/eta.fixed
+++ b/src/tools/clippy/tests/ui/eta.fixed
@@ -316,3 +316,25 @@ pub fn mutable_impl_fn_mut(mut f: impl FnMut(), mut f_used_once: impl FnMut()) -
move || takes_fn_mut(&mut f_used_once)
}
+
+impl dyn TestTrait + '_ {
+ fn method_on_dyn(&self) -> bool {
+ false
+ }
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/7746
+fn angle_brackets_and_substs() {
+ let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]);
+ array_opt.map(<[u8; 3]>::as_slice);
+
+ let slice_opt: Option<&[u8]> = Some(b"slice");
+ slice_opt.map(<[u8]>::len);
+
+ let ptr_opt: Option<*const usize> = Some(&487);
+ ptr_opt.map(<*const usize>::is_null);
+
+ let test_struct = TestStruct { some_ref: &487 };
+ let dyn_opt: Option<&dyn TestTrait> = Some(&test_struct);
+ dyn_opt.map(<dyn TestTrait>::method_on_dyn);
+}
diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs
index cc99906cc..025fd6a0b 100644
--- a/src/tools/clippy/tests/ui/eta.rs
+++ b/src/tools/clippy/tests/ui/eta.rs
@@ -316,3 +316,25 @@ pub fn mutable_impl_fn_mut(mut f: impl FnMut(), mut f_used_once: impl FnMut()) -
move || takes_fn_mut(|| f_used_once())
}
+
+impl dyn TestTrait + '_ {
+ fn method_on_dyn(&self) -> bool {
+ false
+ }
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/7746
+fn angle_brackets_and_substs() {
+ let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]);
+ array_opt.map(|a| a.as_slice());
+
+ let slice_opt: Option<&[u8]> = Some(b"slice");
+ slice_opt.map(|s| s.len());
+
+ let ptr_opt: Option<*const usize> = Some(&487);
+ ptr_opt.map(|p| p.is_null());
+
+ let test_struct = TestStruct { some_ref: &487 };
+ let dyn_opt: Option<&dyn TestTrait> = Some(&test_struct);
+ dyn_opt.map(|d| d.method_on_dyn());
+}
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index 434706b7e..a521fb868 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -134,5 +134,29 @@ error: redundant closure
LL | move || takes_fn_mut(|| f_used_once())
| ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
-error: aborting due to 22 previous errors
+error: redundant closure
+ --> $DIR/eta.rs:329:19
+ |
+LL | array_opt.map(|a| a.as_slice());
+ | ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`
+
+error: redundant closure
+ --> $DIR/eta.rs:332:19
+ |
+LL | slice_opt.map(|s| s.len());
+ | ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`
+
+error: redundant closure
+ --> $DIR/eta.rs:335:17
+ |
+LL | ptr_opt.map(|p| p.is_null());
+ | ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`
+
+error: redundant closure
+ --> $DIR/eta.rs:339:17
+ |
+LL | dyn_opt.map(|d| d.method_on_dyn());
+ | ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
+
+error: aborting due to 26 previous errors
diff --git a/src/tools/clippy/tests/ui/expect.stderr b/src/tools/clippy/tests/ui/expect.stderr
index f6738865c..c08e0dbbf 100644
--- a/src/tools/clippy/tests/ui/expect.stderr
+++ b/src/tools/clippy/tests/ui/expect.stderr
@@ -1,4 +1,4 @@
-error: used `expect()` on `an Option` value
+error: used `expect()` on an `Option` value
--> $DIR/expect.rs:5:13
|
LL | let _ = opt.expect("");
@@ -7,7 +7,7 @@ LL | let _ = opt.expect("");
= help: if this value is `None`, it will panic
= note: `-D clippy::expect-used` implied by `-D warnings`
-error: used `expect()` on `a Result` value
+error: used `expect()` on a `Result` value
--> $DIR/expect.rs:10:13
|
LL | let _ = res.expect("");
@@ -15,7 +15,7 @@ LL | let _ = res.expect("");
|
= help: if this value is an `Err`, it will panic
-error: used `expect_err()` on `a Result` value
+error: used `expect_err()` on a `Result` value
--> $DIR/expect.rs:11:13
|
LL | let _ = res.expect_err("");
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
index d1d35e5c0..475fae5e8 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
@@ -266,4 +266,19 @@ fn main() {
}
x
};
+
+ trait WithAssoc {
+ type Assoc: ?Sized;
+ }
+ impl WithAssoc for String {
+ type Assoc = str;
+ }
+ fn takes_assoc<T: WithAssoc>(_: &T::Assoc) -> T {
+ unimplemented!()
+ }
+ let _: String = takes_assoc(&*String::new());
+
+ // Issue #9901
+ fn takes_ref(_: &i32) {}
+ takes_ref(*Box::new(&0i32));
}
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.rs b/src/tools/clippy/tests/ui/explicit_auto_deref.rs
index deedafad1..c1894258f 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.rs
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.rs
@@ -266,4 +266,19 @@ fn main() {
}
*x
};
+
+ trait WithAssoc {
+ type Assoc: ?Sized;
+ }
+ impl WithAssoc for String {
+ type Assoc = str;
+ }
+ fn takes_assoc<T: WithAssoc>(_: &T::Assoc) -> T {
+ unimplemented!()
+ }
+ let _: String = takes_assoc(&*String::new());
+
+ // Issue #9901
+ fn takes_ref(_: &i32) {}
+ takes_ref(*Box::new(&0i32));
}
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 41828ddd7..462d46169 100644
--- a/src/tools/clippy/tests/ui/filter_map_next_fixable.fixed
+++ b/src/tools/clippy/tests/ui/filter_map_next_fixable.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::all, clippy::pedantic)]
#![allow(unused)]
@@ -11,16 +10,14 @@ fn main() {
assert_eq!(element, Some(1));
}
+#[clippy::msrv = "1.29"]
fn msrv_1_29() {
- #![clippy::msrv = "1.29"]
-
let a = ["1", "lol", "3", "NaN", "5"];
let _: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();
}
+#[clippy::msrv = "1.30"]
fn msrv_1_30() {
- #![clippy::msrv = "1.30"]
-
let a = ["1", "lol", "3", "NaN", "5"];
let _: Option<i32> = a.iter().find_map(|s| s.parse().ok());
}
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 be492a81b..2ea00cf73 100644
--- a/src/tools/clippy/tests/ui/filter_map_next_fixable.rs
+++ b/src/tools/clippy/tests/ui/filter_map_next_fixable.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::all, clippy::pedantic)]
#![allow(unused)]
@@ -11,16 +10,14 @@ fn main() {
assert_eq!(element, Some(1));
}
+#[clippy::msrv = "1.29"]
fn msrv_1_29() {
- #![clippy::msrv = "1.29"]
-
let a = ["1", "lol", "3", "NaN", "5"];
let _: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();
}
+#[clippy::msrv = "1.30"]
fn msrv_1_30() {
- #![clippy::msrv = "1.30"]
-
let a = ["1", "lol", "3", "NaN", "5"];
let _: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();
}
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 e789efeab..a9fc6abe8 100644
--- a/src/tools/clippy/tests/ui/filter_map_next_fixable.stderr
+++ b/src/tools/clippy/tests/ui/filter_map_next_fixable.stderr
@@ -1,5 +1,5 @@
error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead
- --> $DIR/filter_map_next_fixable.rs:10:32
+ --> $DIR/filter_map_next_fixable.rs:9:32
|
LL | let element: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `a.iter().find_map(|s| s.parse().ok())`
@@ -7,7 +7,7 @@ LL | let element: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next
= note: `-D clippy::filter-map-next` implied by `-D warnings`
error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead
- --> $DIR/filter_map_next_fixable.rs:25:26
+ --> $DIR/filter_map_next_fixable.rs:22:26
|
LL | let _: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `a.iter().find_map(|s| s.parse().ok())`
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 f805bcc9b..f53e53162 100644
--- a/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
+++ b/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
@@ -2,6 +2,7 @@
#![allow(clippy::too_many_arguments)]
extern "C" {
+ // Should not lint, most of the time users have no control over extern function signatures
fn f(_: bool, _: bool, _: bool, _: bool);
}
@@ -22,8 +23,12 @@ fn t(_: S, _: S, _: Box<S>, _: Vec<u32>, _: bool, _: bool, _: bool, _: bool) {}
struct S;
trait Trait {
+ // should warn for trait functions with and without body
fn f(_: bool, _: bool, _: bool, _: bool);
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) {}
}
impl S {
@@ -34,8 +39,11 @@ impl S {
}
impl Trait for S {
+ // Should not lint because the trait might not be changeable by the user
+ // We only lint in the trait definition
fn f(_: bool, _: bool, _: bool, _: bool) {}
fn g(_: bool, _: bool, _: bool, _: Vec<u32>) {}
+ fn h(_: bool, _: bool, _: bool, _: bool, _: bool, _: bool) {}
}
fn main() {
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 116271056..43363b469 100644
--- a/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr
+++ b/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr
@@ -1,5 +1,5 @@
error: more than 3 bools in function parameters
- --> $DIR/fn_params_excessive_bools.rs:18:1
+ --> $DIR/fn_params_excessive_bools.rs:19:1
|
LL | fn g(_: bool, _: bool, _: bool, _: bool) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | fn g(_: bool, _: bool, _: bool, _: bool) {}
= note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings`
error: more than 3 bools in function parameters
- --> $DIR/fn_params_excessive_bools.rs:21:1
+ --> $DIR/fn_params_excessive_bools.rs:22:1
|
LL | fn t(_: S, _: S, _: Box<S>, _: Vec<u32>, _: bool, _: bool, _: bool, _: bool) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,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:25:5
+ --> $DIR/fn_params_excessive_bools.rs:27:5
|
LL | fn f(_: bool, _: bool, _: bool, _: bool);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,15 @@ 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:30:5
+ --> $DIR/fn_params_excessive_bools.rs:31:5
+ |
+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
|
LL | fn f(&self, _: bool, _: bool, _: bool, _: bool) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +40,7 @@ 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:42:5
+ --> $DIR/fn_params_excessive_bools.rs:50:5
|
LL | / fn n(_: bool, _: u32, _: bool, _: Box<u32>, _: bool, _: bool) {
LL | | fn nn(_: bool, _: bool, _: bool, _: bool) {}
@@ -42,12 +50,12 @@ LL | | }
= help: consider refactoring bools into two-variant enums
error: more than 3 bools in function parameters
- --> $DIR/fn_params_excessive_bools.rs:43:9
+ --> $DIR/fn_params_excessive_bools.rs:51:9
|
LL | fn nn(_: bool, _: bool, _: bool, _: bool) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider refactoring bools into two-variant enums
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
diff --git a/src/tools/clippy/tests/ui/from_over_into.fixed b/src/tools/clippy/tests/ui/from_over_into.fixed
index 1cf49ca45..125c9a69c 100644
--- a/src/tools/clippy/tests/ui/from_over_into.fixed
+++ b/src/tools/clippy/tests/ui/from_over_into.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::from_over_into)]
#![allow(unused)]
@@ -60,9 +59,8 @@ impl From<String> for A {
}
}
+#[clippy::msrv = "1.40"]
fn msrv_1_40() {
- #![clippy::msrv = "1.40"]
-
struct FromOverInto<T>(Vec<T>);
impl<T> Into<FromOverInto<T>> for Vec<T> {
@@ -72,9 +70,8 @@ fn msrv_1_40() {
}
}
+#[clippy::msrv = "1.41"]
fn msrv_1_41() {
- #![clippy::msrv = "1.41"]
-
struct FromOverInto<T>(Vec<T>);
impl<T> From<Vec<T>> for FromOverInto<T> {
diff --git a/src/tools/clippy/tests/ui/from_over_into.rs b/src/tools/clippy/tests/ui/from_over_into.rs
index d30f3c3fc..5aa127bfa 100644
--- a/src/tools/clippy/tests/ui/from_over_into.rs
+++ b/src/tools/clippy/tests/ui/from_over_into.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::from_over_into)]
#![allow(unused)]
@@ -60,9 +59,8 @@ impl From<String> for A {
}
}
+#[clippy::msrv = "1.40"]
fn msrv_1_40() {
- #![clippy::msrv = "1.40"]
-
struct FromOverInto<T>(Vec<T>);
impl<T> Into<FromOverInto<T>> for Vec<T> {
@@ -72,9 +70,8 @@ fn msrv_1_40() {
}
}
+#[clippy::msrv = "1.41"]
fn msrv_1_41() {
- #![clippy::msrv = "1.41"]
-
struct FromOverInto<T>(Vec<T>);
impl<T> Into<FromOverInto<T>> for Vec<T> {
diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr
index 9c2a7c04c..a1764a5ea 100644
--- a/src/tools/clippy/tests/ui/from_over_into.stderr
+++ b/src/tools/clippy/tests/ui/from_over_into.stderr
@@ -1,5 +1,5 @@
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:9:1
|
LL | impl Into<StringWrapper> for String {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,7 +13,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:17:1
|
LL | impl Into<SelfType> for String {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,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:32:1
|
LL | impl Into<SelfKeywords> for X {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -41,7 +41,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:44:1
|
LL | impl core::convert::Into<bool> for crate::ExplicitPaths {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -59,7 +59,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:80:5
+ --> $DIR/from_over_into.rs:77:5
|
LL | impl<T> Into<FromOverInto<T>> for Vec<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
new file mode 100644
index 000000000..8484da241
--- /dev/null
+++ b/src/tools/clippy/tests/ui/from_raw_with_void_ptr.rs
@@ -0,0 +1,34 @@
+#![warn(clippy::from_raw_with_void_ptr)]
+
+use std::ffi::c_void;
+use std::rc::Rc;
+use std::sync::Arc;
+
+fn main() {
+ // must lint
+ let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;
+ let _ = unsafe { Box::from_raw(ptr) };
+
+ // shouldn't be linted
+ let _ = unsafe { Box::from_raw(ptr as *mut usize) };
+
+ // shouldn't be linted
+ let should_not_lint_ptr = Box::into_raw(Box::new(12u8)) as *mut u8;
+ let _ = unsafe { Box::from_raw(should_not_lint_ptr as *mut u8) };
+
+ // must lint
+ let ptr = Rc::into_raw(Rc::new(42usize)) as *mut c_void;
+ let _ = unsafe { Rc::from_raw(ptr) };
+
+ // must lint
+ let ptr = Arc::into_raw(Arc::new(42usize)) as *mut c_void;
+ let _ = unsafe { Arc::from_raw(ptr) };
+
+ // 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) };
+
+ // 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) };
+}
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
new file mode 100644
index 000000000..96e4af12b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/from_raw_with_void_ptr.stderr
@@ -0,0 +1,63 @@
+error: creating a `Box` from a void raw pointer
+ --> $DIR/from_raw_with_void_ptr.rs:10:22
+ |
+LL | let _ = unsafe { Box::from_raw(ptr) };
+ | ^^^^^^^^^^^^^^^^^^
+ |
+help: cast this to a pointer of the appropriate type
+ --> $DIR/from_raw_with_void_ptr.rs:10:36
+ |
+LL | let _ = unsafe { Box::from_raw(ptr) };
+ | ^^^
+ = note: `-D clippy::from-raw-with-void-ptr` implied by `-D warnings`
+
+error: creating a `Rc` from a void raw pointer
+ --> $DIR/from_raw_with_void_ptr.rs:21: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:21:35
+ |
+LL | let _ = unsafe { Rc::from_raw(ptr) };
+ | ^^^
+
+error: creating a `Arc` from a void raw pointer
+ --> $DIR/from_raw_with_void_ptr.rs:25: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:25:36
+ |
+LL | let _ = unsafe { Arc::from_raw(ptr) };
+ | ^^^
+
+error: creating a `Weak` from a void raw pointer
+ --> $DIR/from_raw_with_void_ptr.rs:29: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:29: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:33: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:33:48
+ |
+LL | let _ = unsafe { std::sync::Weak::from_raw(ptr) };
+ | ^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui/get_unwrap.stderr b/src/tools/clippy/tests/ui/get_unwrap.stderr
index 937f85904..6dee4d5b4 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/get_unwrap.stderr
@@ -10,7 +10,7 @@ note: the lint level is defined here
LL | #![deny(clippy::get_unwrap)]
| ^^^^^^^^^^^^^^^^^^
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:35:17
|
LL | let _ = boxed_slice.get(1).unwrap();
@@ -25,7 +25,7 @@ error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more co
LL | let _ = some_slice.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_slice[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:36:17
|
LL | let _ = some_slice.get(0).unwrap();
@@ -39,7 +39,7 @@ error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more conc
LL | let _ = some_vec.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vec[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:37:17
|
LL | let _ = some_vec.get(0).unwrap();
@@ -53,7 +53,7 @@ error: called `.get().unwrap()` on a VecDeque. Using `[]` is more clear and more
LL | let _ = some_vecdeque.get(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_vecdeque[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:38:17
|
LL | let _ = some_vecdeque.get(0).unwrap();
@@ -67,7 +67,7 @@ error: called `.get().unwrap()` on a HashMap. Using `[]` is more clear and more
LL | let _ = some_hashmap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_hashmap[&1]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:39:17
|
LL | let _ = some_hashmap.get(&1).unwrap();
@@ -81,7 +81,7 @@ error: called `.get().unwrap()` on a BTreeMap. Using `[]` is more clear and more
LL | let _ = some_btreemap.get(&1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&some_btreemap[&1]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:40:17
|
LL | let _ = some_btreemap.get(&1).unwrap();
@@ -95,7 +95,7 @@ error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more co
LL | let _: u8 = *boxed_slice.get(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[1]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:44:22
|
LL | let _: u8 = *boxed_slice.get(1).unwrap();
@@ -109,7 +109,7 @@ error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and mor
LL | *boxed_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `boxed_slice[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:49:10
|
LL | *boxed_slice.get_mut(0).unwrap() = 1;
@@ -123,7 +123,7 @@ error: called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and mor
LL | *some_slice.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_slice[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:50:10
|
LL | *some_slice.get_mut(0).unwrap() = 1;
@@ -137,7 +137,7 @@ error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more
LL | *some_vec.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:51:10
|
LL | *some_vec.get_mut(0).unwrap() = 1;
@@ -151,7 +151,7 @@ error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and
LL | *some_vecdeque.get_mut(0).unwrap() = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vecdeque[0]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:52:10
|
LL | *some_vecdeque.get_mut(0).unwrap() = 1;
@@ -165,7 +165,7 @@ error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more conc
LL | let _ = some_vec.get(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:64:17
|
LL | let _ = some_vec.get(0..1).unwrap().to_vec();
@@ -179,7 +179,7 @@ error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]`
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/get_unwrap.rs:65:17
|
LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
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 3bc3a0395..0e89fdb0d 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
@@ -1,5 +1,4 @@
#![warn(clippy::if_then_some_else_none)]
-#![feature(custom_inner_attributes)]
fn main() {
// Should issue an error.
@@ -66,8 +65,8 @@ fn main() {
let _ = if foo() { into_some("foo") } else { None };
}
+#[clippy::msrv = "1.49"]
fn _msrv_1_49() {
- #![clippy::msrv = "1.49"]
// `bool::then` was stabilized in 1.50. Do not lint this
let _ = if foo() {
println!("true!");
@@ -77,8 +76,8 @@ fn _msrv_1_49() {
};
}
+#[clippy::msrv = "1.50"]
fn _msrv_1_50() {
- #![clippy::msrv = "1.50"]
let _ = if foo() {
println!("true!");
Some(150)
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 24e0b5947..d728a3c31 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
@@ -1,5 +1,5 @@
error: this could be simplified with `bool::then`
- --> $DIR/if_then_some_else_none.rs:6:13
+ --> $DIR/if_then_some_else_none.rs:5:13
|
LL | let _ = if foo() {
| _____________^
@@ -14,7 +14,7 @@ LL | | };
= note: `-D clippy::if-then-some-else-none` implied by `-D warnings`
error: this could be simplified with `bool::then`
- --> $DIR/if_then_some_else_none.rs:14:13
+ --> $DIR/if_then_some_else_none.rs:13:13
|
LL | let _ = if matches!(true, true) {
| _____________^
@@ -28,7 +28,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:23:28
+ --> $DIR/if_then_some_else_none.rs:22:28
|
LL | let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +36,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:27:13
+ --> $DIR/if_then_some_else_none.rs:26:13
|
LL | let _ = if !x { Some(0) } else { None };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ 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:82:13
+ --> $DIR/if_then_some_else_none.rs:81:13
|
LL | let _ = if foo() {
| _____________^
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
index da5bc38b3..d8b6e3f12 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
@@ -4,11 +4,11 @@ error[E0080]: evaluation of `main::{constant#3}` failed
LL | const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
-error[E0080]: erroneous constant used
+note: erroneous constant used
--> $DIR/indexing_slicing_index.rs:31:5
|
LL | const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
- | ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+ | ^^^^^^^^^^^^^^^^^^^^^^
error: indexing may panic
--> $DIR/indexing_slicing_index.rs:22:5
@@ -65,6 +65,6 @@ error[E0080]: evaluation of constant value failed
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
-error: aborting due to 9 previous errors
+error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0080`.
diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed
index b8e40d995..61985e56b 100644
--- a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed
+++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed
@@ -9,6 +9,9 @@ enum SingleVariantEnum {
struct TupleStruct(i32);
+struct NonCopy;
+struct TupleStructWithNonCopy(NonCopy);
+
enum EmptyEnum {}
macro_rules! match_enum {
@@ -71,6 +74,15 @@ fn infallible_destructuring_match_struct() {
let TupleStruct(data) = wrapper;
}
+fn infallible_destructuring_match_struct_with_noncopy() {
+ let wrapper = TupleStructWithNonCopy(NonCopy);
+
+ // This should lint! (keeping `ref` in the suggestion)
+ let TupleStructWithNonCopy(ref data) = wrapper;
+
+ let TupleStructWithNonCopy(ref data) = wrapper;
+}
+
macro_rules! match_never_enum {
($param:expr) => {
let data = match $param {
diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs
index 106cd438b..f2768245b 100644
--- a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs
+++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs
@@ -9,6 +9,9 @@ enum SingleVariantEnum {
struct TupleStruct(i32);
+struct NonCopy;
+struct TupleStructWithNonCopy(NonCopy);
+
enum EmptyEnum {}
macro_rules! match_enum {
@@ -75,6 +78,17 @@ fn infallible_destructuring_match_struct() {
let TupleStruct(data) = wrapper;
}
+fn infallible_destructuring_match_struct_with_noncopy() {
+ let wrapper = TupleStructWithNonCopy(NonCopy);
+
+ // This should lint! (keeping `ref` in the suggestion)
+ let data = match wrapper {
+ TupleStructWithNonCopy(ref n) => n,
+ };
+
+ let TupleStructWithNonCopy(ref data) = wrapper;
+}
+
macro_rules! match_never_enum {
($param:expr) => {
let data = match $param {
diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.stderr b/src/tools/clippy/tests/ui/infallible_destructuring_match.stderr
index 1b78db420..f8a50f022 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:26:5
+ --> $DIR/infallible_destructuring_match.rs:29:5
|
LL | / let data = match wrapper {
LL | | SingleVariantEnum::Variant(i) => i,
@@ -9,7 +9,7 @@ LL | | };
= note: `-D clippy::infallible-destructuring-match` implied by `-D warnings`
error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
- --> $DIR/infallible_destructuring_match.rs:58:5
+ --> $DIR/infallible_destructuring_match.rs:61:5
|
LL | / let data = match wrapper {
LL | | TupleStruct(i) => i,
@@ -17,12 +17,20 @@ LL | | };
| |______^ help: try this: `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:90:5
+ --> $DIR/infallible_destructuring_match.rs:85:5
+ |
+LL | / let data = match wrapper {
+LL | | TupleStructWithNonCopy(ref n) => n,
+LL | | };
+ | |______^ help: try this: `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
|
LL | / let data = match wrapper {
LL | | Ok(i) => i,
LL | | };
| |______^ help: try this: `let Ok(data) = wrapper;`
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
diff --git a/src/tools/clippy/tests/ui/issue_4266.stderr b/src/tools/clippy/tests/ui/issue_4266.stderr
index fb2a93c95..fd553aa45 100644
--- a/src/tools/clippy/tests/ui/issue_4266.stderr
+++ b/src/tools/clippy/tests/ui/issue_4266.stderr
@@ -1,4 +1,4 @@
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+error: the following explicit lifetimes could be elided: 'a
--> $DIR/issue_4266.rs:4:1
|
LL | async fn sink1<'a>(_: &'a str) {} // lint
@@ -6,7 +6,7 @@ LL | async fn sink1<'a>(_: &'a str) {} // lint
|
= note: `-D clippy::needless-lifetimes` implied by `-D warnings`
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+error: the following explicit lifetimes could be elided: 'a
--> $DIR/issue_4266.rs:8:1
|
LL | async fn one_to_one<'a>(s: &'a str) -> &'a str {
diff --git a/src/tools/clippy/tests/ui/let_underscore_drop.rs b/src/tools/clippy/tests/ui/let_underscore_drop.rs
deleted file mode 100644
index 11b50492a..000000000
--- a/src/tools/clippy/tests/ui/let_underscore_drop.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-#![warn(clippy::let_underscore_drop)]
-#![allow(clippy::let_unit_value)]
-
-struct Droppable;
-
-impl Drop for Droppable {
- fn drop(&mut self) {}
-}
-
-fn main() {
- let unit = ();
- let boxed = Box::new(());
- let droppable = Droppable;
- let optional = Some(Droppable);
-
- let _ = ();
- let _ = Box::new(());
- let _ = Droppable;
- let _ = Some(Droppable);
-
- // no lint for reference
- let _ = droppable_ref();
-}
-
-#[must_use]
-fn droppable_ref() -> &'static mut Droppable {
- unimplemented!()
-}
diff --git a/src/tools/clippy/tests/ui/let_underscore_drop.stderr b/src/tools/clippy/tests/ui/let_underscore_drop.stderr
deleted file mode 100644
index 324b7cd43..000000000
--- a/src/tools/clippy/tests/ui/let_underscore_drop.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error: non-binding `let` on a type that implements `Drop`
- --> $DIR/let_underscore_drop.rs:17:5
- |
-LL | let _ = Box::new(());
- | ^^^^^^^^^^^^^^^^^^^^^
- |
- = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
- = note: `-D clippy::let-underscore-drop` implied by `-D warnings`
-
-error: non-binding `let` on a type that implements `Drop`
- --> $DIR/let_underscore_drop.rs:18:5
- |
-LL | let _ = Droppable;
- | ^^^^^^^^^^^^^^^^^^
- |
- = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
-
-error: non-binding `let` on a type that implements `Drop`
- --> $DIR/let_underscore_drop.rs:19:5
- |
-LL | let _ = Some(Droppable);
- | ^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
-
-error: aborting due to 3 previous errors
-
diff --git a/src/tools/clippy/tests/ui/let_underscore_future.rs b/src/tools/clippy/tests/ui/let_underscore_future.rs
new file mode 100644
index 000000000..d8f54cdca
--- /dev/null
+++ b/src/tools/clippy/tests/ui/let_underscore_future.rs
@@ -0,0 +1,20 @@
+use std::future::Future;
+
+async fn some_async_fn() {}
+
+fn sync_side_effects() {}
+fn custom() -> impl Future<Output = ()> {
+ sync_side_effects();
+ async {}
+}
+
+fn do_something_to_future(future: &mut impl Future<Output = ()>) {}
+
+fn main() {
+ let _ = some_async_fn();
+ let _ = custom();
+
+ let mut future = some_async_fn();
+ do_something_to_future(&mut future);
+ let _ = future;
+}
diff --git a/src/tools/clippy/tests/ui/let_underscore_future.stderr b/src/tools/clippy/tests/ui/let_underscore_future.stderr
new file mode 100644
index 000000000..33a748736
--- /dev/null
+++ b/src/tools/clippy/tests/ui/let_underscore_future.stderr
@@ -0,0 +1,27 @@
+error: non-binding `let` on a future
+ --> $DIR/let_underscore_future.rs:14:5
+ |
+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`
+
+error: non-binding `let` on a future
+ --> $DIR/let_underscore_future.rs:15:5
+ |
+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
+ |
+LL | let _ = future;
+ | ^^^^^^^^^^^^^^^
+ |
+ = help: consider awaiting the future or dropping explicitly with `std::mem::drop`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/let_underscore_lock.rs b/src/tools/clippy/tests/ui/let_underscore_lock.rs
index 7a7c4e924..4dff4d766 100644
--- a/src/tools/clippy/tests/ui/let_underscore_lock.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_lock.rs
@@ -3,20 +3,6 @@
extern crate parking_lot;
fn main() {
- let m = std::sync::Mutex::new(());
- let rw = std::sync::RwLock::new(());
-
- let _ = m.lock();
- let _ = rw.read();
- let _ = rw.write();
- let _ = m.try_lock();
- let _ = rw.try_read();
- let _ = rw.try_write();
-
- // These shouldn't throw an error.
- let _ = m;
- let _ = rw;
-
use parking_lot::{lock_api::RawMutex, Mutex, RwLock};
let p_m: Mutex<()> = Mutex::const_new(RawMutex::INIT, ());
@@ -34,3 +20,20 @@ fn main() {
let _ = p_m1;
let _ = p_rw;
}
+
+fn uplifted() {
+ // shouldn't lint std locks as they were uplifted as rustc's `let_underscore_lock`
+
+ let m = std::sync::Mutex::new(());
+ let rw = std::sync::RwLock::new(());
+
+ let _ = m.lock();
+ let _ = rw.read();
+ let _ = rw.write();
+ let _ = m.try_lock();
+ let _ = rw.try_read();
+ let _ = rw.try_write();
+
+ let _ = m;
+ let _ = rw;
+}
diff --git a/src/tools/clippy/tests/ui/let_underscore_lock.stderr b/src/tools/clippy/tests/ui/let_underscore_lock.stderr
index d7779e7b6..f137d4112 100644
--- a/src/tools/clippy/tests/ui/let_underscore_lock.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_lock.stderr
@@ -1,83 +1,35 @@
-error: non-binding let on a synchronization lock
+error: non-binding `let` on a synchronization lock
--> $DIR/let_underscore_lock.rs:9:5
|
-LL | let _ = 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`
-
-error: non-binding let on a synchronization lock
- --> $DIR/let_underscore_lock.rs:10:5
- |
-LL | let _ = 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:11:5
- |
-LL | let _ = rw.write();
- | ^^^^^^^^^^^^^^^^^^^
- |
- = 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:12:5
- |
-LL | let _ = m.try_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:13:5
- |
-LL | let _ = rw.try_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:14:5
- |
-LL | let _ = rw.try_write();
- | ^^^^^^^^^^^^^^^^^^^^^^^
- |
- = 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:23:5
- |
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`
-error: non-binding let on a synchronization lock
- --> $DIR/let_underscore_lock.rs:26:5
+error: non-binding `let` on a synchronization lock
+ --> $DIR/let_underscore_lock.rs:12:5
|
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:29:5
+error: non-binding `let` on a synchronization lock
+ --> $DIR/let_underscore_lock.rs:15:5
|
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:30:5
+error: non-binding `let` on a synchronization lock
+ --> $DIR/let_underscore_lock.rs:16:5
|
LL | let _ = p_rw.write();
| ^^^^^^^^^^^^^^^^^^^^^
|
= help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
-error: aborting due to 10 previous errors
+error: aborting due to 4 previous errors
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 bae60f2ff..28d760eb4 100644
--- a/src/tools/clippy/tests/ui/let_underscore_must_use.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_must_use.stderr
@@ -1,4 +1,4 @@
-error: non-binding let on a result of a `#[must_use]` function
+error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:67:5
|
LL | let _ = f();
@@ -7,7 +7,7 @@ LL | let _ = f();
= help: consider explicitly using function result
= note: `-D clippy::let-underscore-must-use` implied by `-D warnings`
-error: non-binding let on an expression with `#[must_use]` type
+error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:68:5
|
LL | let _ = g();
@@ -15,7 +15,7 @@ LL | let _ = g();
|
= help: consider explicitly using expression value
-error: non-binding let on a result of a `#[must_use]` function
+error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:70:5
|
LL | let _ = l(0_u32);
@@ -23,7 +23,7 @@ LL | let _ = l(0_u32);
|
= help: consider explicitly using function result
-error: non-binding let on a result of a `#[must_use]` function
+error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:74:5
|
LL | let _ = s.f();
@@ -31,7 +31,7 @@ LL | let _ = s.f();
|
= help: consider explicitly using function result
-error: non-binding let on an expression with `#[must_use]` type
+error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:75:5
|
LL | let _ = s.g();
@@ -39,7 +39,7 @@ LL | let _ = s.g();
|
= help: consider explicitly using expression value
-error: non-binding let on a result of a `#[must_use]` function
+error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:78:5
|
LL | let _ = S::h();
@@ -47,7 +47,7 @@ LL | let _ = S::h();
|
= help: consider explicitly using function result
-error: non-binding let on an expression with `#[must_use]` type
+error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:79:5
|
LL | let _ = S::p();
@@ -55,7 +55,7 @@ LL | let _ = S::p();
|
= help: consider explicitly using expression value
-error: non-binding let on a result of a `#[must_use]` function
+error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:81:5
|
LL | let _ = S::a();
@@ -63,7 +63,7 @@ LL | let _ = S::a();
|
= help: consider explicitly using function result
-error: non-binding let on an expression with `#[must_use]` type
+error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:83:5
|
LL | let _ = if true { Ok(()) } else { Err(()) };
@@ -71,7 +71,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
+error: non-binding `let` on a result of a `#[must_use]` function
--> $DIR/let_underscore_must_use.rs:87:5
|
LL | let _ = a.is_ok();
@@ -79,7 +79,7 @@ LL | let _ = a.is_ok();
|
= help: consider explicitly using function result
-error: non-binding let on an expression with `#[must_use]` type
+error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:89:5
|
LL | let _ = a.map(|_| ());
@@ -87,7 +87,7 @@ LL | let _ = a.map(|_| ());
|
= help: consider explicitly using expression value
-error: non-binding let on an expression with `#[must_use]` type
+error: non-binding `let` on an expression with `#[must_use]` type
--> $DIR/let_underscore_must_use.rs:91:5
|
LL | let _ = a;
diff --git a/src/tools/clippy/tests/ui/macro_use_imports.stderr b/src/tools/clippy/tests/ui/macro_use_imports.stderr
index bf7b6edd0..61843124c 100644
--- a/src/tools/clippy/tests/ui/macro_use_imports.stderr
+++ b/src/tools/clippy/tests/ui/macro_use_imports.stderr
@@ -1,8 +1,8 @@
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
- --> $DIR/macro_use_imports.rs:23:5
+ --> $DIR/macro_use_imports.rs:25:5
|
LL | #[macro_use]
- | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::foofoo, inner::try_err};`
+ | ^^^^^^^^^^^^ 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`
@@ -13,10 +13,10 @@ LL | #[macro_use]
| ^^^^^^^^^^^^ 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:25:5
+ --> $DIR/macro_use_imports.rs:23: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 mac::{inner::foofoo, inner::try_err};`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:19:5
diff --git a/src/tools/clippy/tests/ui/manual_clamp.rs b/src/tools/clippy/tests/ui/manual_clamp.rs
index 331fd29b7..f7902e6fd 100644
--- a/src/tools/clippy/tests/ui/manual_clamp.rs
+++ b/src/tools/clippy/tests/ui/manual_clamp.rs
@@ -1,4 +1,3 @@
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_clamp)]
#![allow(
unused,
@@ -304,9 +303,8 @@ fn cmp_min_max(input: i32) -> i32 {
input * 3
}
+#[clippy::msrv = "1.49"]
fn msrv_1_49() {
- #![clippy::msrv = "1.49"]
-
let (input, min, max) = (0, -1, 2);
let _ = if input < min {
min
@@ -317,9 +315,8 @@ fn msrv_1_49() {
};
}
+#[clippy::msrv = "1.50"]
fn msrv_1_50() {
- #![clippy::msrv = "1.50"]
-
let (input, min, max) = (0, -1, 2);
let _ = if input < min {
min
diff --git a/src/tools/clippy/tests/ui/manual_clamp.stderr b/src/tools/clippy/tests/ui/manual_clamp.stderr
index 70abe2809..988ad1527 100644
--- a/src/tools/clippy/tests/ui/manual_clamp.stderr
+++ b/src/tools/clippy/tests/ui/manual_clamp.stderr
@@ -1,5 +1,5 @@
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:77:5
+ --> $DIR/manual_clamp.rs:76:5
|
LL | / if x9 < min {
LL | | x9 = min;
@@ -13,7 +13,7 @@ LL | | }
= note: `-D clippy::manual-clamp` implied by `-D warnings`
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:92:5
+ --> $DIR/manual_clamp.rs:91:5
|
LL | / if x11 > max {
LL | | x11 = max;
@@ -26,7 +26,7 @@ LL | | }
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:100:5
+ --> $DIR/manual_clamp.rs:99:5
|
LL | / if min > x12 {
LL | | x12 = min;
@@ -39,7 +39,7 @@ LL | | }
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:108:5
+ --> $DIR/manual_clamp.rs:107:5
|
LL | / if max < x13 {
LL | | x13 = max;
@@ -52,7 +52,7 @@ LL | | }
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:162:5
+ --> $DIR/manual_clamp.rs:161:5
|
LL | / if max < x33 {
LL | | x33 = max;
@@ -65,7 +65,7 @@ LL | | }
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:22:14
+ --> $DIR/manual_clamp.rs:21:14
|
LL | let x0 = if max < input {
| ______________^
@@ -80,7 +80,7 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:30:14
+ --> $DIR/manual_clamp.rs:29:14
|
LL | let x1 = if input > max {
| ______________^
@@ -95,7 +95,7 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:38:14
+ --> $DIR/manual_clamp.rs:37:14
|
LL | let x2 = if input < min {
| ______________^
@@ -110,7 +110,7 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:46:14
+ --> $DIR/manual_clamp.rs:45:14
|
LL | let x3 = if min > input {
| ______________^
@@ -125,7 +125,7 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:54:14
+ --> $DIR/manual_clamp.rs:53:14
|
LL | let x4 = input.max(min).min(max);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(min, max)`
@@ -133,7 +133,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:56:14
+ --> $DIR/manual_clamp.rs:55:14
|
LL | let x5 = input.min(max).max(min);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(min, max)`
@@ -141,7 +141,7 @@ 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:58:14
+ --> $DIR/manual_clamp.rs:57:14
|
LL | let x6 = match input {
| ______________^
@@ -154,7 +154,7 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:64:14
+ --> $DIR/manual_clamp.rs:63:14
|
LL | let x7 = match input {
| ______________^
@@ -167,7 +167,7 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:70:14
+ --> $DIR/manual_clamp.rs:69:14
|
LL | let x8 = match input {
| ______________^
@@ -180,7 +180,7 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:84:15
+ --> $DIR/manual_clamp.rs:83:15
|
LL | let x10 = match input {
| _______________^
@@ -193,7 +193,7 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:115:15
+ --> $DIR/manual_clamp.rs:114:15
|
LL | let x14 = if input > CONST_MAX {
| _______________^
@@ -208,7 +208,7 @@ LL | | };
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:124:19
+ --> $DIR/manual_clamp.rs:123:19
|
LL | let x15 = if input > max {
| ___________________^
@@ -224,7 +224,7 @@ LL | | };
= note: clamp returns NaN if the input is NaN
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:135:19
+ --> $DIR/manual_clamp.rs:134: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 +232,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:136:19
+ --> $DIR/manual_clamp.rs:135: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 +240,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:137:19
+ --> $DIR/manual_clamp.rs:136: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 +248,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:138:19
+ --> $DIR/manual_clamp.rs:137: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 +256,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:139:19
+ --> $DIR/manual_clamp.rs:138: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 +264,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:140:19
+ --> $DIR/manual_clamp.rs:139: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 +272,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:141:19
+ --> $DIR/manual_clamp.rs:140: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 +280,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:142:19
+ --> $DIR/manual_clamp.rs:141: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 +288,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:144:19
+ --> $DIR/manual_clamp.rs:143: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 +297,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:145:19
+ --> $DIR/manual_clamp.rs:144: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 +306,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:146:19
+ --> $DIR/manual_clamp.rs:145: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 +315,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:147:19
+ --> $DIR/manual_clamp.rs:146: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 +324,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:148:19
+ --> $DIR/manual_clamp.rs:147: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 +333,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:149:19
+ --> $DIR/manual_clamp.rs:148: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 +342,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:150:19
+ --> $DIR/manual_clamp.rs:149: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 +351,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:151:19
+ --> $DIR/manual_clamp.rs:150: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,7 +360,7 @@ 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:154:5
+ --> $DIR/manual_clamp.rs:153:5
|
LL | / if x32 < min {
LL | | x32 = min;
@@ -372,7 +372,7 @@ LL | | }
= note: clamp will panic if max < min
error: clamp-like pattern without using clamp function
- --> $DIR/manual_clamp.rs:324:13
+ --> $DIR/manual_clamp.rs:321:13
|
LL | let _ = if input < min {
| _____________^
diff --git a/src/tools/clippy/tests/ui/manual_flatten.rs b/src/tools/clippy/tests/ui/manual_flatten.rs
index 96cd87c0e..552213a7f 100644
--- a/src/tools/clippy/tests/ui/manual_flatten.rs
+++ b/src/tools/clippy/tests/ui/manual_flatten.rs
@@ -10,7 +10,7 @@ fn main() {
}
}
- // Test for loop over implicitly implicitly adjusted `Iterator` with `if let` statement
+ // Test for loop over implicitly adjusted `Iterator` with `if let` statement
let y: Vec<Result<i32, i32>> = vec![];
for n in y.clone() {
if let Ok(n) = n {
diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed b/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed
index 0fa776b7b..85a91543c 100644
--- a/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed
+++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed
@@ -1,6 +1,7 @@
// run-rustfix
#![warn(clippy::manual_instant_elapsed)]
#![allow(clippy::unnecessary_operation)]
+#![allow(clippy::unchecked_duration_subtraction)]
#![allow(unused_variables)]
#![allow(unused_must_use)]
diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.rs b/src/tools/clippy/tests/ui/manual_instant_elapsed.rs
index 5b11b8453..c98cb15b9 100644
--- a/src/tools/clippy/tests/ui/manual_instant_elapsed.rs
+++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.rs
@@ -1,6 +1,7 @@
// run-rustfix
#![warn(clippy::manual_instant_elapsed)]
#![allow(clippy::unnecessary_operation)]
+#![allow(clippy::unchecked_duration_subtraction)]
#![allow(unused_variables)]
#![allow(unused_must_use)]
diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr b/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr
index 5537f5642..4ce1f6891 100644
--- a/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr
+++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.stderr
@@ -1,5 +1,5 @@
error: manual implementation of `Instant::elapsed`
- --> $DIR/manual_instant_elapsed.rs:17:20
+ --> $DIR/manual_instant_elapsed.rs:18:20
|
LL | let duration = Instant::now() - prev_instant;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `prev_instant.elapsed()`
@@ -7,7 +7,7 @@ LL | let duration = Instant::now() - prev_instant;
= note: `-D clippy::manual-instant-elapsed` implied by `-D warnings`
error: manual implementation of `Instant::elapsed`
- --> $DIR/manual_instant_elapsed.rs:26:5
+ --> $DIR/manual_instant_elapsed.rs:27: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
new file mode 100644
index 000000000..231ba83b1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed
@@ -0,0 +1,42 @@
+// run-rustfix
+
+#![allow(unused, dead_code)]
+#![warn(clippy::manual_is_ascii_check)]
+
+fn main() {
+ assert!('x'.is_ascii_lowercase());
+ assert!('X'.is_ascii_uppercase());
+ assert!(b'x'.is_ascii_lowercase());
+ assert!(b'X'.is_ascii_uppercase());
+
+ let num = '2';
+ assert!(num.is_ascii_digit());
+ assert!(b'1'.is_ascii_digit());
+ assert!('x'.is_ascii_alphabetic());
+
+ assert!(matches!('x', 'A'..='Z' | 'a'..='z' | '_'));
+}
+
+#[clippy::msrv = "1.23"]
+fn msrv_1_23() {
+ assert!(matches!(b'1', b'0'..=b'9'));
+ assert!(matches!('X', 'A'..='Z'));
+ assert!(matches!('x', 'A'..='Z' | 'a'..='z'));
+}
+
+#[clippy::msrv = "1.24"]
+fn msrv_1_24() {
+ assert!(b'1'.is_ascii_digit());
+ assert!('X'.is_ascii_uppercase());
+ assert!('x'.is_ascii_alphabetic());
+}
+
+#[clippy::msrv = "1.46"]
+fn msrv_1_46() {
+ const FOO: bool = matches!('x', '0'..='9');
+}
+
+#[clippy::msrv = "1.47"]
+fn msrv_1_47() {
+ const FOO: bool = 'x'.is_ascii_digit();
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
new file mode 100644
index 000000000..39ee6151c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
@@ -0,0 +1,42 @@
+// run-rustfix
+
+#![allow(unused, dead_code)]
+#![warn(clippy::manual_is_ascii_check)]
+
+fn main() {
+ assert!(matches!('x', 'a'..='z'));
+ assert!(matches!('X', 'A'..='Z'));
+ assert!(matches!(b'x', b'a'..=b'z'));
+ assert!(matches!(b'X', b'A'..=b'Z'));
+
+ let num = '2';
+ assert!(matches!(num, '0'..='9'));
+ assert!(matches!(b'1', b'0'..=b'9'));
+ assert!(matches!('x', 'A'..='Z' | 'a'..='z'));
+
+ assert!(matches!('x', 'A'..='Z' | 'a'..='z' | '_'));
+}
+
+#[clippy::msrv = "1.23"]
+fn msrv_1_23() {
+ assert!(matches!(b'1', b'0'..=b'9'));
+ assert!(matches!('X', 'A'..='Z'));
+ assert!(matches!('x', 'A'..='Z' | 'a'..='z'));
+}
+
+#[clippy::msrv = "1.24"]
+fn msrv_1_24() {
+ assert!(matches!(b'1', b'0'..=b'9'));
+ assert!(matches!('X', 'A'..='Z'));
+ assert!(matches!('x', 'A'..='Z' | 'a'..='z'));
+}
+
+#[clippy::msrv = "1.46"]
+fn msrv_1_46() {
+ const FOO: bool = matches!('x', '0'..='9');
+}
+
+#[clippy::msrv = "1.47"]
+fn msrv_1_47() {
+ const FOO: bool = matches!('x', '0'..='9');
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
new file mode 100644
index 000000000..397cbe05c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
@@ -0,0 +1,70 @@
+error: manual check for common ascii range
+ --> $DIR/manual_is_ascii_check.rs:7:13
+ |
+LL | assert!(matches!('x', 'a'..='z'));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_lowercase()`
+ |
+ = note: `-D clippy::manual-is-ascii-check` implied by `-D warnings`
+
+error: manual check for common ascii range
+ --> $DIR/manual_is_ascii_check.rs:8: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
+ |
+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
+ |
+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
+ |
+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
+ |
+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
+ |
+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:29: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:30: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:31: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:41:23
+ |
+LL | const FOO: bool = matches!('x', '0'..='9');
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'x'.is_ascii_digit()`
+
+error: aborting due to 11 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_let_else.rs b/src/tools/clippy/tests/ui/manual_let_else.rs
new file mode 100644
index 000000000..48a162c13
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_let_else.rs
@@ -0,0 +1,251 @@
+#![allow(unused_braces, unused_variables, dead_code)]
+#![allow(
+ clippy::collapsible_else_if,
+ clippy::unused_unit,
+ clippy::let_unit_value,
+ clippy::match_single_binding,
+ clippy::never_loop
+)]
+#![warn(clippy::manual_let_else)]
+
+fn g() -> Option<()> {
+ None
+}
+
+fn main() {}
+
+fn fire() {
+ let v = if let Some(v_some) = g() { v_some } else { return };
+ let v = if let Some(v_some) = g() {
+ v_some
+ } else {
+ return;
+ };
+
+ let v = if let Some(v) = g() {
+ // Blocks around the identity should have no impact
+ {
+ { v }
+ }
+ } else {
+ // Some computation should still make it fire
+ g();
+ return;
+ };
+
+ // continue and break diverge
+ loop {
+ let v = if let Some(v_some) = g() { v_some } else { continue };
+ let v = if let Some(v_some) = g() { v_some } else { break };
+ }
+
+ // panic also diverges
+ let v = if let Some(v_some) = g() { v_some } else { panic!() };
+
+ // abort also diverges
+ let v = if let Some(v_some) = g() {
+ v_some
+ } else {
+ std::process::abort()
+ };
+
+ // If whose two branches diverge also diverges
+ let v = if let Some(v_some) = g() {
+ v_some
+ } else {
+ if true { return } else { panic!() }
+ };
+
+ // Diverging after an if still makes the block diverge:
+ let v = if let Some(v_some) = g() {
+ v_some
+ } else {
+ if true {}
+ panic!();
+ };
+
+ // A match diverges if all branches diverge:
+ // 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() {
+ v_some
+ } else {
+ match () {
+ _ if panic!() => {},
+ _ => panic!(),
+ }
+ };
+
+ // An if's expression can cause divergence:
+ let v = if let Some(v_some) = g() { v_some } else { if panic!() {} };
+
+ // An expression of a match can cause divergence:
+ let v = if let Some(v_some) = g() {
+ v_some
+ } else {
+ match panic!() {
+ _ => {},
+ }
+ };
+
+ // Top level else if
+ let v = if let Some(v_some) = g() {
+ v_some
+ } else if true {
+ return;
+ } else {
+ panic!("diverge");
+ };
+
+ // All match arms diverge
+ let v = if let Some(v_some) = g() {
+ v_some
+ } else {
+ match (g(), g()) {
+ (Some(_), None) => return,
+ (None, Some(_)) => {
+ if true {
+ return;
+ } else {
+ panic!();
+ }
+ },
+ _ => return,
+ }
+ };
+
+ // Tuples supported for the declared variables
+ let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) {
+ v_some
+ } else {
+ return;
+ };
+
+ // Tuples supported for the identity block and pattern
+ let v = if let (Some(v_some), w_some) = (g(), 0) {
+ (w_some, v_some)
+ } else {
+ return;
+ };
+
+ // entirely inside macro lints
+ macro_rules! create_binding_if_some {
+ ($n:ident, $e:expr) => {
+ let $n = if let Some(v) = $e { v } else { return };
+ };
+ }
+ create_binding_if_some!(w, g());
+}
+
+fn not_fire() {
+ let v = if let Some(v_some) = g() {
+ // Nothing returned. Should not fire.
+ } else {
+ return;
+ };
+
+ let w = 0;
+ let v = if let Some(v_some) = g() {
+ // Different variable than v_some. Should not fire.
+ w
+ } else {
+ return;
+ };
+
+ let v = if let Some(v_some) = g() {
+ // Computation in then clause. Should not fire.
+ g();
+ v_some
+ } else {
+ return;
+ };
+
+ let v = if let Some(v_some) = g() {
+ v_some
+ } else {
+ if false {
+ return;
+ }
+ // This doesn't diverge. Should not fire.
+ ()
+ };
+
+ let v = if let Some(v_some) = g() {
+ v_some
+ } else {
+ // There is one match arm that doesn't diverge. Should not fire.
+ match (g(), g()) {
+ (Some(_), None) => return,
+ (None, Some(_)) => return,
+ (Some(_), Some(_)) => (),
+ _ => return,
+ }
+ };
+
+ let v = if let Some(v_some) = g() {
+ v_some
+ } else {
+ // loop with a break statement inside does not diverge.
+ loop {
+ break;
+ }
+ };
+
+ enum Uninhabited {}
+ fn un() -> Uninhabited {
+ panic!()
+ }
+ let v = if let Some(v_some) = None {
+ v_some
+ } else {
+ // Don't lint if the type is uninhabited but not !
+ un()
+ };
+
+ fn question_mark() -> Option<()> {
+ let v = if let Some(v) = g() {
+ v
+ } else {
+ // Question mark does not diverge
+ g()?
+ };
+ Some(v)
+ }
+
+ // Macro boundary inside let
+ macro_rules! some_or_return {
+ ($e:expr) => {
+ if let Some(v) = $e { v } else { return }
+ };
+ }
+ let v = some_or_return!(g());
+
+ // Also macro boundary inside let, but inside a macro
+ macro_rules! create_binding_if_some_nf {
+ ($n:ident, $e:expr) => {
+ let $n = some_or_return!($e);
+ };
+ }
+ create_binding_if_some_nf!(v, g());
+
+ // Already a let-else
+ let Some(a) = (if let Some(b) = Some(Some(())) { b } else { return }) else { panic!() };
+
+ // If a type annotation is present, don't lint as
+ // expressing the type might be too hard
+ let v: () = if let Some(v_some) = g() { v_some } else { panic!() };
+
+ // Issue 9940
+ // Suggestion should not expand macros
+ macro_rules! macro_call {
+ () => {
+ return ()
+ };
+ }
+
+ let ff = Some(1);
+ let _ = match ff {
+ 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
new file mode 100644
index 000000000..52aac6bc6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_let_else.stderr
@@ -0,0 +1,272 @@
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:18:5
+ |
+LL | let v = if let Some(v_some) = g() { v_some } else { return };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v_some) = g() else { return };`
+ |
+ = note: `-D clippy::manual-let-else` implied by `-D warnings`
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:19:5
+ |
+LL | / let v = if let Some(v_some) = g() {
+LL | | v_some
+LL | | } else {
+LL | | return;
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let Some(v_some) = g() else {
+LL + return;
+LL + };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:25:5
+ |
+LL | / let v = if let Some(v) = g() {
+LL | | // Blocks around the identity should have no impact
+LL | | {
+LL | | { v }
+... |
+LL | | return;
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let Some(v) = g() else {
+LL + // Some computation should still make it fire
+LL + g();
+LL + return;
+LL + };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:38:9
+ |
+LL | let v = if let Some(v_some) = g() { v_some } else { continue };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v_some) = g() else { continue };`
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:39:9
+ |
+LL | let v = if let Some(v_some) = g() { v_some } else { break };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v_some) = g() else { break };`
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:43:5
+ |
+LL | let v = if let Some(v_some) = g() { v_some } else { panic!() };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v_some) = g() else { panic!() };`
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:46:5
+ |
+LL | / let v = if let Some(v_some) = g() {
+LL | | v_some
+LL | | } else {
+LL | | std::process::abort()
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let Some(v_some) = g() else {
+LL + std::process::abort()
+LL + };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:53:5
+ |
+LL | / let v = if let Some(v_some) = g() {
+LL | | v_some
+LL | | } else {
+LL | | if true { return } else { panic!() }
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let Some(v_some) = g() else {
+LL + if true { return } else { panic!() }
+LL + };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:60:5
+ |
+LL | / let v = if let Some(v_some) = g() {
+LL | | v_some
+LL | | } else {
+LL | | if true {}
+LL | | panic!();
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let Some(v_some) = g() else {
+LL + if true {}
+LL + panic!();
+LL + };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:70:5
+ |
+LL | / let v = if let Some(v_some) = g() {
+LL | | v_some
+LL | | } else {
+LL | | match () {
+... |
+LL | | }
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let Some(v_some) = g() else {
+LL + match () {
+LL + _ if panic!() => {},
+LL + _ => panic!(),
+LL + }
+LL + };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:80:5
+ |
+LL | let v = if let Some(v_some) = g() { v_some } else { if panic!() {} };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v_some) = g() else { if panic!() {} };`
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:83:5
+ |
+LL | / let v = if let Some(v_some) = g() {
+LL | | v_some
+LL | | } else {
+LL | | match panic!() {
+LL | | _ => {},
+LL | | }
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let Some(v_some) = g() else {
+LL + match panic!() {
+LL + _ => {},
+LL + }
+LL + };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:92:5
+ |
+LL | / let v = if let Some(v_some) = g() {
+LL | | v_some
+LL | | } else if true {
+LL | | return;
+LL | | } else {
+LL | | panic!("diverge");
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let Some(v_some) = g() else { if true {
+LL + return;
+LL + } else {
+LL + panic!("diverge");
+LL + } };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:101:5
+ |
+LL | / let v = if let Some(v_some) = g() {
+LL | | v_some
+LL | | } else {
+LL | | match (g(), g()) {
+... |
+LL | | }
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let Some(v_some) = g() else {
+LL + match (g(), g()) {
+LL + (Some(_), None) => return,
+LL + (None, Some(_)) => {
+LL + if true {
+LL + return;
+LL + } else {
+LL + panic!();
+LL + }
+LL + },
+LL + _ => return,
+LL + }
+LL + };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:118:5
+ |
+LL | / let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) {
+LL | | v_some
+LL | | } else {
+LL | | return;
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let Some(v_some) = g().map(|v| (v, 42)) else {
+LL + return;
+LL + };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:125:5
+ |
+LL | / let v = if let (Some(v_some), w_some) = (g(), 0) {
+LL | | (w_some, v_some)
+LL | | } else {
+LL | | return;
+LL | | };
+ | |______^
+ |
+help: consider writing
+ |
+LL ~ let (Some(v_some), w_some) = (g(), 0) else {
+LL + return;
+LL + };
+ |
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else.rs:134:13
+ |
+LL | let $n = if let Some(v) = $e { v } else { return };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };`
+...
+LL | create_binding_if_some!(w, g());
+ | ------------------------------- in this macro invocation
+ |
+ = 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:247:5
+ |
+LL | / let _ = match ff {
+LL | | Some(value) => value,
+LL | | _ => macro_call!(),
+LL | | };
+ | |______^ help: consider writing: `let Some(value) = ff else { macro_call!() };`
+
+error: aborting due to 18 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.rs b/src/tools/clippy/tests/ui/manual_let_else_match.rs
new file mode 100644
index 000000000..93c86ca24
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.rs
@@ -0,0 +1,121 @@
+#![allow(unused_braces, unused_variables, dead_code)]
+#![allow(clippy::collapsible_else_if, clippy::let_unit_value)]
+#![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 v = match g() {
+ Some(v_some) => v_some,
+ None => return,
+ };
+
+ let v = match g() {
+ Some(v_some) => v_some,
+ _ => return,
+ };
+
+ loop {
+ // More complex pattern for the identity arm and diverging arm
+ let v = match h() {
+ (Some(_), Some(_)) | (None, None) => continue,
+ (Some(v), None) | (None, Some(v)) => v,
+ };
+ // Custom enums are supported as long as the "else" arm is a simple _
+ let v = match build_enum() {
+ _ => continue,
+ Variant::Bar(v) | Variant::Baz(v) => v,
+ };
+ }
+
+ // There is a _ in the diverging arm
+ // TODO also support unused bindings aka _v
+ let v = match f() {
+ Ok(v) => v,
+ Err(_) => return,
+ };
+
+ // Err(()) is an allowed pattern
+ let v = match f().map_err(|_| ()) {
+ Ok(v) => v,
+ Err(()) => 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,
+ };
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.stderr b/src/tools/clippy/tests/ui/manual_let_else_match.stderr
new file mode 100644
index 000000000..38be5ac54
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.stderr
@@ -0,0 +1,58 @@
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else_match.rs:32:5
+ |
+LL | / let v = match g() {
+LL | | Some(v_some) => v_some,
+LL | | None => return,
+LL | | };
+ | |______^ help: consider writing: `let Some(v_some) = g() else { return };`
+ |
+ = note: `-D clippy::manual-let-else` implied by `-D warnings`
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else_match.rs:37:5
+ |
+LL | / let v = match g() {
+LL | | Some(v_some) => v_some,
+LL | | _ => return,
+LL | | };
+ | |______^ help: consider writing: `let Some(v_some) = g() else { return };`
+
+error: this could be rewritten as `let...else`
+ --> $DIR/manual_let_else_match.rs:44:9
+ |
+LL | / let v = match h() {
+LL | | (Some(_), Some(_)) | (None, None) => continue,
+LL | | (Some(v), None) | (None, Some(v)) => v,
+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:49:9
+ |
+LL | / let v = match build_enum() {
+LL | | _ => continue,
+LL | | Variant::Bar(v) | Variant::Baz(v) => v,
+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:57:5
+ |
+LL | / let v = match f() {
+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:63:5
+ |
+LL | / let v = match f().map_err(|_| ()) {
+LL | | Ok(v) => v,
+LL | | Err(()) => return,
+LL | | };
+ | |______^ help: consider writing: `let Ok(v) = f().map_err(|_| ()) else { return };`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_ok_or.fixed b/src/tools/clippy/tests/ui/manual_ok_or.fixed
index d864f8554..fc8511626 100644
--- a/src/tools/clippy/tests/ui/manual_ok_or.fixed
+++ b/src/tools/clippy/tests/ui/manual_ok_or.fixed
@@ -1,5 +1,6 @@
// run-rustfix
#![warn(clippy::manual_ok_or)]
+#![allow(clippy::or_fun_call)]
#![allow(clippy::disallowed_names)]
#![allow(clippy::redundant_closure)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/manual_ok_or.rs b/src/tools/clippy/tests/ui/manual_ok_or.rs
index 626476846..b5303d33f 100644
--- a/src/tools/clippy/tests/ui/manual_ok_or.rs
+++ b/src/tools/clippy/tests/ui/manual_ok_or.rs
@@ -1,5 +1,6 @@
// run-rustfix
#![warn(clippy::manual_ok_or)]
+#![allow(clippy::or_fun_call)]
#![allow(clippy::disallowed_names)]
#![allow(clippy::redundant_closure)]
#![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/manual_ok_or.stderr b/src/tools/clippy/tests/ui/manual_ok_or.stderr
index 65459a097..b4a17f143 100644
--- a/src/tools/clippy/tests/ui/manual_ok_or.stderr
+++ b/src/tools/clippy/tests/ui/manual_ok_or.stderr
@@ -1,5 +1,5 @@
error: this pattern reimplements `Option::ok_or`
- --> $DIR/manual_ok_or.rs:11:5
+ --> $DIR/manual_ok_or.rs:12:5
|
LL | foo.map_or(Err("error"), |v| Ok(v));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or("error")`
@@ -7,19 +7,19 @@ LL | foo.map_or(Err("error"), |v| Ok(v));
= note: `-D clippy::manual-ok-or` implied by `-D warnings`
error: this pattern reimplements `Option::ok_or`
- --> $DIR/manual_ok_or.rs:14:5
+ --> $DIR/manual_ok_or.rs:15: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:17:5
+ --> $DIR/manual_ok_or.rs:18: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:21:5
+ --> $DIR/manual_ok_or.rs:22:5
|
LL | / foo.map_or(Err::<i32, &str>(
LL | | &format!(
diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.fixed b/src/tools/clippy/tests/ui/manual_rem_euclid.fixed
index b942fbfe9..4cdc0546a 100644
--- a/src/tools/clippy/tests/ui/manual_rem_euclid.fixed
+++ b/src/tools/clippy/tests/ui/manual_rem_euclid.fixed
@@ -1,7 +1,6 @@
// run-rustfix
// aux-build:macro_rules.rs
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_rem_euclid)]
#[macro_use]
@@ -55,31 +54,27 @@ pub const fn const_rem_euclid_4(num: i32) -> i32 {
num.rem_euclid(4)
}
+#[clippy::msrv = "1.37"]
pub fn msrv_1_37() {
- #![clippy::msrv = "1.37"]
-
let x: i32 = 10;
let _: i32 = ((x % 4) + 4) % 4;
}
+#[clippy::msrv = "1.38"]
pub fn msrv_1_38() {
- #![clippy::msrv = "1.38"]
-
let x: i32 = 10;
let _: i32 = x.rem_euclid(4);
}
// For const fns:
+#[clippy::msrv = "1.51"]
pub const fn msrv_1_51() {
- #![clippy::msrv = "1.51"]
-
let x: i32 = 10;
let _: i32 = ((x % 4) + 4) % 4;
}
+#[clippy::msrv = "1.52"]
pub const fn msrv_1_52() {
- #![clippy::msrv = "1.52"]
-
let x: i32 = 10;
let _: i32 = x.rem_euclid(4);
}
diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.rs b/src/tools/clippy/tests/ui/manual_rem_euclid.rs
index 7462d5321..58a9e20f3 100644
--- a/src/tools/clippy/tests/ui/manual_rem_euclid.rs
+++ b/src/tools/clippy/tests/ui/manual_rem_euclid.rs
@@ -1,7 +1,6 @@
// run-rustfix
// aux-build:macro_rules.rs
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_rem_euclid)]
#[macro_use]
@@ -55,31 +54,27 @@ pub const fn const_rem_euclid_4(num: i32) -> i32 {
((num % 4) + 4) % 4
}
+#[clippy::msrv = "1.37"]
pub fn msrv_1_37() {
- #![clippy::msrv = "1.37"]
-
let x: i32 = 10;
let _: i32 = ((x % 4) + 4) % 4;
}
+#[clippy::msrv = "1.38"]
pub fn msrv_1_38() {
- #![clippy::msrv = "1.38"]
-
let x: i32 = 10;
let _: i32 = ((x % 4) + 4) % 4;
}
// For const fns:
+#[clippy::msrv = "1.51"]
pub const fn msrv_1_51() {
- #![clippy::msrv = "1.51"]
-
let x: i32 = 10;
let _: i32 = ((x % 4) + 4) % 4;
}
+#[clippy::msrv = "1.52"]
pub const fn msrv_1_52() {
- #![clippy::msrv = "1.52"]
-
let x: i32 = 10;
let _: i32 = ((x % 4) + 4) % 4;
}
diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.stderr b/src/tools/clippy/tests/ui/manual_rem_euclid.stderr
index d51bac03b..e3122a588 100644
--- a/src/tools/clippy/tests/ui/manual_rem_euclid.stderr
+++ b/src/tools/clippy/tests/ui/manual_rem_euclid.stderr
@@ -1,5 +1,5 @@
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:20:18
+ --> $DIR/manual_rem_euclid.rs:19:18
|
LL | let _: i32 = ((value % 4) + 4) % 4;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
@@ -7,31 +7,31 @@ LL | let _: i32 = ((value % 4) + 4) % 4;
= note: `-D clippy::manual-rem-euclid` implied by `-D warnings`
error: manual `rem_euclid` implementation
- --> $DIR/manual_rem_euclid.rs:21:18
+ --> $DIR/manual_rem_euclid.rs:20: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:22:18
+ --> $DIR/manual_rem_euclid.rs:21: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:23:18
+ --> $DIR/manual_rem_euclid.rs:22: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:24:22
+ --> $DIR/manual_rem_euclid.rs:23: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:13:22
+ --> $DIR/manual_rem_euclid.rs:12:22
|
LL | let _: i32 = ((value % 4) + 4) % 4;
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`
@@ -42,25 +42,25 @@ LL | internal_rem_euclid!();
= note: this error originates in the macro `internal_rem_euclid` (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:69: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:84: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 fba503a20..e5ae3cf3e 100644
--- a/src/tools/clippy/tests/ui/manual_retain.fixed
+++ b/src/tools/clippy/tests/ui/manual_retain.fixed
@@ -1,5 +1,4 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_retain)]
#![allow(unused)]
use std::collections::BTreeMap;
@@ -216,8 +215,8 @@ fn vec_deque_retain() {
bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
}
+#[clippy::msrv = "1.52"]
fn _msrv_153() {
- #![clippy::msrv = "1.52"]
let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
@@ -225,14 +224,14 @@ fn _msrv_153() {
btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
}
+#[clippy::msrv = "1.25"]
fn _msrv_126() {
- #![clippy::msrv = "1.25"]
let mut s = String::from("foobar");
s = s.chars().filter(|&c| c != 'o').to_owned().collect();
}
+#[clippy::msrv = "1.17"]
fn _msrv_118() {
- #![clippy::msrv = "1.17"]
let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]);
hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
let mut hash_map: HashMap<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 81a849fe7..1021f15ed 100644
--- a/src/tools/clippy/tests/ui/manual_retain.rs
+++ b/src/tools/clippy/tests/ui/manual_retain.rs
@@ -1,5 +1,4 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_retain)]
#![allow(unused)]
use std::collections::BTreeMap;
@@ -222,8 +221,8 @@ fn vec_deque_retain() {
bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();
}
+#[clippy::msrv = "1.52"]
fn _msrv_153() {
- #![clippy::msrv = "1.52"]
let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
@@ -231,14 +230,14 @@ fn _msrv_153() {
btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
}
+#[clippy::msrv = "1.25"]
fn _msrv_126() {
- #![clippy::msrv = "1.25"]
let mut s = String::from("foobar");
s = s.chars().filter(|&c| c != 'o').to_owned().collect();
}
+#[clippy::msrv = "1.17"]
fn _msrv_118() {
- #![clippy::msrv = "1.17"]
let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]);
hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
let mut hash_map: HashMap<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 ec635919b..89316ce1d 100644
--- a/src/tools/clippy/tests/ui/manual_retain.stderr
+++ b/src/tools/clippy/tests/ui/manual_retain.stderr
@@ -1,5 +1,5 @@
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:52:5
+ --> $DIR/manual_retain.rs:51: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)`
@@ -7,13 +7,13 @@ LL | btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect()
= note: `-D clippy::manual-retain` implied by `-D warnings`
error: this expression can be written more simply using `.retain()`
- --> $DIR/manual_retain.rs:53:5
+ --> $DIR/manual_retain.rs:52: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:54:5
+ --> $DIR/manual_retain.rs:53:5
|
LL | / btree_map = btree_map
LL | | .into_iter()
@@ -22,37 +22,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:76:5
+ --> $DIR/manual_retain.rs:75: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:77:5
+ --> $DIR/manual_retain.rs:76: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:78:5
+ --> $DIR/manual_retain.rs:77: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:108:5
+ --> $DIR/manual_retain.rs:107: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:109:5
+ --> $DIR/manual_retain.rs:108: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:110:5
+ --> $DIR/manual_retain.rs:109:5
|
LL | / hash_map = hash_map
LL | | .into_iter()
@@ -61,61 +61,61 @@ 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:131:5
+ --> $DIR/manual_retain.rs:130: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:132:5
+ --> $DIR/manual_retain.rs:131: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:133:5
+ --> $DIR/manual_retain.rs:132: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:162:5
+ --> $DIR/manual_retain.rs:161: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:174:5
+ --> $DIR/manual_retain.rs:173: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:175:5
+ --> $DIR/manual_retain.rs:174: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:176:5
+ --> $DIR/manual_retain.rs:175: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:198:5
+ --> $DIR/manual_retain.rs:197: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:199:5
+ --> $DIR/manual_retain.rs:198: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:200:5
+ --> $DIR/manual_retain.rs:199: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)`
diff --git a/src/tools/clippy/tests/ui/manual_split_once.fixed b/src/tools/clippy/tests/ui/manual_split_once.fixed
index c7ca77043..50b02019c 100644
--- a/src/tools/clippy/tests/ui/manual_split_once.fixed
+++ b/src/tools/clippy/tests/ui/manual_split_once.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_split_once)]
#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
@@ -127,8 +126,8 @@ fn indirect() -> Option<()> {
None
}
+#[clippy::msrv = "1.51"]
fn _msrv_1_51() {
- #![clippy::msrv = "1.51"]
// `str::split_once` was stabilized in 1.52. Do not lint this
let _ = "key=value".splitn(2, '=').nth(1).unwrap();
@@ -137,8 +136,8 @@ fn _msrv_1_51() {
let b = iter.next().unwrap();
}
+#[clippy::msrv = "1.52"]
fn _msrv_1_52() {
- #![clippy::msrv = "1.52"]
let _ = "key=value".split_once('=').unwrap().1;
let (a, b) = "a.b.c".split_once('.').unwrap();
diff --git a/src/tools/clippy/tests/ui/manual_split_once.rs b/src/tools/clippy/tests/ui/manual_split_once.rs
index ee2848a25..e1e8b71a9 100644
--- a/src/tools/clippy/tests/ui/manual_split_once.rs
+++ b/src/tools/clippy/tests/ui/manual_split_once.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_split_once)]
#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
@@ -127,8 +126,8 @@ fn indirect() -> Option<()> {
None
}
+#[clippy::msrv = "1.51"]
fn _msrv_1_51() {
- #![clippy::msrv = "1.51"]
// `str::split_once` was stabilized in 1.52. Do not lint this
let _ = "key=value".splitn(2, '=').nth(1).unwrap();
@@ -137,8 +136,8 @@ fn _msrv_1_51() {
let b = iter.next().unwrap();
}
+#[clippy::msrv = "1.52"]
fn _msrv_1_52() {
- #![clippy::msrv = "1.52"]
let _ = "key=value".splitn(2, '=').nth(1).unwrap();
let mut iter = "a.b.c".splitn(2, '.');
diff --git a/src/tools/clippy/tests/ui/manual_split_once.stderr b/src/tools/clippy/tests/ui/manual_split_once.stderr
index 269669468..78da5a16c 100644
--- a/src/tools/clippy/tests/ui/manual_split_once.stderr
+++ b/src/tools/clippy/tests/ui/manual_split_once.stderr
@@ -1,5 +1,5 @@
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:14:13
+ --> $DIR/manual_split_once.rs:13:13
|
LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').unwrap().1`
@@ -7,79 +7,79 @@ LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
= note: `-D clippy::manual-split-once` implied by `-D warnings`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:15:13
+ --> $DIR/manual_split_once.rs:14:13
|
LL | let _ = "key=value".splitn(2, '=').skip(1).next().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').unwrap().1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:16:18
+ --> $DIR/manual_split_once.rs:15:18
|
LL | let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=')`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:19:13
+ --> $DIR/manual_split_once.rs:18:13
|
LL | let _ = s.splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').unwrap().1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:22:13
+ --> $DIR/manual_split_once.rs:21:13
|
LL | let _ = s.splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').unwrap().1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:25:13
+ --> $DIR/manual_split_once.rs:24:13
|
LL | let _ = s.splitn(2, '=').skip(1).next().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').unwrap().1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:28:17
+ --> $DIR/manual_split_once.rs:27:17
|
LL | let _ = s.splitn(2, '=').nth(1)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=')?.1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:29:17
+ --> $DIR/manual_split_once.rs:28:17
|
LL | let _ = s.splitn(2, '=').skip(1).next()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=')?.1`
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:30:17
+ --> $DIR/manual_split_once.rs:29:17
|
LL | let _ = s.rsplitn(2, '=').nth(1)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit_once('=')?.0`
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:31:17
+ --> $DIR/manual_split_once.rs:30:17
|
LL | let _ = s.rsplitn(2, '=').skip(1).next()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit_once('=')?.0`
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:39:13
+ --> $DIR/manual_split_once.rs:38:13
|
LL | let _ = "key=value".rsplitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".rsplit_once('=').unwrap().0`
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:40:18
+ --> $DIR/manual_split_once.rs:39:18
|
LL | let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))`
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:41:13
+ --> $DIR/manual_split_once.rs:40:13
|
LL | let _ = s.rsplitn(2, '=').nth(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit_once('=').map(|x| x.0)`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:45:5
+ --> $DIR/manual_split_once.rs:44:5
|
LL | let mut iter = "a.b.c".splitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -104,7 +104,7 @@ LL +
|
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:49:5
+ --> $DIR/manual_split_once.rs:48:5
|
LL | let mut iter = "a.b.c".splitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,7 +129,7 @@ LL +
|
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:53:5
+ --> $DIR/manual_split_once.rs:52:5
|
LL | let mut iter = "a.b.c".rsplitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,7 +154,7 @@ LL +
|
error: manual implementation of `rsplit_once`
- --> $DIR/manual_split_once.rs:57:5
+ --> $DIR/manual_split_once.rs:56:5
|
LL | let mut iter = "a.b.c".rsplitn(2, '.');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -179,13 +179,13 @@ LL +
|
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:142:13
+ --> $DIR/manual_split_once.rs:141:13
|
LL | let _ = "key=value".splitn(2, '=').nth(1).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').unwrap().1`
error: manual implementation of `split_once`
- --> $DIR/manual_split_once.rs:144:5
+ --> $DIR/manual_split_once.rs:143: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 0704ba2f9..3d56f2a0d 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.fixed
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_str_repeat)]
use std::borrow::Cow;
@@ -54,13 +53,13 @@ fn main() {
let _: String = repeat(x).take(count).collect();
}
+#[clippy::msrv = "1.15"]
fn _msrv_1_15() {
- #![clippy::msrv = "1.15"]
// `str::repeat` was stabilized in 1.16. Do not lint this
let _: String = std::iter::repeat("test").take(10).collect();
}
+#[clippy::msrv = "1.16"]
fn _msrv_1_16() {
- #![clippy::msrv = "1.16"]
let _: String = "test".repeat(10);
}
diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.rs b/src/tools/clippy/tests/ui/manual_str_repeat.rs
index f522be439..e8240a949 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.rs
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_str_repeat)]
use std::borrow::Cow;
@@ -54,13 +53,13 @@ fn main() {
let _: String = repeat(x).take(count).collect();
}
+#[clippy::msrv = "1.15"]
fn _msrv_1_15() {
- #![clippy::msrv = "1.15"]
// `str::repeat` was stabilized in 1.16. Do not lint this
let _: String = std::iter::repeat("test").take(10).collect();
}
+#[clippy::msrv = "1.16"]
fn _msrv_1_16() {
- #![clippy::msrv = "1.16"]
let _: String = std::iter::repeat("test").take(10).collect();
}
diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.stderr b/src/tools/clippy/tests/ui/manual_str_repeat.stderr
index c65116897..bdfee7cab 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.stderr
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.stderr
@@ -1,5 +1,5 @@
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:10:21
+ --> $DIR/manual_str_repeat.rs:9:21
|
LL | let _: String = std::iter::repeat("test").take(10).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"test".repeat(10)`
@@ -7,55 +7,55 @@ LL | let _: String = std::iter::repeat("test").take(10).collect();
= note: `-D clippy::manual-str-repeat` implied by `-D warnings`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:11:21
+ --> $DIR/manual_str_repeat.rs:10:21
|
LL | let _: String = std::iter::repeat('x').take(10).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"x".repeat(10)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:12:21
+ --> $DIR/manual_str_repeat.rs:11:21
|
LL | let _: String = std::iter::repeat('/'').take(10).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"'".repeat(10)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:13:21
+ --> $DIR/manual_str_repeat.rs:12:21
|
LL | let _: String = std::iter::repeat('"').take(10).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"/"".repeat(10)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:17:13
+ --> $DIR/manual_str_repeat.rs:16:13
|
LL | let _ = repeat(x).take(count + 2).collect::<String>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `x.repeat(count + 2)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:26:21
+ --> $DIR/manual_str_repeat.rs:25:21
|
LL | let _: String = repeat(*x).take(count).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `(*x).repeat(count)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:35:21
+ --> $DIR/manual_str_repeat.rs:34:21
|
LL | let _: String = repeat(x).take(count).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `x.repeat(count)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:47:21
+ --> $DIR/manual_str_repeat.rs:46:21
|
LL | let _: String = repeat(Cow::Borrowed("test")).take(count).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Cow::Borrowed("test").repeat(count)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:50:21
+ --> $DIR/manual_str_repeat.rs:49:21
|
LL | let _: String = repeat(x).take(count).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `x.repeat(count)`
error: manual implementation of `str::repeat` using iterators
- --> $DIR/manual_str_repeat.rs:65:21
+ --> $DIR/manual_str_repeat.rs:64:21
|
LL | let _: String = std::iter::repeat("test").take(10).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"test".repeat(10)`
diff --git a/src/tools/clippy/tests/ui/manual_strip.rs b/src/tools/clippy/tests/ui/manual_strip.rs
index 85009d785..b0b1c262a 100644
--- a/src/tools/clippy/tests/ui/manual_strip.rs
+++ b/src/tools/clippy/tests/ui/manual_strip.rs
@@ -1,4 +1,3 @@
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_strip)]
fn main() {
@@ -66,18 +65,16 @@ fn main() {
}
}
+#[clippy::msrv = "1.44"]
fn msrv_1_44() {
- #![clippy::msrv = "1.44"]
-
let s = "abc";
if s.starts_with('a') {
s[1..].to_string();
}
}
+#[clippy::msrv = "1.45"]
fn msrv_1_45() {
- #![clippy::msrv = "1.45"]
-
let s = "abc";
if s.starts_with('a') {
s[1..].to_string();
diff --git a/src/tools/clippy/tests/ui/manual_strip.stderr b/src/tools/clippy/tests/ui/manual_strip.stderr
index ad2a362f3..f592e898f 100644
--- a/src/tools/clippy/tests/ui/manual_strip.stderr
+++ b/src/tools/clippy/tests/ui/manual_strip.stderr
@@ -1,11 +1,11 @@
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:8:24
+ --> $DIR/manual_strip.rs:7:24
|
LL | str::to_string(&s["ab".len()..]);
| ^^^^^^^^^^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:7:5
+ --> $DIR/manual_strip.rs:6:5
|
LL | if s.starts_with("ab") {
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -21,13 +21,13 @@ LL ~ <stripped>.to_string();
|
error: stripping a suffix manually
- --> $DIR/manual_strip.rs:16:24
+ --> $DIR/manual_strip.rs:15:24
|
LL | str::to_string(&s[..s.len() - "bc".len()]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the suffix was tested here
- --> $DIR/manual_strip.rs:15:5
+ --> $DIR/manual_strip.rs:14:5
|
LL | if s.ends_with("bc") {
| ^^^^^^^^^^^^^^^^^^^^^
@@ -42,13 +42,13 @@ LL ~ <stripped>.to_string();
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:25:24
+ --> $DIR/manual_strip.rs:24:24
|
LL | str::to_string(&s[1..]);
| ^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:24:5
+ --> $DIR/manual_strip.rs:23:5
|
LL | if s.starts_with('a') {
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -60,13 +60,13 @@ LL ~ <stripped>.to_string();
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:32:24
+ --> $DIR/manual_strip.rs:31:24
|
LL | str::to_string(&s[prefix.len()..]);
| ^^^^^^^^^^^^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:31:5
+ --> $DIR/manual_strip.rs:30:5
|
LL | if s.starts_with(prefix) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -77,13 +77,13 @@ LL ~ str::to_string(<stripped>);
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:38:24
+ --> $DIR/manual_strip.rs:37:24
|
LL | str::to_string(&s[PREFIX.len()..]);
| ^^^^^^^^^^^^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:37:5
+ --> $DIR/manual_strip.rs:36:5
|
LL | if s.starts_with(PREFIX) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -95,13 +95,13 @@ LL ~ str::to_string(<stripped>);
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:45:24
+ --> $DIR/manual_strip.rs:44:24
|
LL | str::to_string(&TARGET[prefix.len()..]);
| ^^^^^^^^^^^^^^^^^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:44:5
+ --> $DIR/manual_strip.rs:43:5
|
LL | if TARGET.starts_with(prefix) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -112,13 +112,13 @@ LL ~ str::to_string(<stripped>);
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:51:9
+ --> $DIR/manual_strip.rs:50:9
|
LL | s1[2..].to_uppercase();
| ^^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:50:5
+ --> $DIR/manual_strip.rs:49:5
|
LL | if s1.starts_with("ab") {
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,13 +129,13 @@ LL ~ <stripped>.to_uppercase();
|
error: stripping a prefix manually
- --> $DIR/manual_strip.rs:83:9
+ --> $DIR/manual_strip.rs:80:9
|
LL | s[1..].to_string();
| ^^^^^^
|
note: the prefix was tested here
- --> $DIR/manual_strip.rs:82:5
+ --> $DIR/manual_strip.rs:79:5
|
LL | if s.starts_with('a') {
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
index 312819a0a..53628ef65 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
@@ -1,7 +1,6 @@
// run-rustfix
#![warn(clippy::all, clippy::pedantic)]
-#![allow(clippy::let_underscore_drop)]
#![allow(clippy::missing_docs_in_private_items)]
#![allow(clippy::map_identity)]
#![allow(clippy::redundant_closure)]
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.rs b/src/tools/clippy/tests/ui/map_flatten_fixable.rs
index 3fbf4f9a1..76016c8ed 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.rs
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.rs
@@ -1,7 +1,6 @@
// run-rustfix
#![warn(clippy::all, clippy::pedantic)]
-#![allow(clippy::let_underscore_drop)]
#![allow(clippy::missing_docs_in_private_items)]
#![allow(clippy::map_identity)]
#![allow(clippy::redundant_closure)]
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
index c91f0b9ae..b6b0c4d09 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
@@ -1,5 +1,5 @@
error: called `map(..).flatten()` on `Iterator`
- --> $DIR/map_flatten_fixable.rs:18:47
+ --> $DIR/map_flatten_fixable.rs:17: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)`
@@ -7,43 +7,43 @@ LL | let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().coll
= note: `-D clippy::map-flatten` implied by `-D warnings`
error: called `map(..).flatten()` on `Iterator`
- --> $DIR/map_flatten_fixable.rs:19:47
+ --> $DIR/map_flatten_fixable.rs:18: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:19: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:20: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:23: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:26: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:29: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:38:10
|
LL | .map(|n| match n {
| __________^
@@ -72,7 +72,7 @@ LL ~ });
|
error: called `map(..).flatten()` on `Option`
- --> $DIR/map_flatten_fixable.rs:59:10
+ --> $DIR/map_flatten_fixable.rs:58:10
|
LL | .map(|_| {
| __________^
diff --git a/src/tools/clippy/tests/ui/map_unwrap_or.rs b/src/tools/clippy/tests/ui/map_unwrap_or.rs
index 396b22a9a..32631024c 100644
--- a/src/tools/clippy/tests/ui/map_unwrap_or.rs
+++ b/src/tools/clippy/tests/ui/map_unwrap_or.rs
@@ -1,6 +1,5 @@
// aux-build:option_helpers.rs
-#![feature(custom_inner_attributes)]
#![warn(clippy::map_unwrap_or)]
#![allow(clippy::uninlined_format_args, clippy::unnecessary_lazy_evaluations)]
@@ -82,17 +81,15 @@ fn main() {
result_methods();
}
+#[clippy::msrv = "1.40"]
fn msrv_1_40() {
- #![clippy::msrv = "1.40"]
-
let res: Result<i32, ()> = Ok(1);
let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0);
}
+#[clippy::msrv = "1.41"]
fn msrv_1_41() {
- #![clippy::msrv = "1.41"]
-
let res: Result<i32, ()> = Ok(1);
let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0);
diff --git a/src/tools/clippy/tests/ui/map_unwrap_or.stderr b/src/tools/clippy/tests/ui/map_unwrap_or.stderr
index d17d24a40..41781b050 100644
--- a/src/tools/clippy/tests/ui/map_unwrap_or.stderr
+++ b/src/tools/clippy/tests/ui/map_unwrap_or.stderr
@@ -1,5 +1,5 @@
error: called `map(<f>).unwrap_or(<a>)` on an `Option` value. This can be done more directly by calling `map_or(<a>, <f>)` instead
- --> $DIR/map_unwrap_or.rs:18:13
+ --> $DIR/map_unwrap_or.rs:17:13
|
LL | let _ = opt.map(|x| x + 1)
| _____________^
@@ -15,7 +15,7 @@ LL + let _ = opt.map_or(0, |x| x + 1);
|
error: called `map(<f>).unwrap_or(<a>)` on an `Option` value. This can be done more directly by calling `map_or(<a>, <f>)` instead
- --> $DIR/map_unwrap_or.rs:22:13
+ --> $DIR/map_unwrap_or.rs:21:13
|
LL | let _ = opt.map(|x| {
| _____________^
@@ -33,7 +33,7 @@ LL ~ );
|
error: called `map(<f>).unwrap_or(<a>)` on an `Option` value. This can be done more directly by calling `map_or(<a>, <f>)` instead
- --> $DIR/map_unwrap_or.rs:26:13
+ --> $DIR/map_unwrap_or.rs:25:13
|
LL | let _ = opt.map(|x| x + 1)
| _____________^
@@ -50,7 +50,7 @@ LL ~ }, |x| x + 1);
|
error: called `map(<f>).unwrap_or(None)` on an `Option` value. This can be done more directly by calling `and_then(<f>)` instead
- --> $DIR/map_unwrap_or.rs:31:13
+ --> $DIR/map_unwrap_or.rs:30:13
|
LL | let _ = opt.map(|x| Some(x + 1)).unwrap_or(None);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -62,7 +62,7 @@ LL + let _ = opt.and_then(|x| Some(x + 1));
|
error: called `map(<f>).unwrap_or(None)` on an `Option` value. This can be done more directly by calling `and_then(<f>)` instead
- --> $DIR/map_unwrap_or.rs:33:13
+ --> $DIR/map_unwrap_or.rs:32:13
|
LL | let _ = opt.map(|x| {
| _____________^
@@ -80,7 +80,7 @@ LL ~ );
|
error: called `map(<f>).unwrap_or(None)` on an `Option` value. This can be done more directly by calling `and_then(<f>)` instead
- --> $DIR/map_unwrap_or.rs:37:13
+ --> $DIR/map_unwrap_or.rs:36:13
|
LL | let _ = opt
| _____________^
@@ -95,7 +95,7 @@ LL + .and_then(|x| Some(x + 1));
|
error: called `map(<f>).unwrap_or(<a>)` on an `Option` value. This can be done more directly by calling `map_or(<a>, <f>)` instead
- --> $DIR/map_unwrap_or.rs:48:13
+ --> $DIR/map_unwrap_or.rs:47:13
|
LL | let _ = Some("prefix").map(|p| format!("{}.", p)).unwrap_or(id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -107,7 +107,7 @@ LL + let _ = Some("prefix").map_or(id, |p| format!("{}.", p));
|
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.rs:52:13
+ --> $DIR/map_unwrap_or.rs:51:13
|
LL | let _ = opt.map(|x| {
| _____________^
@@ -117,7 +117,7 @@ LL | | ).unwrap_or_else(|| 0);
| |__________________________^
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.rs:56:13
+ --> $DIR/map_unwrap_or.rs:55:13
|
LL | let _ = opt.map(|x| x + 1)
| _____________^
@@ -127,7 +127,7 @@ LL | | );
| |_________^
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.rs:68:13
+ --> $DIR/map_unwrap_or.rs:67:13
|
LL | let _ = res.map(|x| {
| _____________^
@@ -137,7 +137,7 @@ LL | | ).unwrap_or_else(|_e| 0);
| |____________________________^
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.rs:72:13
+ --> $DIR/map_unwrap_or.rs:71:13
|
LL | let _ = res.map(|x| x + 1)
| _____________^
@@ -147,7 +147,7 @@ LL | | });
| |__________^
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.rs:98:13
+ --> $DIR/map_unwrap_or.rs:95:13
|
LL | let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `res.map_or_else(|_e| 0, |x| x + 1)`
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 249800769..55cd15bd5 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,8 +1,12 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::match_like_matches_macro)]
-#![allow(unreachable_patterns, dead_code, clippy::equatable_if_let)]
+#![allow(
+ unreachable_patterns,
+ dead_code,
+ clippy::equatable_if_let,
+ clippy::needless_borrowed_reference
+)]
fn main() {
let x = Some(5);
@@ -195,17 +199,15 @@ fn main() {
};
}
+#[clippy::msrv = "1.41"]
fn msrv_1_41() {
- #![clippy::msrv = "1.41"]
-
let _y = match Some(5) {
Some(0) => true,
_ => false,
};
}
+#[clippy::msrv = "1.42"]
fn msrv_1_42() {
- #![clippy::msrv = "1.42"]
-
let _y = matches!(Some(5), Some(0));
}
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 b4e48499b..5d645e108 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,8 +1,12 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::match_like_matches_macro)]
-#![allow(unreachable_patterns, dead_code, clippy::equatable_if_let)]
+#![allow(
+ unreachable_patterns,
+ dead_code,
+ clippy::equatable_if_let,
+ clippy::needless_borrowed_reference
+)]
fn main() {
let x = Some(5);
@@ -236,18 +240,16 @@ fn main() {
};
}
+#[clippy::msrv = "1.41"]
fn msrv_1_41() {
- #![clippy::msrv = "1.41"]
-
let _y = match Some(5) {
Some(0) => true,
_ => false,
};
}
+#[clippy::msrv = "1.42"]
fn msrv_1_42() {
- #![clippy::msrv = "1.42"]
-
let _y = match Some(5) {
Some(0) => true,
_ => false,
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 f1d1c23ae..46f67ef49 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:11:14
+ --> $DIR/match_expr_like_matches_macro.rs:15:14
|
LL | let _y = match x {
| ______________^
@@ -11,7 +11,7 @@ LL | | };
= note: `-D clippy::match-like-matches-macro` implied by `-D warnings`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:17:14
+ --> $DIR/match_expr_like_matches_macro.rs:21:14
|
LL | let _w = match x {
| ______________^
@@ -21,7 +21,7 @@ LL | | };
| |_____^ help: try this: `matches!(x, Some(_))`
error: redundant pattern matching, consider using `is_none()`
- --> $DIR/match_expr_like_matches_macro.rs:23:14
+ --> $DIR/match_expr_like_matches_macro.rs:27:14
|
LL | let _z = match x {
| ______________^
@@ -33,7 +33,7 @@ LL | | };
= note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:29:15
+ --> $DIR/match_expr_like_matches_macro.rs:33:15
|
LL | let _zz = match x {
| _______________^
@@ -43,13 +43,13 @@ LL | | };
| |_____^ help: try this: `!matches!(x, Some(r) if r == 0)`
error: if let .. else expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:35:16
+ --> $DIR/match_expr_like_matches_macro.rs:39:16
|
LL | let _zzz = if let Some(5) = x { true } else { false };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `matches!(x, Some(5))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:59:20
+ --> $DIR/match_expr_like_matches_macro.rs:63:20
|
LL | let _ans = match x {
| ____________________^
@@ -60,7 +60,7 @@ LL | | };
| |_________^ help: try this: `matches!(x, E::A(_) | E::B(_))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:69:20
+ --> $DIR/match_expr_like_matches_macro.rs:73:20
|
LL | let _ans = match x {
| ____________________^
@@ -73,7 +73,7 @@ LL | | };
| |_________^ help: try this: `matches!(x, E::A(_) | E::B(_))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:79:20
+ --> $DIR/match_expr_like_matches_macro.rs:83:20
|
LL | let _ans = match x {
| ____________________^
@@ -84,7 +84,7 @@ LL | | };
| |_________^ help: try this: `!matches!(x, E::B(_) | E::C)`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:139:18
+ --> $DIR/match_expr_like_matches_macro.rs:143:18
|
LL | let _z = match &z {
| __________________^
@@ -94,7 +94,7 @@ LL | | };
| |_________^ help: try this: `matches!(z, Some(3))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:148:18
+ --> $DIR/match_expr_like_matches_macro.rs:152:18
|
LL | let _z = match &z {
| __________________^
@@ -104,7 +104,7 @@ LL | | };
| |_________^ help: try this: `matches!(&z, Some(3))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:165:21
+ --> $DIR/match_expr_like_matches_macro.rs:169:21
|
LL | let _ = match &z {
| _____________________^
@@ -114,7 +114,7 @@ LL | | };
| |_____________^ help: try this: `matches!(&z, AnEnum::X)`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:179:20
+ --> $DIR/match_expr_like_matches_macro.rs:183:20
|
LL | let _res = match &val {
| ____________________^
@@ -124,7 +124,7 @@ LL | | };
| |_________^ help: try this: `matches!(&val, &Some(ref _a))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:191:20
+ --> $DIR/match_expr_like_matches_macro.rs:195:20
|
LL | let _res = match &val {
| ____________________^
@@ -134,7 +134,7 @@ LL | | };
| |_________^ help: try this: `matches!(&val, &Some(ref _a))`
error: match expression looks like `matches!` macro
- --> $DIR/match_expr_like_matches_macro.rs:251:14
+ --> $DIR/match_expr_like_matches_macro.rs:253:14
|
LL | let _y = match Some(5) {
| ______________^
diff --git a/src/tools/clippy/tests/ui/mem_replace.fixed b/src/tools/clippy/tests/ui/mem_replace.fixed
index ae237395b..874d55843 100644
--- a/src/tools/clippy/tests/ui/mem_replace.fixed
+++ b/src/tools/clippy/tests/ui/mem_replace.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(unused)]
#![warn(
clippy::all,
@@ -80,16 +79,14 @@ fn main() {
dont_lint_primitive();
}
+#[clippy::msrv = "1.39"]
fn msrv_1_39() {
- #![clippy::msrv = "1.39"]
-
let mut s = String::from("foo");
let _ = std::mem::replace(&mut s, String::default());
}
+#[clippy::msrv = "1.40"]
fn msrv_1_40() {
- #![clippy::msrv = "1.40"]
-
let mut s = String::from("foo");
let _ = std::mem::take(&mut s);
}
diff --git a/src/tools/clippy/tests/ui/mem_replace.rs b/src/tools/clippy/tests/ui/mem_replace.rs
index 3202e99e0..f4f3bff51 100644
--- a/src/tools/clippy/tests/ui/mem_replace.rs
+++ b/src/tools/clippy/tests/ui/mem_replace.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(unused)]
#![warn(
clippy::all,
@@ -80,16 +79,14 @@ fn main() {
dont_lint_primitive();
}
+#[clippy::msrv = "1.39"]
fn msrv_1_39() {
- #![clippy::msrv = "1.39"]
-
let mut s = String::from("foo");
let _ = std::mem::replace(&mut s, String::default());
}
+#[clippy::msrv = "1.40"]
fn msrv_1_40() {
- #![clippy::msrv = "1.40"]
-
let mut s = String::from("foo");
let _ = std::mem::replace(&mut s, String::default());
}
diff --git a/src/tools/clippy/tests/ui/mem_replace.stderr b/src/tools/clippy/tests/ui/mem_replace.stderr
index dd8a50dab..caa127f76 100644
--- a/src/tools/clippy/tests/ui/mem_replace.stderr
+++ b/src/tools/clippy/tests/ui/mem_replace.stderr
@@ -1,5 +1,5 @@
error: replacing an `Option` with `None`
- --> $DIR/mem_replace.rs:17:13
+ --> $DIR/mem_replace.rs:16:13
|
LL | let _ = mem::replace(&mut an_option, None);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
@@ -7,13 +7,13 @@ LL | let _ = mem::replace(&mut an_option, None);
= note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings`
error: replacing an `Option` with `None`
- --> $DIR/mem_replace.rs:19:13
+ --> $DIR/mem_replace.rs:18: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:24:13
+ --> $DIR/mem_replace.rs:23:13
|
LL | let _ = std::mem::replace(&mut s, String::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`
@@ -21,103 +21,103 @@ LL | let _ = std::mem::replace(&mut s, String::default());
= note: `-D clippy::mem-replace-with-default` implied by `-D warnings`
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:26: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:28:13
+ --> $DIR/mem_replace.rs:27: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:31:13
+ --> $DIR/mem_replace.rs:30: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:32:13
+ --> $DIR/mem_replace.rs:31: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:33:13
+ --> $DIR/mem_replace.rs:32: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:34:13
+ --> $DIR/mem_replace.rs:33: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:37:13
+ --> $DIR/mem_replace.rs:36: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:40:13
+ --> $DIR/mem_replace.rs:39: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:43:13
+ --> $DIR/mem_replace.rs:42: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:46:13
+ --> $DIR/mem_replace.rs:45: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:49:13
+ --> $DIR/mem_replace.rs:48: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:52:13
+ --> $DIR/mem_replace.rs:51: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:55:13
+ --> $DIR/mem_replace.rs:54: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:58:13
+ --> $DIR/mem_replace.rs:57: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:61:13
+ --> $DIR/mem_replace.rs:60: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:64:13
+ --> $DIR/mem_replace.rs:63: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:94:13
+ --> $DIR/mem_replace.rs:91:13
|
LL | let _ = std::mem::replace(&mut s, String::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`
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 cd148063b..955e7eb72 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.rs
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.rs
@@ -3,27 +3,60 @@
fn main() {}
+#[clippy::msrv = "1.42.0"]
fn just_under_msrv() {
- #![clippy::msrv = "1.42.0"]
let log2_10 = 3.321928094887362;
}
+#[clippy::msrv = "1.43.0"]
fn meets_msrv() {
- #![clippy::msrv = "1.43.0"]
let log2_10 = 3.321928094887362;
}
+#[clippy::msrv = "1.44.0"]
fn just_above_msrv() {
- #![clippy::msrv = "1.44.0"]
let log2_10 = 3.321928094887362;
}
+#[clippy::msrv = "1.42"]
fn no_patch_under() {
- #![clippy::msrv = "1.42"]
let log2_10 = 3.321928094887362;
}
+#[clippy::msrv = "1.43"]
fn no_patch_meets() {
+ let log2_10 = 3.321928094887362;
+}
+
+fn inner_attr_under() {
+ #![clippy::msrv = "1.42"]
+ let log2_10 = 3.321928094887362;
+}
+
+fn inner_attr_meets() {
#![clippy::msrv = "1.43"]
let log2_10 = 3.321928094887362;
}
+
+// https://github.com/rust-lang/rust-clippy/issues/6920
+fn scoping() {
+ mod m {
+ #![clippy::msrv = "1.42.0"]
+ }
+
+ // Should warn
+ let log2_10 = 3.321928094887362;
+
+ mod a {
+ #![clippy::msrv = "1.42.0"]
+
+ fn should_warn() {
+ #![clippy::msrv = "1.43.0"]
+ let log2_10 = 3.321928094887362;
+ }
+
+ fn should_not_warn() {
+ let log2_10 = 3.321928094887362;
+ }
+ }
+}
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 68aa58748..7e2135584 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
@@ -23,5 +23,29 @@ LL | let log2_10 = 3.321928094887362;
|
= help: consider using the constant directly
-error: aborting due to 3 previous errors
+error: approximate value of `f{32, 64}::consts::LOG2_10` found
+ --> $DIR/min_rust_version_attr.rs:38:19
+ |
+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
+ |
+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
+ |
+LL | let log2_10 = 3.321928094887362;
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using the constant directly
+
+error: aborting due to 6 previous errors
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 93370a0fa..675b78031 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
@@ -4,7 +4,7 @@ error: `invalid.version` is not a valid Rust version
LL | #![clippy::msrv = "invalid.version"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: `msrv` cannot be an outer attribute
+error: `invalid.version` is not a valid Rust version
--> $DIR/min_rust_version_invalid_attr.rs:6:1
|
LL | #[clippy::msrv = "invalid.version"]
diff --git a/src/tools/clippy/tests/ui/misnamed_getters.rs b/src/tools/clippy/tests/ui/misnamed_getters.rs
new file mode 100644
index 000000000..03e7dac7d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/misnamed_getters.rs
@@ -0,0 +1,124 @@
+#![allow(unused)]
+#![warn(clippy::misnamed_getters)]
+
+struct A {
+ a: u8,
+ b: u8,
+ c: u8,
+}
+
+impl A {
+ fn a(&self) -> &u8 {
+ &self.b
+ }
+ fn a_mut(&mut self) -> &mut u8 {
+ &mut self.b
+ }
+
+ fn b(self) -> u8 {
+ self.a
+ }
+
+ fn b_mut(&mut self) -> &mut u8 {
+ &mut self.a
+ }
+
+ fn c(&self) -> &u8 {
+ &self.b
+ }
+
+ fn c_mut(&mut self) -> &mut u8 {
+ &mut self.a
+ }
+}
+
+union B {
+ a: u8,
+ b: u8,
+}
+
+impl B {
+ unsafe fn a(&self) -> &u8 {
+ &self.b
+ }
+ unsafe fn a_mut(&mut self) -> &mut u8 {
+ &mut self.b
+ }
+
+ unsafe fn b(self) -> u8 {
+ self.a
+ }
+
+ unsafe fn b_mut(&mut self) -> &mut u8 {
+ &mut self.a
+ }
+
+ unsafe fn c(&self) -> &u8 {
+ &self.b
+ }
+
+ unsafe fn c_mut(&mut self) -> &mut u8 {
+ &mut self.a
+ }
+
+ unsafe fn a_unchecked(&self) -> &u8 {
+ &self.b
+ }
+ unsafe fn a_unchecked_mut(&mut self) -> &mut u8 {
+ &mut self.b
+ }
+
+ unsafe fn b_unchecked(self) -> u8 {
+ self.a
+ }
+
+ unsafe fn b_unchecked_mut(&mut self) -> &mut u8 {
+ &mut self.a
+ }
+
+ 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 {
+ &self.b
+ }
+ fn a_mut(&mut self) -> &mut u8 {
+ &mut self.b
+ }
+
+ fn d(&self) -> &u8 {
+ &self.b
+ }
+ fn d_mut(&mut self) -> &mut u8 {
+ &mut self.b
+ }
+}
+
+fn main() {
+ // test code goes here
+}
diff --git a/src/tools/clippy/tests/ui/misnamed_getters.stderr b/src/tools/clippy/tests/ui/misnamed_getters.stderr
new file mode 100644
index 000000000..1e38a83d0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/misnamed_getters.stderr
@@ -0,0 +1,166 @@
+error: getter function appears to return the wrong field
+ --> $DIR/misnamed_getters.rs:11:5
+ |
+LL | / fn a(&self) -> &u8 {
+LL | | &self.b
+ | | ------- help: consider using: `&self.a`
+LL | | }
+ | |_____^
+ |
+ = note: `-D clippy::misnamed-getters` implied by `-D warnings`
+
+error: getter function appears to return the wrong field
+ --> $DIR/misnamed_getters.rs:14:5
+ |
+LL | / fn a_mut(&mut self) -> &mut u8 {
+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
+ |
+LL | / fn b(self) -> u8 {
+LL | | self.a
+ | | ------ help: consider using: `self.b`
+LL | | }
+ | |_____^
+
+error: getter function appears to return the wrong field
+ --> $DIR/misnamed_getters.rs:22:5
+ |
+LL | / fn b_mut(&mut self) -> &mut u8 {
+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
+ |
+LL | / fn c(&self) -> &u8 {
+LL | | &self.b
+ | | ------- help: consider using: `&self.c`
+LL | | }
+ | |_____^
+
+error: getter function appears to return the wrong field
+ --> $DIR/misnamed_getters.rs:30:5
+ |
+LL | / fn c_mut(&mut self) -> &mut u8 {
+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
+ |
+LL | / unsafe fn a(&self) -> &u8 {
+LL | | &self.b
+ | | ------- help: consider using: `&self.a`
+LL | | }
+ | |_____^
+
+error: getter function appears to return the wrong field
+ --> $DIR/misnamed_getters.rs:44:5
+ |
+LL | / unsafe fn a_mut(&mut self) -> &mut u8 {
+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
+ |
+LL | / unsafe fn b(self) -> u8 {
+LL | | self.a
+ | | ------ help: consider using: `self.b`
+LL | | }
+ | |_____^
+
+error: getter function appears to return the wrong field
+ --> $DIR/misnamed_getters.rs:52:5
+ |
+LL | / unsafe fn b_mut(&mut self) -> &mut u8 {
+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
+ |
+LL | / unsafe fn a_unchecked(&self) -> &u8 {
+LL | | &self.b
+ | | ------- help: consider using: `&self.a`
+LL | | }
+ | |_____^
+
+error: getter function appears to return the wrong field
+ --> $DIR/misnamed_getters.rs:67:5
+ |
+LL | / unsafe fn a_unchecked_mut(&mut self) -> &mut u8 {
+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
+ |
+LL | / unsafe fn b_unchecked(self) -> u8 {
+LL | | self.a
+ | | ------ help: consider using: `self.b`
+LL | | }
+ | |_____^
+
+error: getter function appears to return the wrong field
+ --> $DIR/misnamed_getters.rs:75:5
+ |
+LL | / unsafe fn b_unchecked_mut(&mut self) -> &mut u8 {
+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
+ |
+LL | / fn a(&self) -> &u8 {
+LL | | &self.b
+ | | ------- help: consider using: `&self.a`
+LL | | }
+ | |_____^
+
+error: getter function appears to return the wrong field
+ --> $DIR/misnamed_getters.rs:110:5
+ |
+LL | / fn a_mut(&mut self) -> &mut u8 {
+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
+ |
+LL | / fn d(&self) -> &u8 {
+LL | | &self.b
+ | | ------- help: consider using: `&self.d`
+LL | | }
+ | |_____^
+
+error: getter function appears to return the wrong field
+ --> $DIR/misnamed_getters.rs:117:5
+ |
+LL | / fn d_mut(&mut self) -> &mut u8 {
+LL | | &mut self.b
+ | | ----------- help: consider using: `&mut self.d`
+LL | | }
+ | |_____^
+
+error: aborting due to 18 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 b950248ef..75cace181 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
@@ -7,7 +7,6 @@
#![warn(clippy::missing_const_for_fn)]
#![feature(start)]
-#![feature(custom_inner_attributes)]
extern crate helper;
extern crate proc_macro_with_span;
@@ -115,9 +114,8 @@ fn unstably_const_fn() {
helper::unstably_const_fn()
}
+#[clippy::msrv = "1.46.0"]
mod const_fn_stabilized_after_msrv {
- #![clippy::msrv = "1.46.0"]
-
// Do not lint this because `u8::is_ascii_digit` is stabilized as a const function in 1.47.0.
fn const_fn_stabilized_after_msrv(byte: u8) {
byte.is_ascii_digit();
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 b85e88784..0246c8622 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
@@ -1,6 +1,5 @@
#![warn(clippy::missing_const_for_fn)]
#![allow(incomplete_features, clippy::let_and_return)]
-#![feature(custom_inner_attributes)]
use std::mem::transmute;
@@ -68,24 +67,21 @@ mod with_drop {
}
}
+#[clippy::msrv = "1.47.0"]
mod const_fn_stabilized_before_msrv {
- #![clippy::msrv = "1.47.0"]
-
// 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) {
byte.is_ascii_digit();
}
}
+#[clippy::msrv = "1.45"]
fn msrv_1_45() -> i32 {
- #![clippy::msrv = "1.45"]
-
45
}
+#[clippy::msrv = "1.46"]
fn msrv_1_46() -> i32 {
- #![clippy::msrv = "1.46"]
-
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 f8e221c82..955e1ed26 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
@@ -1,5 +1,5 @@
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:13:5
+ --> $DIR/could_be_const.rs:12:5
|
LL | / pub fn new() -> Self {
LL | | Self { guess: 42 }
@@ -9,7 +9,7 @@ LL | | }
= note: `-D clippy::missing-const-for-fn` implied by `-D warnings`
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:17:5
+ --> $DIR/could_be_const.rs:16:5
|
LL | / fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {
LL | | b
@@ -17,7 +17,7 @@ LL | | }
| |_____^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:23:1
+ --> $DIR/could_be_const.rs:22:1
|
LL | / fn one() -> i32 {
LL | | 1
@@ -25,7 +25,7 @@ LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:28:1
+ --> $DIR/could_be_const.rs:27:1
|
LL | / fn two() -> i32 {
LL | | let abc = 2;
@@ -34,7 +34,7 @@ LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:34:1
+ --> $DIR/could_be_const.rs:33:1
|
LL | / fn string() -> String {
LL | | String::new()
@@ -42,7 +42,7 @@ LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:39:1
+ --> $DIR/could_be_const.rs:38:1
|
LL | / unsafe fn four() -> i32 {
LL | | 4
@@ -50,7 +50,7 @@ LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:44:1
+ --> $DIR/could_be_const.rs:43:1
|
LL | / fn generic<T>(t: T) -> T {
LL | | t
@@ -58,7 +58,7 @@ LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:52:1
+ --> $DIR/could_be_const.rs:51:1
|
LL | / fn generic_arr<T: Copy>(t: [T; 1]) -> T {
LL | | t[0]
@@ -66,7 +66,7 @@ LL | | }
| |_^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:65:9
+ --> $DIR/could_be_const.rs:64:9
|
LL | / pub fn b(self, a: &A) -> B {
LL | | B
@@ -74,7 +74,7 @@ LL | | }
| |_________^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:75:5
+ --> $DIR/could_be_const.rs:73:5
|
LL | / fn const_fn_stabilized_before_msrv(byte: u8) {
LL | | byte.is_ascii_digit();
@@ -82,11 +82,9 @@ LL | | }
| |_____^
error: this could be a `const fn`
- --> $DIR/could_be_const.rs:86:1
+ --> $DIR/could_be_const.rs:84:1
|
LL | / fn msrv_1_46() -> i32 {
-LL | | #![clippy::msrv = "1.46"]
-LL | |
LL | | 46
LL | | }
| |_^
diff --git a/src/tools/clippy/tests/ui/missing_panics_doc.stderr b/src/tools/clippy/tests/ui/missing_panics_doc.stderr
index c9ded7f1a..183c262ce 100644
--- a/src/tools/clippy/tests/ui/missing_panics_doc.stderr
+++ b/src/tools/clippy/tests/ui/missing_panics_doc.stderr
@@ -1,11 +1,8 @@
error: docs for function which may panic missing `# Panics` section
--> $DIR/missing_panics_doc.rs:6:1
|
-LL | / pub fn unwrap() {
-LL | | let result = Err("Hi");
-LL | | result.unwrap()
-LL | | }
- | |_^
+LL | pub fn unwrap() {
+ | ^^^^^^^^^^^^^^^
|
note: first possible panic found here
--> $DIR/missing_panics_doc.rs:8:5
@@ -17,10 +14,8 @@ LL | result.unwrap()
error: docs for function which may panic missing `# Panics` section
--> $DIR/missing_panics_doc.rs:12:1
|
-LL | / pub fn panic() {
-LL | | panic!("This function panics")
-LL | | }
- | |_^
+LL | pub fn panic() {
+ | ^^^^^^^^^^^^^^
|
note: first possible panic found here
--> $DIR/missing_panics_doc.rs:13:5
@@ -31,10 +26,8 @@ LL | panic!("This function panics")
error: docs for function which may panic missing `# Panics` section
--> $DIR/missing_panics_doc.rs:17:1
|
-LL | / pub fn todo() {
-LL | | todo!()
-LL | | }
- | |_^
+LL | pub fn todo() {
+ | ^^^^^^^^^^^^^
|
note: first possible panic found here
--> $DIR/missing_panics_doc.rs:18:5
@@ -45,14 +38,8 @@ LL | todo!()
error: docs for function which may panic missing `# Panics` section
--> $DIR/missing_panics_doc.rs:22:1
|
-LL | / pub fn inner_body(opt: Option<u32>) {
-LL | | opt.map(|x| {
-LL | | if x == 10 {
-LL | | panic!()
-LL | | }
-LL | | });
-LL | | }
- | |_^
+LL | pub fn inner_body(opt: Option<u32>) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first possible panic found here
--> $DIR/missing_panics_doc.rs:25:13
@@ -63,10 +50,8 @@ LL | panic!()
error: docs for function which may panic missing `# Panics` section
--> $DIR/missing_panics_doc.rs:31:1
|
-LL | / pub fn unreachable_and_panic() {
-LL | | if true { unreachable!() } else { panic!() }
-LL | | }
- | |_^
+LL | pub fn unreachable_and_panic() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first possible panic found here
--> $DIR/missing_panics_doc.rs:32:39
@@ -77,11 +62,8 @@ LL | if true { unreachable!() } else { panic!() }
error: docs for function which may panic missing `# Panics` section
--> $DIR/missing_panics_doc.rs:36:1
|
-LL | / pub fn assert_eq() {
-LL | | let x = 0;
-LL | | assert_eq!(x, 0);
-LL | | }
- | |_^
+LL | pub fn assert_eq() {
+ | ^^^^^^^^^^^^^^^^^^
|
note: first possible panic found here
--> $DIR/missing_panics_doc.rs:38:5
@@ -92,11 +74,8 @@ LL | assert_eq!(x, 0);
error: docs for function which may panic missing `# Panics` section
--> $DIR/missing_panics_doc.rs:42:1
|
-LL | / pub fn assert_ne() {
-LL | | let x = 0;
-LL | | assert_ne!(x, 0);
-LL | | }
- | |_^
+LL | pub fn assert_ne() {
+ | ^^^^^^^^^^^^^^^^^^
|
note: first possible panic found here
--> $DIR/missing_panics_doc.rs:44:5
diff --git a/src/tools/clippy/tests/ui/mut_from_ref.rs b/src/tools/clippy/tests/ui/mut_from_ref.rs
index 370dbd588..7de153305 100644
--- a/src/tools/clippy/tests/ui/mut_from_ref.rs
+++ b/src/tools/clippy/tests/ui/mut_from_ref.rs
@@ -1,4 +1,4 @@
-#![allow(unused)]
+#![allow(unused, clippy::needless_lifetimes)]
#![warn(clippy::mut_from_ref)]
struct Foo;
diff --git a/src/tools/clippy/tests/ui/mut_mut.rs b/src/tools/clippy/tests/ui/mut_mut.rs
index ac8fd9d8f..ee3a85656 100644
--- a/src/tools/clippy/tests/ui/mut_mut.rs
+++ b/src/tools/clippy/tests/ui/mut_mut.rs
@@ -57,3 +57,20 @@ fn issue6922() {
// do not lint from an external macro
mut_mut!();
}
+
+mod issue9035 {
+ use std::fmt::Display;
+
+ struct Foo<'a> {
+ inner: &'a mut dyn Display,
+ }
+
+ impl Foo<'_> {
+ fn foo(&mut self) {
+ let hlp = &mut self.inner;
+ bar(hlp);
+ }
+ }
+
+ fn bar(_: &mut impl Display) {}
+}
diff --git a/src/tools/clippy/tests/ui/mut_range_bound.rs b/src/tools/clippy/tests/ui/mut_range_bound.rs
index e1ae1ef92..7fdeb27ed 100644
--- a/src/tools/clippy/tests/ui/mut_range_bound.rs
+++ b/src/tools/clippy/tests/ui/mut_range_bound.rs
@@ -76,7 +76,7 @@ fn mut_range_bound_no_immediate_break() {
let mut n = 3;
for i in n..10 {
if n == 4 {
- n = 1; // FIXME: warning because is is not immediately followed by break
+ n = 1; // FIXME: warning because it is not immediately followed by break
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 e0c8dced3..b679b7a0a 100644
--- a/src/tools/clippy/tests/ui/mut_range_bound.stderr
+++ b/src/tools/clippy/tests/ui/mut_range_bound.stderr
@@ -50,7 +50,7 @@ LL | m = 2; // warning because it is not immediately followed by break
error: attempt to mutate range bound within loop
--> $DIR/mut_range_bound.rs:79:13
|
-LL | n = 1; // FIXME: warning because is is not immediately followed by break
+LL | n = 1; // FIXME: warning because it is not immediately followed by break
| ^
|
= note: the range of the loop is unchanged
diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed
index 340e89d2d..4cb7f6b68 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrow.fixed
@@ -1,13 +1,13 @@
// run-rustfix
-#![feature(custom_inner_attributes, lint_reasons)]
-
-#[warn(clippy::all, clippy::needless_borrow)]
-#[allow(unused_variables)]
-#[allow(
+#![feature(lint_reasons)]
+#![allow(
+ unused,
clippy::uninlined_format_args,
clippy::unnecessary_mut_passed,
clippy::unnecessary_to_owned
)]
+#![warn(clippy::needless_borrow)]
+
fn main() {
let a = 5;
let ref_a = &a;
@@ -171,14 +171,12 @@ impl<'a> Trait for &'a str {}
fn h(_: &dyn Trait) {}
-#[allow(dead_code)]
fn check_expect_suppression() {
let a = 5;
#[expect(clippy::needless_borrow)]
let _ = x(&&a);
}
-#[allow(dead_code)]
mod issue9160 {
pub struct S<F> {
f: F,
@@ -267,7 +265,6 @@ where
}
// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
-#[allow(dead_code)]
mod copyable_iterator {
#[derive(Clone, Copy)]
struct Iter;
@@ -287,25 +284,20 @@ mod copyable_iterator {
}
}
+#[clippy::msrv = "1.52.0"]
mod under_msrv {
- #![allow(dead_code)]
- #![clippy::msrv = "1.52.0"]
-
fn foo() {
let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
}
}
+#[clippy::msrv = "1.53.0"]
mod meets_msrv {
- #![allow(dead_code)]
- #![clippy::msrv = "1.53.0"]
-
fn foo() {
let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
}
}
-#[allow(unused)]
fn issue9383() {
// Should not lint because unions need explicit deref when accessing field
use std::mem::ManuallyDrop;
@@ -334,7 +326,6 @@ fn issue9383() {
}
}
-#[allow(dead_code)]
fn closure_test() {
let env = "env".to_owned();
let arg = "arg".to_owned();
@@ -348,7 +339,6 @@ fn closure_test() {
f(arg);
}
-#[allow(dead_code)]
mod significant_drop {
#[derive(Debug)]
struct X;
@@ -368,7 +358,6 @@ mod significant_drop {
fn debug(_: impl std::fmt::Debug) {}
}
-#[allow(dead_code)]
mod used_exactly_once {
fn foo(x: String) {
use_x(x);
@@ -376,7 +365,6 @@ mod used_exactly_once {
fn use_x(_: impl AsRef<str>) {}
}
-#[allow(dead_code)]
mod used_more_than_once {
fn foo(x: String) {
use_x(&x);
@@ -385,3 +373,121 @@ mod used_more_than_once {
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 {
+ struct S;
+
+ impl S {
+ fn foo<T: AsRef<[u8]>>(&self, 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);
+ }
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs
index c93711ac8..9a01190ed 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow.rs
@@ -1,13 +1,13 @@
// run-rustfix
-#![feature(custom_inner_attributes, lint_reasons)]
-
-#[warn(clippy::all, clippy::needless_borrow)]
-#[allow(unused_variables)]
-#[allow(
+#![feature(lint_reasons)]
+#![allow(
+ unused,
clippy::uninlined_format_args,
clippy::unnecessary_mut_passed,
clippy::unnecessary_to_owned
)]
+#![warn(clippy::needless_borrow)]
+
fn main() {
let a = 5;
let ref_a = &a;
@@ -171,14 +171,12 @@ impl<'a> Trait for &'a str {}
fn h(_: &dyn Trait) {}
-#[allow(dead_code)]
fn check_expect_suppression() {
let a = 5;
#[expect(clippy::needless_borrow)]
let _ = x(&&a);
}
-#[allow(dead_code)]
mod issue9160 {
pub struct S<F> {
f: F,
@@ -267,7 +265,6 @@ where
}
// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
-#[allow(dead_code)]
mod copyable_iterator {
#[derive(Clone, Copy)]
struct Iter;
@@ -287,25 +284,20 @@ mod copyable_iterator {
}
}
+#[clippy::msrv = "1.52.0"]
mod under_msrv {
- #![allow(dead_code)]
- #![clippy::msrv = "1.52.0"]
-
fn foo() {
let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
}
}
+#[clippy::msrv = "1.53.0"]
mod meets_msrv {
- #![allow(dead_code)]
- #![clippy::msrv = "1.53.0"]
-
fn foo() {
let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
}
}
-#[allow(unused)]
fn issue9383() {
// Should not lint because unions need explicit deref when accessing field
use std::mem::ManuallyDrop;
@@ -334,7 +326,6 @@ fn issue9383() {
}
}
-#[allow(dead_code)]
fn closure_test() {
let env = "env".to_owned();
let arg = "arg".to_owned();
@@ -348,7 +339,6 @@ fn closure_test() {
f(arg);
}
-#[allow(dead_code)]
mod significant_drop {
#[derive(Debug)]
struct X;
@@ -368,7 +358,6 @@ mod significant_drop {
fn debug(_: impl std::fmt::Debug) {}
}
-#[allow(dead_code)]
mod used_exactly_once {
fn foo(x: String) {
use_x(&x);
@@ -376,7 +365,6 @@ mod used_exactly_once {
fn use_x(_: impl AsRef<str>) {}
}
-#[allow(dead_code)]
mod used_more_than_once {
fn foo(x: String) {
use_x(&x);
@@ -385,3 +373,121 @@ mod used_more_than_once {
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 {
+ struct S;
+
+ impl S {
+ fn foo<T: AsRef<[u8]>>(&self, 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);
+ }
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index 8b593268b..d26c31712 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -163,52 +163,58 @@ 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:192:13
+ --> $DIR/needless_borrow.rs:190: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:201:13
+ --> $DIR/needless_borrow.rs:199:13
|
LL | (&mut self.f)()
| ^^^^^^^^^^^^^ help: change this to: `(self.f)`
error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:286:20
+ --> $DIR/needless_borrow.rs:283:20
|
LL | takes_iter(&mut x)
| ^^^^^^ help: change this to: `x`
error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:304:55
+ --> $DIR/needless_borrow.rs:297: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:344:37
+ --> $DIR/needless_borrow.rs:335: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:345:37
+ --> $DIR/needless_borrow.rs:336: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:364:15
+ --> $DIR/needless_borrow.rs:354:15
|
LL | debug(&x);
| ^^ help: change this to: `x`
error: the borrowed expression implements the required traits
- --> $DIR/needless_borrow.rs:374:15
+ --> $DIR/needless_borrow.rs:363:15
|
LL | use_x(&x);
| ^^ help: change this to: `x`
-error: aborting due to 35 previous errors
+error: the borrowed expression implements the required traits
+ --> $DIR/needless_borrow.rs:457:13
+ |
+LL | foo(&a);
+ | ^^ help: change this to: `a`
+
+error: aborting due to 36 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed b/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed
index bcb4eb2dd..0c47ceb7b 100644
--- a/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed
@@ -1,11 +1,32 @@
// run-rustfix
#![warn(clippy::needless_borrowed_reference)]
-#![allow(unused, clippy::needless_borrow)]
+#![allow(
+ unused,
+ irrefutable_let_patterns,
+ non_shorthand_field_patterns,
+ clippy::needless_borrow
+)]
fn main() {}
-fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
+struct Struct {
+ a: usize,
+ b: usize,
+ c: usize,
+}
+
+struct TupleStruct(u8, u8, u8);
+
+fn should_lint(
+ array: [u8; 4],
+ slice: &[u8],
+ slice_of_refs: &[&u8],
+ vec: Vec<u8>,
+ tuple: (u8, u8, u8),
+ tuple_struct: TupleStruct,
+ s: Struct,
+) {
let mut v = Vec::<String>::new();
let _ = v.iter_mut().filter(|a| a.is_empty());
@@ -24,16 +45,54 @@ fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>
if let [a, b, ..] = slice {}
if let [a, .., b] = slice {}
if let [.., a, b] = slice {}
+
+ if let [a, _] = slice {}
+
+ if let (a, b, c) = &tuple {}
+ if let (a, _, c) = &tuple {}
+ if let (a, ..) = &tuple {}
+
+ if let TupleStruct(a, ..) = &tuple_struct {}
+
+ if let Struct {
+ a,
+ b: b,
+ c: renamed,
+ } = &s
+ {}
+
+ if let Struct { a, b: _, .. } = &s {}
}
-fn should_not_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
+fn should_not_lint(
+ array: [u8; 4],
+ slice: &[u8],
+ slice_of_refs: &[&u8],
+ vec: Vec<u8>,
+ tuple: (u8, u8, u8),
+ tuple_struct: TupleStruct,
+ s: Struct,
+) {
if let [ref a] = slice {}
if let &[ref a, b] = slice {}
if let &[ref a, .., b] = slice {}
+ if let &(ref a, b, ..) = &tuple {}
+ if let &TupleStruct(ref a, b, ..) = &tuple_struct {}
+ if let &Struct { ref a, b, .. } = &s {}
+
// must not be removed as variables must be bound consistently across | patterns
if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}
+ // the `&`s here technically could be removed, but it'd be noisy and without a `ref` doesn't match
+ // the lint name
+ if let &[] = slice {}
+ if let &[_] = slice {}
+ if let &[..] = slice {}
+ if let &(..) = &tuple {}
+ if let &TupleStruct(..) = &tuple_struct {}
+ if let &Struct { .. } = &s {}
+
let mut var2 = 5;
let thingy2 = Some(&mut var2);
if let Some(&mut ref mut v) = thingy2 {
@@ -59,6 +118,6 @@ fn foo(a: &Animal, b: &Animal) {
// lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63
(&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),
// ^ and ^ should **not** be linted
- (&Animal::Dog(ref a), &Animal::Dog(_)) => (), // ^ should **not** be linted
+ (Animal::Dog(a), &Animal::Dog(_)) => (),
}
}
diff --git a/src/tools/clippy/tests/ui/needless_borrowed_ref.rs b/src/tools/clippy/tests/ui/needless_borrowed_ref.rs
index f6de1a6d8..f883bb0c8 100644
--- a/src/tools/clippy/tests/ui/needless_borrowed_ref.rs
+++ b/src/tools/clippy/tests/ui/needless_borrowed_ref.rs
@@ -1,11 +1,32 @@
// run-rustfix
#![warn(clippy::needless_borrowed_reference)]
-#![allow(unused, clippy::needless_borrow)]
+#![allow(
+ unused,
+ irrefutable_let_patterns,
+ non_shorthand_field_patterns,
+ clippy::needless_borrow
+)]
fn main() {}
-fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
+struct Struct {
+ a: usize,
+ b: usize,
+ c: usize,
+}
+
+struct TupleStruct(u8, u8, u8);
+
+fn should_lint(
+ array: [u8; 4],
+ slice: &[u8],
+ slice_of_refs: &[&u8],
+ vec: Vec<u8>,
+ tuple: (u8, u8, u8),
+ tuple_struct: TupleStruct,
+ s: Struct,
+) {
let mut v = Vec::<String>::new();
let _ = v.iter_mut().filter(|&ref a| a.is_empty());
@@ -24,16 +45,54 @@ fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>
if let &[ref a, ref b, ..] = slice {}
if let &[ref a, .., ref b] = slice {}
if let &[.., ref a, ref b] = slice {}
+
+ if let &[ref a, _] = slice {}
+
+ if let &(ref a, ref b, ref c) = &tuple {}
+ if let &(ref a, _, ref c) = &tuple {}
+ if let &(ref a, ..) = &tuple {}
+
+ if let &TupleStruct(ref a, ..) = &tuple_struct {}
+
+ if let &Struct {
+ ref a,
+ b: ref b,
+ c: ref renamed,
+ } = &s
+ {}
+
+ if let &Struct { ref a, b: _, .. } = &s {}
}
-fn should_not_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
+fn should_not_lint(
+ array: [u8; 4],
+ slice: &[u8],
+ slice_of_refs: &[&u8],
+ vec: Vec<u8>,
+ tuple: (u8, u8, u8),
+ tuple_struct: TupleStruct,
+ s: Struct,
+) {
if let [ref a] = slice {}
if let &[ref a, b] = slice {}
if let &[ref a, .., b] = slice {}
+ if let &(ref a, b, ..) = &tuple {}
+ if let &TupleStruct(ref a, b, ..) = &tuple_struct {}
+ if let &Struct { ref a, b, .. } = &s {}
+
// must not be removed as variables must be bound consistently across | patterns
if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}
+ // the `&`s here technically could be removed, but it'd be noisy and without a `ref` doesn't match
+ // the lint name
+ if let &[] = slice {}
+ if let &[_] = slice {}
+ if let &[..] = slice {}
+ if let &(..) = &tuple {}
+ if let &TupleStruct(..) = &tuple_struct {}
+ if let &Struct { .. } = &s {}
+
let mut var2 = 5;
let thingy2 = Some(&mut var2);
if let Some(&mut ref mut v) = thingy2 {
@@ -59,6 +118,6 @@ fn foo(a: &Animal, b: &Animal) {
// lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63
(&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),
// ^ and ^ should **not** be linted
- (&Animal::Dog(ref a), &Animal::Dog(_)) => (), // ^ should **not** be linted
+ (Animal::Dog(a), &Animal::Dog(_)) => (),
}
}
diff --git a/src/tools/clippy/tests/ui/needless_borrowed_ref.stderr b/src/tools/clippy/tests/ui/needless_borrowed_ref.stderr
index 7453542e6..8d0f0c258 100644
--- a/src/tools/clippy/tests/ui/needless_borrowed_ref.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrowed_ref.stderr
@@ -1,5 +1,5 @@
error: this pattern takes a reference on something that is being dereferenced
- --> $DIR/needless_borrowed_ref.rs:10:34
+ --> $DIR/needless_borrowed_ref.rs:31:34
|
LL | let _ = v.iter_mut().filter(|&ref a| a.is_empty());
| ^^^^^^
@@ -12,7 +12,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:14:17
+ --> $DIR/needless_borrowed_ref.rs:35:17
|
LL | if let Some(&ref v) = thingy {}
| ^^^^^^
@@ -24,7 +24,7 @@ LL + if let Some(v) = thingy {}
|
error: this pattern takes a reference on something that is being dereferenced
- --> $DIR/needless_borrowed_ref.rs:16:14
+ --> $DIR/needless_borrowed_ref.rs:37:14
|
LL | if let &[&ref a, ref b] = slice_of_refs {}
| ^^^^^^
@@ -36,7 +36,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:18:9
+ --> $DIR/needless_borrowed_ref.rs:39:9
|
LL | let &[ref a, ..] = &array;
| ^^^^^^^^^^^^
@@ -48,7 +48,7 @@ LL + let [a, ..] = &array;
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:19:9
+ --> $DIR/needless_borrowed_ref.rs:40:9
|
LL | let &[ref a, ref b, ..] = &array;
| ^^^^^^^^^^^^^^^^^^^
@@ -60,7 +60,7 @@ LL + let [a, b, ..] = &array;
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:21:12
+ --> $DIR/needless_borrowed_ref.rs:42:12
|
LL | if let &[ref a, ref b] = slice {}
| ^^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL + if let [a, b] = slice {}
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:22:12
+ --> $DIR/needless_borrowed_ref.rs:43:12
|
LL | if let &[ref a, ref b] = &vec[..] {}
| ^^^^^^^^^^^^^^^
@@ -84,7 +84,7 @@ LL + if let [a, b] = &vec[..] {}
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:24:12
+ --> $DIR/needless_borrowed_ref.rs:45:12
|
LL | if let &[ref a, ref b, ..] = slice {}
| ^^^^^^^^^^^^^^^^^^^
@@ -96,7 +96,7 @@ LL + if let [a, b, ..] = slice {}
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:25:12
+ --> $DIR/needless_borrowed_ref.rs:46:12
|
LL | if let &[ref a, .., ref b] = slice {}
| ^^^^^^^^^^^^^^^^^^^
@@ -108,7 +108,7 @@ LL + if let [a, .., b] = slice {}
|
error: dereferencing a slice pattern where every element takes a reference
- --> $DIR/needless_borrowed_ref.rs:26:12
+ --> $DIR/needless_borrowed_ref.rs:47:12
|
LL | if let &[.., ref a, ref b] = slice {}
| ^^^^^^^^^^^^^^^^^^^
@@ -119,5 +119,96 @@ LL - if let &[.., ref a, ref b] = slice {}
LL + if let [.., a, b] = slice {}
|
-error: aborting due to 10 previous errors
+error: dereferencing a slice pattern where every element takes a reference
+ --> $DIR/needless_borrowed_ref.rs:49:12
+ |
+LL | if let &[ref a, _] = slice {}
+ | ^^^^^^^^^^^
+ |
+help: try removing the `&` and `ref` parts
+ |
+LL - if let &[ref a, _] = slice {}
+LL + if let [a, _] = slice {}
+ |
+
+error: dereferencing a tuple pattern where every element takes a reference
+ --> $DIR/needless_borrowed_ref.rs:51:12
+ |
+LL | if let &(ref a, ref b, ref c) = &tuple {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try removing the `&` and `ref` parts
+ |
+LL - if let &(ref a, ref b, ref c) = &tuple {}
+LL + if let (a, b, c) = &tuple {}
+ |
+
+error: dereferencing a tuple pattern where every element takes a reference
+ --> $DIR/needless_borrowed_ref.rs:52:12
+ |
+LL | if let &(ref a, _, ref c) = &tuple {}
+ | ^^^^^^^^^^^^^^^^^^
+ |
+help: try removing the `&` and `ref` parts
+ |
+LL - if let &(ref a, _, ref c) = &tuple {}
+LL + if let (a, _, c) = &tuple {}
+ |
+
+error: dereferencing a tuple pattern where every element takes a reference
+ --> $DIR/needless_borrowed_ref.rs:53:12
+ |
+LL | if let &(ref a, ..) = &tuple {}
+ | ^^^^^^^^^^^^
+ |
+help: try removing the `&` and `ref` parts
+ |
+LL - if let &(ref a, ..) = &tuple {}
+LL + if let (a, ..) = &tuple {}
+ |
+
+error: dereferencing a tuple pattern where every element takes a reference
+ --> $DIR/needless_borrowed_ref.rs:55:12
+ |
+LL | if let &TupleStruct(ref a, ..) = &tuple_struct {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try removing the `&` and `ref` parts
+ |
+LL - if let &TupleStruct(ref a, ..) = &tuple_struct {}
+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:57:12
+ |
+LL | if let &Struct {
+ | ____________^
+LL | | ref a,
+LL | | b: ref b,
+LL | | c: ref renamed,
+LL | | } = &s
+ | |_____^
+ |
+help: try removing the `&` and `ref` parts
+ |
+LL ~ if let Struct {
+LL ~ a,
+LL ~ b: b,
+LL ~ c: renamed,
+ |
+
+error: dereferencing a struct pattern where every field's pattern takes a reference
+ --> $DIR/needless_borrowed_ref.rs:64:12
+ |
+LL | if let &Struct { ref a, b: _, .. } = &s {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: try removing the `&` and `ref` parts
+ |
+LL - if let &Struct { ref a, b: _, .. } = &s {}
+LL + if let Struct { a, b: _, .. } = &s {}
+ |
+
+error: aborting due to 17 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_collect.fixed b/src/tools/clippy/tests/ui/needless_collect.fixed
index 6ecbbcb62..2659ad384 100644
--- a/src/tools/clippy/tests/ui/needless_collect.fixed
+++ b/src/tools/clippy/tests/ui/needless_collect.fixed
@@ -33,4 +33,33 @@ fn main() {
// `BinaryHeap` doesn't have `contains` method
sample.iter().count();
sample.iter().next().is_none();
+
+ // Don't lint string from str
+ let _ = ["", ""].into_iter().collect::<String>().is_empty();
+
+ let _ = sample.iter().next().is_none();
+ let _ = sample.iter().any(|x| x == &0);
+
+ struct VecWrapper<T>(Vec<T>);
+ impl<T> core::ops::Deref for VecWrapper<T> {
+ type Target = Vec<T>;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+ impl<T> IntoIterator for VecWrapper<T> {
+ type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
+ type Item = <Vec<T> as IntoIterator>::Item;
+ fn into_iter(self) -> Self::IntoIter {
+ self.0.into_iter()
+ }
+ }
+ impl<T> FromIterator<T> for VecWrapper<T> {
+ fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
+ Self(Vec::from_iter(iter))
+ }
+ }
+
+ let _ = sample.iter().next().is_none();
+ let _ = sample.iter().any(|x| x == &0);
}
diff --git a/src/tools/clippy/tests/ui/needless_collect.rs b/src/tools/clippy/tests/ui/needless_collect.rs
index 8dc69bcf5..535ec8298 100644
--- a/src/tools/clippy/tests/ui/needless_collect.rs
+++ b/src/tools/clippy/tests/ui/needless_collect.rs
@@ -33,4 +33,33 @@ fn main() {
// `BinaryHeap` doesn't have `contains` method
sample.iter().collect::<BinaryHeap<_>>().len();
sample.iter().collect::<BinaryHeap<_>>().is_empty();
+
+ // Don't lint string from str
+ let _ = ["", ""].into_iter().collect::<String>().is_empty();
+
+ let _ = sample.iter().collect::<HashSet<_>>().is_empty();
+ let _ = sample.iter().collect::<HashSet<_>>().contains(&&0);
+
+ struct VecWrapper<T>(Vec<T>);
+ impl<T> core::ops::Deref for VecWrapper<T> {
+ type Target = Vec<T>;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+ impl<T> IntoIterator for VecWrapper<T> {
+ type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
+ type Item = <Vec<T> as IntoIterator>::Item;
+ fn into_iter(self) -> Self::IntoIter {
+ self.0.into_iter()
+ }
+ }
+ impl<T> FromIterator<T> for VecWrapper<T> {
+ fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
+ Self(Vec::from_iter(iter))
+ }
+ }
+
+ let _ = sample.iter().collect::<VecWrapper<_>>().is_empty();
+ let _ = sample.iter().collect::<VecWrapper<_>>().contains(&&0);
}
diff --git a/src/tools/clippy/tests/ui/needless_collect.stderr b/src/tools/clippy/tests/ui/needless_collect.stderr
index 039091627..584d2a1d8 100644
--- a/src/tools/clippy/tests/ui/needless_collect.stderr
+++ b/src/tools/clippy/tests/ui/needless_collect.stderr
@@ -66,5 +66,29 @@ error: avoid using `collect()` when not needed
LL | sample.iter().collect::<BinaryHeap<_>>().is_empty();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
-error: aborting due to 11 previous errors
+error: avoid using `collect()` when not needed
+ --> $DIR/needless_collect.rs:40: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
+ |
+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
+ |
+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
+ |
+LL | let _ = sample.iter().collect::<VecWrapper<_>>().contains(&&0);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)`
+
+error: aborting due to 15 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.rs b/src/tools/clippy/tests/ui/needless_collect_indirect.rs
index 6d213b46c..fe4209e99 100644
--- a/src/tools/clippy/tests/ui/needless_collect_indirect.rs
+++ b/src/tools/clippy/tests/ui/needless_collect_indirect.rs
@@ -1,4 +1,5 @@
#![allow(clippy::uninlined_format_args)]
+#![warn(clippy::needless_collect)]
use std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
index 99e1b91d8..790d72590 100644
--- a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
+++ b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
@@ -1,5 +1,5 @@
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:7:39
+ --> $DIR/needless_collect_indirect.rs:8:39
|
LL | let indirect_iter = sample.iter().collect::<Vec<_>>();
| ^^^^^^^
@@ -14,7 +14,7 @@ LL ~ sample.iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:9:38
+ --> $DIR/needless_collect_indirect.rs:10:38
|
LL | let indirect_len = sample.iter().collect::<VecDeque<_>>();
| ^^^^^^^
@@ -28,7 +28,7 @@ LL ~ sample.iter().count();
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:11:40
+ --> $DIR/needless_collect_indirect.rs:12:40
|
LL | let indirect_empty = sample.iter().collect::<VecDeque<_>>();
| ^^^^^^^
@@ -42,7 +42,7 @@ LL ~ sample.iter().next().is_none();
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:13:43
+ --> $DIR/needless_collect_indirect.rs:14:43
|
LL | let indirect_contains = sample.iter().collect::<VecDeque<_>>();
| ^^^^^^^
@@ -56,7 +56,7 @@ LL ~ sample.iter().any(|x| x == &5);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:25:48
+ --> $DIR/needless_collect_indirect.rs:26:48
|
LL | let non_copy_contains = sample.into_iter().collect::<Vec<_>>();
| ^^^^^^^
@@ -70,7 +70,7 @@ LL ~ sample.into_iter().any(|x| x == a);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:54:51
+ --> $DIR/needless_collect_indirect.rs:55:51
|
LL | let buffer: Vec<&str> = string.split('/').collect();
| ^^^^^^^
@@ -84,7 +84,7 @@ LL ~ string.split('/').count()
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:59:55
+ --> $DIR/needless_collect_indirect.rs:60:55
|
LL | let indirect_len: VecDeque<_> = sample.iter().collect();
| ^^^^^^^
@@ -98,7 +98,7 @@ LL ~ sample.iter().count()
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:64:57
+ --> $DIR/needless_collect_indirect.rs:65:57
|
LL | let indirect_len: LinkedList<_> = sample.iter().collect();
| ^^^^^^^
@@ -112,7 +112,7 @@ LL ~ sample.iter().count()
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:69:57
+ --> $DIR/needless_collect_indirect.rs:70:57
|
LL | let indirect_len: BinaryHeap<_> = sample.iter().collect();
| ^^^^^^^
@@ -126,7 +126,7 @@ LL ~ sample.iter().count()
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:129:59
+ --> $DIR/needless_collect_indirect.rs:130:59
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -143,7 +143,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == i);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:154:59
+ --> $DIR/needless_collect_indirect.rs:155:59
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -160,7 +160,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:183:63
+ --> $DIR/needless_collect_indirect.rs:184:63
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -177,7 +177,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:219:59
+ --> $DIR/needless_collect_indirect.rs:220:59
|
LL | let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
| ^^^^^^^
@@ -195,7 +195,7 @@ LL ~ vec.iter().map(|k| k * k).any(|x| x == n);
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:244:26
+ --> $DIR/needless_collect_indirect.rs:245:26
|
LL | let w = v.iter().collect::<Vec<_>>();
| ^^^^^^^
@@ -211,7 +211,7 @@ LL ~ for _ in 0..v.iter().count() {
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:266:30
+ --> $DIR/needless_collect_indirect.rs:267:30
|
LL | let mut w = v.iter().collect::<Vec<_>>();
| ^^^^^^^
@@ -227,7 +227,7 @@ LL ~ while 1 == v.iter().count() {
|
error: avoid using `collect()` when not needed
- --> $DIR/needless_collect_indirect.rs:288:30
+ --> $DIR/needless_collect_indirect.rs:289:30
|
LL | let mut w = v.iter().collect::<Vec<_>>();
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs
index fc686b1da..2efc93675 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs
@@ -29,11 +29,20 @@ fn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 {
x
}
-// No error; multiple input refs.
-fn multiple_in_and_out_2<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
+// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
+// fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8
+// ^^^
+fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
x
}
+// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
+// fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8
+// ^^^
+fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 {
+ y
+}
+
// No error; multiple input refs
async fn func<'a>(args: &[&'a str]) -> Option<&'a str> {
args.get(0).cloned()
@@ -44,11 +53,20 @@ fn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 {
x
}
-// No error.
-fn deep_reference_1<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {
+// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
+// fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()>
+// ^^^
+fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {
Ok(x)
}
+// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
+// fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()>
+// ^^^
+fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> {
+ Ok(y)
+}
+
// No error; two input refs.
fn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 {
x.unwrap()
@@ -129,11 +147,20 @@ impl X {
&self.x
}
- // No error; multiple input refs.
- fn self_and_in_out<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
+ // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
+ // fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8
+ // ^^^
+ fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
&self.x
}
+ // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:
+ // fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8
+ // ^^^^^
+ fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {
+ x
+ }
+
fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}
// No error; same lifetimes on two params.
@@ -167,8 +194,19 @@ fn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {
unimplemented!()
}
-// No warning; two input lifetimes.
-fn struct_with_lt4<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
+// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
+// valid:
+// fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str
+// ^^
+fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
+ unimplemented!()
+}
+
+// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
+// valid:
+// fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str
+// ^^^^
+fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {
unimplemented!()
}
@@ -203,8 +241,19 @@ fn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {
unimplemented!()
}
-// No warning; two input lifetimes.
-fn alias_with_lt4<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
+// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
+// valid:
+// fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str
+// ^^
+fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
+ unimplemented!()
+}
+
+// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is
+// valid:
+// fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str
+// ^^^^^^^^^
+fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {
unimplemented!()
}
@@ -419,4 +468,31 @@ mod issue7296 {
}
}
+mod pr_9743_false_negative_fix {
+ #![allow(unused)]
+
+ fn foo<'a>(x: &'a u8, y: &'_ u8) {}
+
+ fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}
+}
+
+mod pr_9743_output_lifetime_checks {
+ #![allow(unused)]
+
+ // lint: only one input
+ fn one_input<'a>(x: &'a u8) -> &'a u8 {
+ unimplemented!()
+ }
+
+ // lint: multiple inputs, output would not be elided
+ fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {
+ unimplemented!()
+ }
+
+ // don't lint: multiple inputs, output would be elided (which would create an ambiguity)
+ fn multiple_inputs_output_would_be_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'a u8 {
+ unimplemented!()
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
index 3c428fd46..5a7cf13c8 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
@@ -1,4 +1,4 @@
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+error: the following explicit lifetimes could be elided: 'a, 'b
--> $DIR/needless_lifetimes.rs:11:1
|
LL | fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}
@@ -6,185 +6,311 @@ LL | fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}
|
= note: `-D clippy::needless-lifetimes` implied by `-D warnings`
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+error: the following explicit lifetimes could be elided: 'a, 'b
--> $DIR/needless_lifetimes.rs:13:1
|
LL | fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+error: the following explicit lifetimes could be elided: 'a
--> $DIR/needless_lifetimes.rs:23:1
|
LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:57:1
+error: the following explicit lifetimes could be elided: 'b
+ --> $DIR/needless_lifetimes.rs:35:1
+ |
+LL | fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:42:1
+ |
+LL | fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the following explicit lifetimes could be elided: 'b
+ --> $DIR/needless_lifetimes.rs:59:1
+ |
+LL | fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:66:1
+ |
+LL | fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:75:1
|
LL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:62:1
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:80:1
|
LL | fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:74:1
+error: the following explicit lifetimes could be elided: 'a, 'b
+ --> $DIR/needless_lifetimes.rs:92:1
|
LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: replace with `'_` in generic arguments such as here
+ --> $DIR/needless_lifetimes.rs:92:37
+ |
+LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
+ | ^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:98:1
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:116:1
|
LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: replace with `'_` in generic arguments such as here
+ --> $DIR/needless_lifetimes.rs:116:32
+ |
+LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
+ | ^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:128:5
+error: the following explicit lifetimes could be elided: 's
+ --> $DIR/needless_lifetimes.rs:146:5
|
LL | fn self_and_out<'s>(&'s self) -> &'s u8 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:137:5
+error: the following explicit lifetimes could be elided: 't
+ --> $DIR/needless_lifetimes.rs:153:5
+ |
+LL | fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the following explicit lifetimes could be elided: 's
+ --> $DIR/needless_lifetimes.rs:160:5
+ |
+LL | fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the following explicit lifetimes could be elided: 's, 't
+ --> $DIR/needless_lifetimes.rs:164:5
|
LL | fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:156:1
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:183:1
|
LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: replace with `'_` in generic arguments such as here
+ --> $DIR/needless_lifetimes.rs:183:33
+ |
+LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
+ | ^^
+
+error: the following explicit lifetimes could be elided: 'b
+ --> $DIR/needless_lifetimes.rs:201:1
+ |
+LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: replace with `'_` in generic arguments such as here
+ --> $DIR/needless_lifetimes.rs:201:43
+ |
+LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
+ | ^^
+
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:209:1
+ |
+LL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:186:1
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:224:1
|
LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:192:1
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:230:1
|
LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: replace with `'_` in generic arguments such as here
+ --> $DIR/needless_lifetimes.rs:230:37
+ |
+LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
+ | ^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:211:1
+error: the following explicit lifetimes could be elided: 'b
+ --> $DIR/needless_lifetimes.rs:248:1
+ |
+LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: replace with `'_` in generic arguments such as here
+ --> $DIR/needless_lifetimes.rs:248:47
+ |
+LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
+ | ^^
+
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:256:1
+ |
+LL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:260:1
|
LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:219:1
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:268:1
|
LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:255:1
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:304:1
|
LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: replace with `'_` in generic arguments such as here
+ --> $DIR/needless_lifetimes.rs:304:47
+ |
+LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
+ | ^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:262:9
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:311:9
|
LL | fn needless_lt<'a>(x: &'a u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:266:9
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:315:9
|
LL | fn needless_lt<'a>(_x: &'a u8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:279:9
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:328:9
|
LL | fn baz<'a>(&'a self) -> impl Foo + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:311:5
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:360:5
|
LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:320:5
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:369:5
|
LL | fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:332:5
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:381:5
|
LL | fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:347:5
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:396:5
|
LL | fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:360:5
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:409:5
|
LL | fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:363:5
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:412:5
|
LL | fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:385:9
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:434:9
|
LL | fn implicit<'a>(&'a self) -> &'a () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:388:9
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:437:9
|
LL | fn implicit_mut<'a>(&'a mut self) -> &'a () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:399:9
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:448:9
|
LL | fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:405:9
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:454:9
|
LL | fn implicit<'a>(&'a self) -> &'a ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:406:9
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:455:9
|
LL | fn implicit_provided<'a>(&'a self) -> &'a () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:415:9
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:464:9
|
LL | fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
- --> $DIR/needless_lifetimes.rs:416:9
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:465:9
|
LL | fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 31 previous errors
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:474:5
+ |
+LL | fn foo<'a>(x: &'a u8, y: &'_ u8) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:476:5
+ |
+LL | fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:483:5
+ |
+LL | fn one_input<'a>(x: &'a u8) -> &'a u8 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the following explicit lifetimes could be elided: 'a
+ --> $DIR/needless_lifetimes.rs:488:5
+ |
+LL | fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 45 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_question_mark.fixed b/src/tools/clippy/tests/ui/needless_question_mark.fixed
index ba9d15e59..7eaca5719 100644
--- a/src/tools/clippy/tests/ui/needless_question_mark.fixed
+++ b/src/tools/clippy/tests/ui/needless_question_mark.fixed
@@ -8,7 +8,6 @@
dead_code,
unused_must_use
)]
-#![feature(custom_inner_attributes)]
struct TO {
magic: Option<usize>,
diff --git a/src/tools/clippy/tests/ui/needless_question_mark.rs b/src/tools/clippy/tests/ui/needless_question_mark.rs
index 3a6523e8f..960bc7b78 100644
--- a/src/tools/clippy/tests/ui/needless_question_mark.rs
+++ b/src/tools/clippy/tests/ui/needless_question_mark.rs
@@ -8,7 +8,6 @@
dead_code,
unused_must_use
)]
-#![feature(custom_inner_attributes)]
struct TO {
magic: Option<usize>,
diff --git a/src/tools/clippy/tests/ui/needless_question_mark.stderr b/src/tools/clippy/tests/ui/needless_question_mark.stderr
index f8308e24e..d1f89e326 100644
--- a/src/tools/clippy/tests/ui/needless_question_mark.stderr
+++ b/src/tools/clippy/tests/ui/needless_question_mark.stderr
@@ -1,5 +1,5 @@
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:23:12
+ --> $DIR/needless_question_mark.rs:22:12
|
LL | return Some(to.magic?);
| ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic`
@@ -7,67 +7,67 @@ LL | return Some(to.magic?);
= note: `-D clippy::needless-question-mark` implied by `-D warnings`
error: question mark operator is useless here
- --> $DIR/needless_question_mark.rs:31:12
+ --> $DIR/needless_question_mark.rs:30: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:36:5
+ --> $DIR/needless_question_mark.rs:35: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:41:21
+ --> $DIR/needless_question_mark.rs:40: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:50:9
+ --> $DIR/needless_question_mark.rs:49: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:55:12
+ --> $DIR/needless_question_mark.rs:54: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:62:12
+ --> $DIR/needless_question_mark.rs:61: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:66:5
+ --> $DIR/needless_question_mark.rs:65: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:70:21
+ --> $DIR/needless_question_mark.rs:69: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:78:9
+ --> $DIR/needless_question_mark.rs:77: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:85:16
+ --> $DIR/needless_question_mark.rs:84: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:120:27
+ --> $DIR/needless_question_mark.rs:119:27
|
LL | || -> Option<_> { Some(Some($expr)?) }()
| ^^^^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `Some($expr)`
@@ -78,13 +78,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:131:5
+ --> $DIR/needless_question_mark.rs:130: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:139:5
+ --> $DIR/needless_question_mark.rs:138:5
|
LL | Ok(s.magic?)
| ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `s.magic`
diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed
index d2163b14f..4386aaec4 100644
--- a/src/tools/clippy/tests/ui/needless_return.fixed
+++ b/src/tools/clippy/tests/ui/needless_return.fixed
@@ -59,14 +59,11 @@ fn test_macro_call() -> i32 {
}
fn test_void_fun() {
-
}
fn test_void_if_fun(b: bool) {
if b {
-
} else {
-
}
}
@@ -82,7 +79,6 @@ fn test_nested_match(x: u32) {
0 => (),
1 => {
let _ = 42;
-
},
_ => (),
}
@@ -126,7 +122,6 @@ mod issue6501 {
fn test_closure() {
let _ = || {
-
};
let _ = || {};
}
@@ -179,14 +174,11 @@ async fn async_test_macro_call() -> i32 {
}
async fn async_test_void_fun() {
-
}
async fn async_test_void_if_fun(b: bool) {
if b {
-
} else {
-
}
}
@@ -269,4 +261,15 @@ fn issue9503(x: usize) -> isize {
}
}
+mod issue9416 {
+ pub fn with_newline() {
+ let _ = 42;
+ }
+
+ #[rustfmt::skip]
+ pub fn oneline() {
+ let _ = 42;
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs
index 114414b5f..666dc54b7 100644
--- a/src/tools/clippy/tests/ui/needless_return.rs
+++ b/src/tools/clippy/tests/ui/needless_return.rs
@@ -269,4 +269,17 @@ fn issue9503(x: usize) -> isize {
};
}
+mod issue9416 {
+ pub fn with_newline() {
+ let _ = 42;
+
+ return;
+ }
+
+ #[rustfmt::skip]
+ pub fn oneline() {
+ let _ = 42; return;
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr
index 047fb6c23..a8b5d86cd 100644
--- a/src/tools/clippy/tests/ui/needless_return.stderr
+++ b/src/tools/clippy/tests/ui/needless_return.stderr
@@ -72,26 +72,32 @@ LL | return the_answer!();
= help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:62:5
+ --> $DIR/needless_return.rs:61:21
|
-LL | return;
- | ^^^^^^
+LL | fn test_void_fun() {
+ | _____________________^
+LL | | return;
+ | |__________^
|
= help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:67:9
+ --> $DIR/needless_return.rs:66:11
|
-LL | return;
- | ^^^^^^
+LL | if b {
+ | ___________^
+LL | | return;
+ | |______________^
|
= help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:69:9
+ --> $DIR/needless_return.rs:68:13
|
-LL | return;
- | ^^^^^^
+LL | } else {
+ | _____________^
+LL | | return;
+ | |______________^
|
= help: remove `return`
@@ -104,10 +110,12 @@ LL | _ => return,
= help: replace `return` with a unit value
error: unneeded `return` statement
- --> $DIR/needless_return.rs:85:13
+ --> $DIR/needless_return.rs:84:24
|
-LL | return;
- | ^^^^^^
+LL | let _ = 42;
+ | ________________________^
+LL | | return;
+ | |__________________^
|
= help: remove `return`
@@ -144,10 +152,12 @@ LL | bar.unwrap_or_else(|_| return)
= help: replace `return` with an empty block
error: unneeded `return` statement
- --> $DIR/needless_return.rs:129:13
+ --> $DIR/needless_return.rs:128:21
|
-LL | return;
- | ^^^^^^
+LL | let _ = || {
+ | _____________________^
+LL | | return;
+ | |__________________^
|
= help: remove `return`
@@ -240,26 +250,32 @@ LL | return the_answer!();
= help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:182:5
+ --> $DIR/needless_return.rs:181:33
|
-LL | return;
- | ^^^^^^
+LL | async fn async_test_void_fun() {
+ | _________________________________^
+LL | | return;
+ | |__________^
|
= help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:187:9
+ --> $DIR/needless_return.rs:186:11
|
-LL | return;
- | ^^^^^^
+LL | if b {
+ | ___________^
+LL | | return;
+ | |______________^
|
= help: remove `return`
error: unneeded `return` statement
- --> $DIR/needless_return.rs:189:9
+ --> $DIR/needless_return.rs:188:13
|
-LL | return;
- | ^^^^^^
+LL | } else {
+ | _____________^
+LL | | return;
+ | |______________^
|
= help: remove `return`
@@ -351,5 +367,24 @@ LL | return !*(x as *const isize);
|
= help: remove `return`
-error: aborting due to 44 previous errors
+error: unneeded `return` statement
+ --> $DIR/needless_return.rs:274:20
+ |
+LL | let _ = 42;
+ | ____________________^
+LL | |
+LL | | return;
+ | |______________^
+ |
+ = help: remove `return`
+
+error: unneeded `return` statement
+ --> $DIR/needless_return.rs:281:20
+ |
+LL | let _ = 42; return;
+ | ^^^^^^^
+ |
+ = help: remove `return`
+
+error: aborting due to 46 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_splitn.fixed b/src/tools/clippy/tests/ui/needless_splitn.fixed
index 61f5fc4e6..5496031fe 100644
--- a/src/tools/clippy/tests/ui/needless_splitn.fixed
+++ b/src/tools/clippy/tests/ui/needless_splitn.fixed
@@ -1,7 +1,6 @@
// run-rustfix
// edition:2018
-#![feature(custom_inner_attributes)]
#![warn(clippy::needless_splitn)]
#![allow(clippy::iter_skip_next, clippy::iter_nth_zero, clippy::manual_split_once)]
@@ -40,8 +39,8 @@ fn _question_mark(s: &str) -> Option<()> {
Some(())
}
+#[clippy::msrv = "1.51"]
fn _test_msrv() {
- #![clippy::msrv = "1.51"]
// `manual_split_once` MSRV shouldn't apply to `needless_splitn`
let _ = "key=value".split('=').nth(0).unwrap();
}
diff --git a/src/tools/clippy/tests/ui/needless_splitn.rs b/src/tools/clippy/tests/ui/needless_splitn.rs
index 71d9a7077..35c2465ba 100644
--- a/src/tools/clippy/tests/ui/needless_splitn.rs
+++ b/src/tools/clippy/tests/ui/needless_splitn.rs
@@ -1,7 +1,6 @@
// run-rustfix
// edition:2018
-#![feature(custom_inner_attributes)]
#![warn(clippy::needless_splitn)]
#![allow(clippy::iter_skip_next, clippy::iter_nth_zero, clippy::manual_split_once)]
@@ -40,8 +39,8 @@ fn _question_mark(s: &str) -> Option<()> {
Some(())
}
+#[clippy::msrv = "1.51"]
fn _test_msrv() {
- #![clippy::msrv = "1.51"]
// `manual_split_once` MSRV shouldn't apply to `needless_splitn`
let _ = "key=value".splitn(2, '=').nth(0).unwrap();
}
diff --git a/src/tools/clippy/tests/ui/needless_splitn.stderr b/src/tools/clippy/tests/ui/needless_splitn.stderr
index f112b29e7..f607d8e1a 100644
--- a/src/tools/clippy/tests/ui/needless_splitn.stderr
+++ b/src/tools/clippy/tests/ui/needless_splitn.stderr
@@ -1,5 +1,5 @@
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:15:13
+ --> $DIR/needless_splitn.rs:14:13
|
LL | let _ = str.splitn(2, '=').next();
| ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')`
@@ -7,73 +7,73 @@ LL | let _ = str.splitn(2, '=').next();
= note: `-D clippy::needless-splitn` implied by `-D warnings`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:16:13
+ --> $DIR/needless_splitn.rs:15:13
|
LL | let _ = str.splitn(2, '=').nth(0);
| ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:19:18
+ --> $DIR/needless_splitn.rs:18:18
|
LL | let (_, _) = str.splitn(3, '=').next_tuple().unwrap();
| ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')`
error: unnecessary use of `rsplitn`
- --> $DIR/needless_splitn.rs:22:13
+ --> $DIR/needless_splitn.rs:21:13
|
LL | let _ = str.rsplitn(2, '=').next();
| ^^^^^^^^^^^^^^^^^^^ help: try this: `str.rsplit('=')`
error: unnecessary use of `rsplitn`
- --> $DIR/needless_splitn.rs:23:13
+ --> $DIR/needless_splitn.rs:22:13
|
LL | let _ = str.rsplitn(2, '=').nth(0);
| ^^^^^^^^^^^^^^^^^^^ help: try this: `str.rsplit('=')`
error: unnecessary use of `rsplitn`
- --> $DIR/needless_splitn.rs:26:18
+ --> $DIR/needless_splitn.rs:25:18
|
LL | let (_, _) = str.rsplitn(3, '=').next_tuple().unwrap();
| ^^^^^^^^^^^^^^^^^^^ help: try this: `str.rsplit('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:28:13
+ --> $DIR/needless_splitn.rs:27:13
|
LL | let _ = str.splitn(5, '=').next();
| ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:29:13
+ --> $DIR/needless_splitn.rs:28:13
|
LL | let _ = str.splitn(5, '=').nth(3);
| ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:35:13
+ --> $DIR/needless_splitn.rs:34:13
|
LL | let _ = s.splitn(2, '=').next()?;
| ^^^^^^^^^^^^^^^^ help: try this: `s.split('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:36:13
+ --> $DIR/needless_splitn.rs:35:13
|
LL | let _ = s.splitn(2, '=').nth(0)?;
| ^^^^^^^^^^^^^^^^ help: try this: `s.split('=')`
error: unnecessary use of `rsplitn`
- --> $DIR/needless_splitn.rs:37:13
+ --> $DIR/needless_splitn.rs:36:13
|
LL | let _ = s.rsplitn(2, '=').next()?;
| ^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit('=')`
error: unnecessary use of `rsplitn`
- --> $DIR/needless_splitn.rs:38:13
+ --> $DIR/needless_splitn.rs:37:13
|
LL | let _ = s.rsplitn(2, '=').nth(0)?;
| ^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit('=')`
error: unnecessary use of `splitn`
- --> $DIR/needless_splitn.rs:46:13
+ --> $DIR/needless_splitn.rs:45:13
|
LL | let _ = "key=value".splitn(2, '=').nth(0).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split('=')`
diff --git a/src/tools/clippy/tests/ui/never_loop.rs b/src/tools/clippy/tests/ui/never_loop.rs
index 3dbef1989..28e8f459d 100644
--- a/src/tools/clippy/tests/ui/never_loop.rs
+++ b/src/tools/clippy/tests/ui/never_loop.rs
@@ -229,6 +229,27 @@ pub fn test18() {
};
}
+// Issue #9831: unconditional break to internal labeled block
+pub fn test19() {
+ fn thing(iter: impl Iterator) {
+ for _ in iter {
+ 'b: {
+ break 'b;
+ }
+ }
+ }
+}
+
+pub fn test20() {
+ 'a: loop {
+ 'b: {
+ break 'b 'c: {
+ break 'a;
+ };
+ }
+ }
+}
+
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 3033f0192..b7029bf8b 100644
--- a/src/tools/clippy/tests/ui/never_loop.stderr
+++ b/src/tools/clippy/tests/ui/never_loop.stderr
@@ -114,5 +114,17 @@ LL | | break x;
LL | | };
| |_____^
-error: aborting due to 10 previous errors
+error: this loop never actually loops
+ --> $DIR/never_loop.rs:244:5
+ |
+LL | / 'a: loop {
+LL | | 'b: {
+LL | | break 'b 'c: {
+LL | | break 'a;
+LL | | };
+LL | | }
+LL | | }
+ | |_____^
+
+error: aborting due to 11 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 2f315ffe2..beec42f08 100644
--- a/src/tools/clippy/tests/ui/new_ret_no_self.rs
+++ b/src/tools/clippy/tests/ui/new_ret_no_self.rs
@@ -1,3 +1,4 @@
+#![feature(type_alias_impl_trait)]
#![warn(clippy::new_ret_no_self)]
#![allow(dead_code)]
@@ -350,3 +351,75 @@ impl RetOtherSelf<T> {
RetOtherSelf(RetOtherSelfWrapper(t))
}
}
+
+mod issue7344 {
+ struct RetImplTraitSelf<T>(T);
+
+ impl<T> RetImplTraitSelf<T> {
+ // should not trigger lint
+ fn new(t: T) -> impl Into<Self> {
+ Self(t)
+ }
+ }
+
+ struct RetImplTraitNoSelf<T>(T);
+
+ impl<T> RetImplTraitNoSelf<T> {
+ // should trigger lint
+ fn new(t: T) -> impl Into<i32> {
+ 1
+ }
+ }
+
+ trait Trait2<T, U> {}
+ impl<T, U> Trait2<T, U> for () {}
+
+ struct RetImplTraitSelf2<T>(T);
+
+ impl<T> RetImplTraitSelf2<T> {
+ // should not trigger lint
+ fn new(t: T) -> impl Trait2<(), Self> {
+ unimplemented!()
+ }
+ }
+
+ struct RetImplTraitNoSelf2<T>(T);
+
+ impl<T> RetImplTraitNoSelf2<T> {
+ // should trigger lint
+ fn new(t: T) -> impl Trait2<(), i32> {
+ unimplemented!()
+ }
+ }
+
+ struct RetImplTraitSelfAdt<'a>(&'a str);
+
+ impl<'a> RetImplTraitSelfAdt<'a> {
+ // should not trigger lint
+ fn new<'b: 'a>(s: &'b str) -> impl Into<RetImplTraitSelfAdt<'b>> {
+ RetImplTraitSelfAdt(s)
+ }
+ }
+}
+
+mod issue10041 {
+ struct Bomb;
+
+ impl Bomb {
+ // Hidden <Rhs = Self> default generic paramter.
+ pub fn new() -> impl PartialOrd {
+ 0i32
+ }
+ }
+
+ // TAIT with self-referencing bounds
+ type X = impl std::ops::Add<Output = X>;
+
+ struct Bomb2;
+
+ impl Bomb2 {
+ pub fn new() -> X {
+ 0i32
+ }
+ }
+}
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 8217bc618..2eaebfb5c 100644
--- a/src/tools/clippy/tests/ui/new_ret_no_self.stderr
+++ b/src/tools/clippy/tests/ui/new_ret_no_self.stderr
@@ -1,5 +1,5 @@
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:49:5
+ --> $DIR/new_ret_no_self.rs:50:5
|
LL | / pub fn new(_: String) -> impl R<Item = u32> {
LL | | S3
@@ -9,7 +9,7 @@ LL | | }
= note: `-D clippy::new-ret-no-self` implied by `-D warnings`
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:81:5
+ --> $DIR/new_ret_no_self.rs:82:5
|
LL | / pub fn new() -> u32 {
LL | | unimplemented!();
@@ -17,7 +17,7 @@ LL | | }
| |_____^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:90:5
+ --> $DIR/new_ret_no_self.rs:91:5
|
LL | / pub fn new(_: String) -> u32 {
LL | | unimplemented!();
@@ -25,7 +25,7 @@ LL | | }
| |_____^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:126:5
+ --> $DIR/new_ret_no_self.rs:127:5
|
LL | / pub fn new() -> (u32, u32) {
LL | | unimplemented!();
@@ -33,7 +33,7 @@ LL | | }
| |_____^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:153:5
+ --> $DIR/new_ret_no_self.rs:154:5
|
LL | / pub fn new() -> *mut V {
LL | | unimplemented!();
@@ -41,7 +41,7 @@ LL | | }
| |_____^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:171:5
+ --> $DIR/new_ret_no_self.rs:172:5
|
LL | / pub fn new() -> Option<u32> {
LL | | unimplemented!();
@@ -49,19 +49,19 @@ LL | | }
| |_____^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:224:9
+ --> $DIR/new_ret_no_self.rs:225:9
|
LL | fn new() -> String;
| ^^^^^^^^^^^^^^^^^^^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:236:9
+ --> $DIR/new_ret_no_self.rs:237:9
|
LL | fn new(_: String) -> String;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:271:9
+ --> $DIR/new_ret_no_self.rs:272:9
|
LL | / fn new() -> (u32, u32) {
LL | | unimplemented!();
@@ -69,12 +69,44 @@ LL | | }
| |_________^
error: methods called `new` usually return `Self`
- --> $DIR/new_ret_no_self.rs:298:9
+ --> $DIR/new_ret_no_self.rs:299:9
|
LL | / fn new() -> *mut V {
LL | | unimplemented!();
LL | | }
| |_________^
-error: aborting due to 10 previous errors
+error: methods called `new` usually return `Self`
+ --> $DIR/new_ret_no_self.rs:369:9
+ |
+LL | / fn new(t: T) -> impl Into<i32> {
+LL | | 1
+LL | | }
+ | |_________^
+
+error: methods called `new` usually return `Self`
+ --> $DIR/new_ret_no_self.rs:390:9
+ |
+LL | / fn new(t: T) -> impl Trait2<(), i32> {
+LL | | unimplemented!()
+LL | | }
+ | |_________^
+
+error: methods called `new` usually return `Self`
+ --> $DIR/new_ret_no_self.rs:410:9
+ |
+LL | / pub fn new() -> impl PartialOrd {
+LL | | 0i32
+LL | | }
+ | |_________^
+
+error: methods called `new` usually return `Self`
+ --> $DIR/new_ret_no_self.rs:421:9
+ |
+LL | / pub fn new() -> X {
+LL | | 0i32
+LL | | }
+ | |_________^
+
+error: aborting due to 14 previous errors
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 bc376d0d7..d124d133f 100644
--- a/src/tools/clippy/tests/ui/option_as_ref_deref.fixed
+++ b/src/tools/clippy/tests/ui/option_as_ref_deref.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(unused, clippy::redundant_clone)]
#![warn(clippy::option_as_ref_deref)]
@@ -44,16 +43,14 @@ fn main() {
let _ = opt.as_deref();
}
+#[clippy::msrv = "1.39"]
fn msrv_1_39() {
- #![clippy::msrv = "1.39"]
-
let opt = Some(String::from("123"));
let _ = opt.as_ref().map(String::as_str);
}
+#[clippy::msrv = "1.40"]
fn msrv_1_40() {
- #![clippy::msrv = "1.40"]
-
let opt = Some(String::from("123"));
let _ = opt.as_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 ba3a2eedc..86e354c67 100644
--- a/src/tools/clippy/tests/ui/option_as_ref_deref.rs
+++ b/src/tools/clippy/tests/ui/option_as_ref_deref.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(unused, clippy::redundant_clone)]
#![warn(clippy::option_as_ref_deref)]
@@ -47,16 +46,14 @@ fn main() {
let _ = opt.as_ref().map(std::ops::Deref::deref);
}
+#[clippy::msrv = "1.39"]
fn msrv_1_39() {
- #![clippy::msrv = "1.39"]
-
let opt = Some(String::from("123"));
let _ = opt.as_ref().map(String::as_str);
}
+#[clippy::msrv = "1.40"]
fn msrv_1_40() {
- #![clippy::msrv = "1.40"]
-
let opt = Some(String::from("123"));
let _ = opt.as_ref().map(String::as_str);
}
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 7de8b3b6b..e471b56ee 100644
--- a/src/tools/clippy/tests/ui/option_as_ref_deref.stderr
+++ b/src/tools/clippy/tests/ui/option_as_ref_deref.stderr
@@ -1,5 +1,5 @@
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:14:13
+ --> $DIR/option_as_ref_deref.rs:13:13
|
LL | let _ = opt.clone().as_ref().map(Deref::deref).map(str::len);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.clone().as_deref()`
@@ -7,7 +7,7 @@ LL | let _ = opt.clone().as_ref().map(Deref::deref).map(str::len);
= note: `-D clippy::option-as-ref-deref` implied by `-D warnings`
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:17:13
+ --> $DIR/option_as_ref_deref.rs:16:13
|
LL | let _ = opt.clone()
| _____________^
@@ -17,97 +17,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:23:13
+ --> $DIR/option_as_ref_deref.rs:22: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:25:13
+ --> $DIR/option_as_ref_deref.rs:24: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:26:13
+ --> $DIR/option_as_ref_deref.rs:25: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:27:13
+ --> $DIR/option_as_ref_deref.rs:26: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:28:13
+ --> $DIR/option_as_ref_deref.rs:27: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:29:13
+ --> $DIR/option_as_ref_deref.rs:28: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:30:13
+ --> $DIR/option_as_ref_deref.rs:29: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:31:13
+ --> $DIR/option_as_ref_deref.rs:30: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:32:13
+ --> $DIR/option_as_ref_deref.rs:31: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:33:13
+ --> $DIR/option_as_ref_deref.rs:32: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:35:13
+ --> $DIR/option_as_ref_deref.rs:34: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:36:13
+ --> $DIR/option_as_ref_deref.rs:35: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:43:13
+ --> $DIR/option_as_ref_deref.rs:42: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:44:13
+ --> $DIR/option_as_ref_deref.rs:43: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:47:13
+ --> $DIR/option_as_ref_deref.rs:46: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:61:13
+ --> $DIR/option_as_ref_deref.rs:58: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_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed
index f15ac551b..0456005dc 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.fixed
+++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed
@@ -189,3 +189,12 @@ fn main() {
let _ = res.map_or(1, |a| a + 1);
let _ = res.map_or(5, |a| a + 1);
}
+
+#[allow(dead_code)]
+fn issue9742() -> Option<&'static str> {
+ // should not lint because of guards
+ match Some("foo ") {
+ Some(name) if name.starts_with("foo") => Some(name.trim()),
+ _ => None,
+ }
+}
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 9eeaea12d..23b148752 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.rs
+++ b/src/tools/clippy/tests/ui/option_if_let_else.rs
@@ -230,3 +230,12 @@ fn main() {
};
let _ = if let Ok(a) = res { a + 1 } else { 5 };
}
+
+#[allow(dead_code)]
+fn issue9742() -> Option<&'static str> {
+ // should not lint because of guards
+ match Some("foo ") {
+ Some(name) if name.starts_with("foo") => Some(name.trim()),
+ _ => None,
+ }
+}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed
index 23b1aa8be..be9a65506 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/or_fun_call.fixed
@@ -236,4 +236,20 @@ mod issue9608 {
}
}
+mod issue8993 {
+ fn g() -> i32 {
+ 3
+ }
+
+ fn f(n: i32) -> i32 {
+ n
+ }
+
+ fn test_map_or() {
+ let _ = Some(4).map_or_else(g, |v| v);
+ let _ = Some(4).map_or_else(g, f);
+ let _ = Some(4).map_or(0, f);
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.rs b/src/tools/clippy/tests/ui/or_fun_call.rs
index 039998f22..628c97046 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.rs
+++ b/src/tools/clippy/tests/ui/or_fun_call.rs
@@ -236,4 +236,20 @@ mod issue9608 {
}
}
+mod issue8993 {
+ fn g() -> i32 {
+ 3
+ }
+
+ fn f(n: i32) -> i32 {
+ n
+ }
+
+ fn test_map_or() {
+ let _ = Some(4).map_or(g(), |v| v);
+ let _ = Some(4).map_or(g(), f);
+ let _ = Some(4).map_or(0, f);
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr
index 113ba150c..ba3001db7 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/or_fun_call.stderr
@@ -156,5 +156,17 @@ error: use of `unwrap_or` followed by a call to `new`
LL | .unwrap_or(String::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_default()`
-error: aborting due to 26 previous errors
+error: use of `map_or` followed by a function call
+ --> $DIR/or_fun_call.rs:249:25
+ |
+LL | let _ = Some(4).map_or(g(), |v| v);
+ | ^^^^^^^^^^^^^^^^^^ help: try this: `map_or_else(g, |v| v)`
+
+error: use of `map_or` followed by a function call
+ --> $DIR/or_fun_call.rs:250:25
+ |
+LL | let _ = Some(4).map_or(g(), f);
+ | ^^^^^^^^^^^^^^ help: try this: `map_or_else(g, f)`
+
+error: aborting due to 28 previous errors
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
index bea6be66a..df36a9b84 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
@@ -2,7 +2,6 @@
// aux-build:macro_rules.rs
#![warn(clippy::ptr_as_ptr)]
-#![feature(custom_inner_attributes)]
extern crate macro_rules;
@@ -45,8 +44,8 @@ fn main() {
let _ = macro_rules::ptr_as_ptr_cast!(ptr);
}
+#[clippy::msrv = "1.37"]
fn _msrv_1_37() {
- #![clippy::msrv = "1.37"]
let ptr: *const u32 = &42_u32;
let mut_ptr: *mut u32 = &mut 42_u32;
@@ -55,8 +54,8 @@ fn _msrv_1_37() {
let _ = mut_ptr as *mut i32;
}
+#[clippy::msrv = "1.38"]
fn _msrv_1_38() {
- #![clippy::msrv = "1.38"]
let ptr: *const u32 = &42_u32;
let mut_ptr: *mut u32 = &mut 42_u32;
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.rs b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
index ca2616b00..302c66462 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
@@ -2,7 +2,6 @@
// aux-build:macro_rules.rs
#![warn(clippy::ptr_as_ptr)]
-#![feature(custom_inner_attributes)]
extern crate macro_rules;
@@ -45,8 +44,8 @@ fn main() {
let _ = macro_rules::ptr_as_ptr_cast!(ptr);
}
+#[clippy::msrv = "1.37"]
fn _msrv_1_37() {
- #![clippy::msrv = "1.37"]
let ptr: *const u32 = &42_u32;
let mut_ptr: *mut u32 = &mut 42_u32;
@@ -55,8 +54,8 @@ fn _msrv_1_37() {
let _ = mut_ptr as *mut i32;
}
+#[clippy::msrv = "1.38"]
fn _msrv_1_38() {
- #![clippy::msrv = "1.38"]
let ptr: *const u32 = &42_u32;
let mut_ptr: *mut u32 = &mut 42_u32;
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
index c58c55cfd..a68e1cab6 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
@@ -1,5 +1,5 @@
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:19:13
+ --> $DIR/ptr_as_ptr.rs:18:13
|
LL | let _ = ptr as *const i32;
| ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
@@ -7,31 +7,31 @@ LL | let _ = ptr as *const i32;
= note: `-D clippy::ptr-as-ptr` implied by `-D warnings`
error: `as` casting between raw pointers without changing its mutability
- --> $DIR/ptr_as_ptr.rs:20:13
+ --> $DIR/ptr_as_ptr.rs:19: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:25:17
+ --> $DIR/ptr_as_ptr.rs:24: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:38:25
+ --> $DIR/ptr_as_ptr.rs:37: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:39:23
+ --> $DIR/ptr_as_ptr.rs:38: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:11:9
+ --> $DIR/ptr_as_ptr.rs:10:9
|
LL | $ptr as *const i32
| ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::<i32>()`
@@ -42,13 +42,13 @@ LL | let _ = cast_it!(ptr);
= note: this error originates in the macro `cast_it` (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:63:13
+ --> $DIR/ptr_as_ptr.rs:62: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:64:13
+ --> $DIR/ptr_as_ptr.rs:63: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/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed
index 993389232..5c49d46da 100644
--- a/src/tools/clippy/tests/ui/question_mark.fixed
+++ b/src/tools/clippy/tests/ui/question_mark.fixed
@@ -134,6 +134,9 @@ fn result_func(x: Result<i32, i32>) -> Result<i32, i32> {
return func_returning_result();
}
+ // no warning
+ let _ = if let Err(e) = x { Err(e) } else { Ok(0) };
+
Ok(y)
}
diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs
index 9ae0d8882..d057df6a9 100644
--- a/src/tools/clippy/tests/ui/question_mark.rs
+++ b/src/tools/clippy/tests/ui/question_mark.rs
@@ -166,6 +166,9 @@ fn result_func(x: Result<i32, i32>) -> Result<i32, i32> {
return func_returning_result();
}
+ // no warning
+ let _ = if let Err(e) = x { Err(e) } else { Ok(0) };
+
Ok(y)
}
diff --git a/src/tools/clippy/tests/ui/question_mark.stderr b/src/tools/clippy/tests/ui/question_mark.stderr
index 1b6cd524b..23172d7e5 100644
--- a/src/tools/clippy/tests/ui/question_mark.stderr
+++ b/src/tools/clippy/tests/ui/question_mark.stderr
@@ -115,7 +115,7 @@ LL | | }
| |_____^ help: replace it with: `x?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:193:5
+ --> $DIR/question_mark.rs:196:5
|
LL | / if let Err(err) = func_returning_result() {
LL | | return Err(err);
@@ -123,7 +123,7 @@ LL | | }
| |_____^ help: replace it with: `func_returning_result()?;`
error: this block may be rewritten with the `?` operator
- --> $DIR/question_mark.rs:200:5
+ --> $DIR/question_mark.rs:203:5
|
LL | / if let Err(err) = func_returning_result() {
LL | | return Err(err);
diff --git a/src/tools/clippy/tests/ui/range_contains.fixed b/src/tools/clippy/tests/ui/range_contains.fixed
index 824f00cb9..4923731fe 100644
--- a/src/tools/clippy/tests/ui/range_contains.fixed
+++ b/src/tools/clippy/tests/ui/range_contains.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_range_contains)]
#![allow(unused)]
#![allow(clippy::no_effect)]
@@ -65,16 +64,14 @@ pub const fn in_range(a: i32) -> bool {
3 <= a && a <= 20
}
+#[clippy::msrv = "1.34"]
fn msrv_1_34() {
- #![clippy::msrv = "1.34"]
-
let x = 5;
x >= 8 && x < 34;
}
+#[clippy::msrv = "1.35"]
fn msrv_1_35() {
- #![clippy::msrv = "1.35"]
-
let x = 5;
(8..35).contains(&x);
}
diff --git a/src/tools/clippy/tests/ui/range_contains.rs b/src/tools/clippy/tests/ui/range_contains.rs
index df925eead..d623ccb5d 100644
--- a/src/tools/clippy/tests/ui/range_contains.rs
+++ b/src/tools/clippy/tests/ui/range_contains.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::manual_range_contains)]
#![allow(unused)]
#![allow(clippy::no_effect)]
@@ -65,16 +64,14 @@ pub const fn in_range(a: i32) -> bool {
3 <= a && a <= 20
}
+#[clippy::msrv = "1.34"]
fn msrv_1_34() {
- #![clippy::msrv = "1.34"]
-
let x = 5;
x >= 8 && x < 34;
}
+#[clippy::msrv = "1.35"]
fn msrv_1_35() {
- #![clippy::msrv = "1.35"]
-
let x = 5;
x >= 8 && x < 35;
}
diff --git a/src/tools/clippy/tests/ui/range_contains.stderr b/src/tools/clippy/tests/ui/range_contains.stderr
index 9689e665b..ea34023a4 100644
--- a/src/tools/clippy/tests/ui/range_contains.stderr
+++ b/src/tools/clippy/tests/ui/range_contains.stderr
@@ -1,5 +1,5 @@
error: manual `Range::contains` implementation
- --> $DIR/range_contains.rs:14:5
+ --> $DIR/range_contains.rs:13:5
|
LL | x >= 8 && x < 12;
| ^^^^^^^^^^^^^^^^ help: use: `(8..12).contains(&x)`
@@ -7,121 +7,121 @@ LL | x >= 8 && x < 12;
= note: `-D clippy::manual-range-contains` implied by `-D warnings`
error: manual `Range::contains` implementation
- --> $DIR/range_contains.rs:15: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:16: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:19: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:20: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:21: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:24: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:25: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:26: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:29: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:30: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:31: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:46: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:47: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:50: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:52: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:57: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:57: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:58: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:58: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:79: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/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
index 7cd687c95..c0e49ff4c 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
@@ -25,4 +25,16 @@ fn main() {
x * y
};
let d = async { something().await };
+
+ macro_rules! m {
+ () => {
+ 0
+ };
+ }
+ macro_rules! m2 {
+ () => {
+ m!()
+ };
+ }
+ m2!();
}
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 37e4d2238..9e6e54348 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
@@ -25,4 +25,16 @@ fn main() {
x * y
})();
let d = (async || something().await)();
+
+ macro_rules! m {
+ () => {
+ (|| 0)()
+ };
+ }
+ macro_rules! m2 {
+ () => {
+ (|| m!())()
+ };
+ }
+ m2!();
}
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 56a8e57c0..d71bcba2a 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
@@ -52,5 +52,27 @@ error: try not to call a closure in the expression where it is declared
LL | let d = (async || something().await)();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }`
-error: aborting due to 4 previous errors
+error: try not to call a closure in the expression where it is declared
+ --> $DIR/redundant_closure_call_fixable.rs:36:13
+ |
+LL | (|| m!())()
+ | ^^^^^^^^^^^ help: try doing something like: `m!()`
+...
+LL | m2!();
+ | ----- in this macro invocation
+ |
+ = 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:31:13
+ |
+LL | (|| 0)()
+ | ^^^^^^^^ help: try doing something like: `0`
+...
+LL | m2!();
+ | ----- in this macro invocation
+ |
+ = 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: aborting due to 6 previous errors
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.fixed b/src/tools/clippy/tests/ui/redundant_field_names.fixed
index 34ab552cb..ec7f8ae92 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.fixed
+++ b/src/tools/clippy/tests/ui/redundant_field_names.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::redundant_field_names)]
#![allow(clippy::no_effect, dead_code, unused_variables)]
@@ -72,16 +71,14 @@ fn issue_3476() {
S { foo: foo::<i32> };
}
+#[clippy::msrv = "1.16"]
fn msrv_1_16() {
- #![clippy::msrv = "1.16"]
-
let start = 0;
let _ = RangeFrom { start: start };
}
+#[clippy::msrv = "1.17"]
fn msrv_1_17() {
- #![clippy::msrv = "1.17"]
-
let start = 0;
let _ = RangeFrom { start };
}
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.rs b/src/tools/clippy/tests/ui/redundant_field_names.rs
index a051b1f96..73122016c 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.rs
+++ b/src/tools/clippy/tests/ui/redundant_field_names.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::redundant_field_names)]
#![allow(clippy::no_effect, dead_code, unused_variables)]
@@ -72,16 +71,14 @@ fn issue_3476() {
S { foo: foo::<i32> };
}
+#[clippy::msrv = "1.16"]
fn msrv_1_16() {
- #![clippy::msrv = "1.16"]
-
let start = 0;
let _ = RangeFrom { start: start };
}
+#[clippy::msrv = "1.17"]
fn msrv_1_17() {
- #![clippy::msrv = "1.17"]
-
let start = 0;
let _ = RangeFrom { start: start };
}
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.stderr b/src/tools/clippy/tests/ui/redundant_field_names.stderr
index 8b82e062b..00a72c50c 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.stderr
+++ b/src/tools/clippy/tests/ui/redundant_field_names.stderr
@@ -1,5 +1,5 @@
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:36:9
+ --> $DIR/redundant_field_names.rs:35:9
|
LL | gender: gender,
| ^^^^^^^^^^^^^^ help: replace it with: `gender`
@@ -7,43 +7,43 @@ LL | gender: gender,
= note: `-D clippy::redundant-field-names` implied by `-D warnings`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:37:9
+ --> $DIR/redundant_field_names.rs:36:9
|
LL | age: age,
| ^^^^^^^^ help: replace it with: `age`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:58:25
+ --> $DIR/redundant_field_names.rs:57:25
|
LL | let _ = RangeFrom { start: start };
| ^^^^^^^^^^^^ help: replace it with: `start`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:59:23
+ --> $DIR/redundant_field_names.rs:58:23
|
LL | let _ = RangeTo { end: end };
| ^^^^^^^^ help: replace it with: `end`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:60:21
+ --> $DIR/redundant_field_names.rs:59: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:60:35
+ --> $DIR/redundant_field_names.rs:59: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:62:32
+ --> $DIR/redundant_field_names.rs:61:32
|
LL | let _ = RangeToInclusive { end: end };
| ^^^^^^^^ help: replace it with: `end`
error: redundant field names in struct initialization
- --> $DIR/redundant_field_names.rs:86:25
+ --> $DIR/redundant_field_names.rs:83:25
|
LL | let _ = RangeFrom { start: start };
| ^^^^^^^^^^^^ help: replace it with: `start`
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
index 42110dbe8..4c5846fe8 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(unused)]
#[derive(Debug)]
@@ -56,14 +55,12 @@ impl Bar for Foo {
const TRAIT_VAR: &'static str = "foo";
}
+#[clippy::msrv = "1.16"]
fn msrv_1_16() {
- #![clippy::msrv = "1.16"]
-
static V: &'static u8 = &16;
}
+#[clippy::msrv = "1.17"]
fn msrv_1_17() {
- #![clippy::msrv = "1.17"]
-
static V: &u8 = &17;
}
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
index bc5200bc8..64a66be1a 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![allow(unused)]
#[derive(Debug)]
@@ -56,14 +55,12 @@ impl Bar for Foo {
const TRAIT_VAR: &'static str = "foo";
}
+#[clippy::msrv = "1.16"]
fn msrv_1_16() {
- #![clippy::msrv = "1.16"]
-
static V: &'static u8 = &16;
}
+#[clippy::msrv = "1.17"]
fn msrv_1_17() {
- #![clippy::msrv = "1.17"]
-
static V: &'static u8 = &17;
}
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr b/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr
index 735113460..0938ebf78 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr
@@ -1,5 +1,5 @@
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:9:17
+ --> $DIR/redundant_static_lifetimes.rs:8:17
|
LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removing 'static.
| -^^^^^^^---- help: consider removing `'static`: `&str`
@@ -7,97 +7,97 @@ LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removin
= note: `-D clippy::redundant-static-lifetimes` implied by `-D warnings`
error: constants have by default a `'static` lifetime
- --> $DIR/redundant_static_lifetimes.rs:13:21
+ --> $DIR/redundant_static_lifetimes.rs:12: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:15:32
+ --> $DIR/redundant_static_lifetimes.rs:14: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:15:47
+ --> $DIR/redundant_static_lifetimes.rs:14: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:17:17
+ --> $DIR/redundant_static_lifetimes.rs:16: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:19:20
+ --> $DIR/redundant_static_lifetimes.rs:18: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:21:19
+ --> $DIR/redundant_static_lifetimes.rs:20: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:23:19
+ --> $DIR/redundant_static_lifetimes.rs:22: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:25:19
+ --> $DIR/redundant_static_lifetimes.rs:24: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:27:25
+ --> $DIR/redundant_static_lifetimes.rs:26: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:31:29
+ --> $DIR/redundant_static_lifetimes.rs:30: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:33:25
+ --> $DIR/redundant_static_lifetimes.rs:32: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:35:28
+ --> $DIR/redundant_static_lifetimes.rs:34: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:37:27
+ --> $DIR/redundant_static_lifetimes.rs:36: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:39:27
+ --> $DIR/redundant_static_lifetimes.rs:38: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:41:27
+ --> $DIR/redundant_static_lifetimes.rs:40: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:68:16
+ --> $DIR/redundant_static_lifetimes.rs:65:16
|
LL | static V: &'static u8 = &17;
| -^^^^^^^--- help: consider removing `'static`: `&u8`
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 8beae8dee..689928f04 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -12,7 +12,6 @@
#![allow(clippy::disallowed_methods)]
#![allow(clippy::disallowed_types)]
#![allow(clippy::mixed_read_write_in_expression)]
-#![allow(for_loops_over_fallibles)]
#![allow(clippy::useless_conversion)]
#![allow(clippy::match_result_ok)]
#![allow(clippy::overly_complex_bool_expr)]
@@ -27,9 +26,11 @@
#![allow(clippy::recursive_format_impl)]
#![allow(clippy::invisible_characters)]
#![allow(drop_bounds)]
+#![allow(for_loops_over_fallibles)]
#![allow(array_into_iter)]
#![allow(invalid_atomic_ordering)]
#![allow(invalid_value)]
+#![allow(let_underscore_drop)]
#![allow(enum_intrinsics_non_enums)]
#![allow(non_fmt_panics)]
#![allow(named_arguments_used_positionally)]
@@ -45,8 +46,6 @@
#![warn(clippy::disallowed_methods)]
#![warn(clippy::disallowed_types)]
#![warn(clippy::mixed_read_write_in_expression)]
-#![warn(for_loops_over_fallibles)]
-#![warn(for_loops_over_fallibles)]
#![warn(clippy::useless_conversion)]
#![warn(clippy::match_result_ok)]
#![warn(clippy::overly_complex_bool_expr)]
@@ -66,9 +65,12 @@
#![warn(clippy::invisible_characters)]
#![warn(drop_bounds)]
#![warn(for_loops_over_fallibles)]
+#![warn(for_loops_over_fallibles)]
+#![warn(for_loops_over_fallibles)]
#![warn(array_into_iter)]
#![warn(invalid_atomic_ordering)]
#![warn(invalid_value)]
+#![warn(let_underscore_drop)]
#![warn(enum_intrinsics_non_enums)]
#![warn(non_fmt_panics)]
#![warn(named_arguments_used_positionally)]
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 9e665047b..b74aa650f 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -12,7 +12,6 @@
#![allow(clippy::disallowed_methods)]
#![allow(clippy::disallowed_types)]
#![allow(clippy::mixed_read_write_in_expression)]
-#![allow(for_loops_over_fallibles)]
#![allow(clippy::useless_conversion)]
#![allow(clippy::match_result_ok)]
#![allow(clippy::overly_complex_bool_expr)]
@@ -27,9 +26,11 @@
#![allow(clippy::recursive_format_impl)]
#![allow(clippy::invisible_characters)]
#![allow(drop_bounds)]
+#![allow(for_loops_over_fallibles)]
#![allow(array_into_iter)]
#![allow(invalid_atomic_ordering)]
#![allow(invalid_value)]
+#![allow(let_underscore_drop)]
#![allow(enum_intrinsics_non_enums)]
#![allow(non_fmt_panics)]
#![allow(named_arguments_used_positionally)]
@@ -45,8 +46,6 @@
#![warn(clippy::disallowed_method)]
#![warn(clippy::disallowed_type)]
#![warn(clippy::eval_order_dependence)]
-#![warn(clippy::for_loop_over_option)]
-#![warn(clippy::for_loop_over_result)]
#![warn(clippy::identity_conversion)]
#![warn(clippy::if_let_some_result)]
#![warn(clippy::logic_bug)]
@@ -65,10 +64,13 @@
#![warn(clippy::to_string_in_display)]
#![warn(clippy::zero_width_space)]
#![warn(clippy::drop_bounds)]
+#![warn(clippy::for_loop_over_option)]
+#![warn(clippy::for_loop_over_result)]
#![warn(clippy::for_loops_over_fallibles)]
#![warn(clippy::into_iter_on_array)]
#![warn(clippy::invalid_atomic_ordering)]
#![warn(clippy::invalid_ref)]
+#![warn(clippy::let_underscore_drop)]
#![warn(clippy::mem_discriminant_non_enum)]
#![warn(clippy::panic_params)]
#![warn(clippy::positional_named_format_parameters)]
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index 63eb56518..622a32c59 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -1,5 +1,5 @@
error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
- --> $DIR/rename.rs:39:9
+ --> $DIR/rename.rs:40:9
|
LL | #![warn(clippy::blacklisted_name)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
@@ -7,232 +7,238 @@ LL | #![warn(clippy::blacklisted_name)]
= note: `-D renamed-and-removed-lints` implied by `-D warnings`
error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
- --> $DIR/rename.rs:40:9
+ --> $DIR/rename.rs:41:9
|
LL | #![warn(clippy::block_in_if_condition_expr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
- --> $DIR/rename.rs:41:9
+ --> $DIR/rename.rs:42:9
|
LL | #![warn(clippy::block_in_if_condition_stmt)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
- --> $DIR/rename.rs:42:9
+ --> $DIR/rename.rs:43:9
|
LL | #![warn(clippy::box_vec)]
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
- --> $DIR/rename.rs:43:9
+ --> $DIR/rename.rs:44:9
|
LL | #![warn(clippy::const_static_lifetime)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
- --> $DIR/rename.rs:44:9
+ --> $DIR/rename.rs:45:9
|
LL | #![warn(clippy::cyclomatic_complexity)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
- --> $DIR/rename.rs:45:9
+ --> $DIR/rename.rs:46:9
|
LL | #![warn(clippy::disallowed_method)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
- --> $DIR/rename.rs:46:9
+ --> $DIR/rename.rs:47:9
|
LL | #![warn(clippy::disallowed_type)]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`
- --> $DIR/rename.rs:47:9
+ --> $DIR/rename.rs:48:9
|
LL | #![warn(clippy::eval_order_dependence)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
-error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
- --> $DIR/rename.rs:48: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:49:9
- |
-LL | #![warn(clippy::for_loop_over_result)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
-
error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
- --> $DIR/rename.rs:50:9
+ --> $DIR/rename.rs:49:9
|
LL | #![warn(clippy::identity_conversion)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
- --> $DIR/rename.rs:51:9
+ --> $DIR/rename.rs:50:9
|
LL | #![warn(clippy::if_let_some_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
- --> $DIR/rename.rs:52:9
+ --> $DIR/rename.rs:51: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:53:9
+ --> $DIR/rename.rs:52: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:54:9
+ --> $DIR/rename.rs:53: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:55:9
+ --> $DIR/rename.rs:54: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:56:9
+ --> $DIR/rename.rs:55: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:57:9
+ --> $DIR/rename.rs:56: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:58:9
+ --> $DIR/rename.rs:57: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:59:9
+ --> $DIR/rename.rs:58: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:60:9
+ --> $DIR/rename.rs:59: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:61:9
+ --> $DIR/rename.rs:60: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:62:9
+ --> $DIR/rename.rs:61: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:63:9
+ --> $DIR/rename.rs:62: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:64:9
+ --> $DIR/rename.rs:63: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:65:9
+ --> $DIR/rename.rs:64:9
|
LL | #![warn(clippy::to_string_in_display)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
- --> $DIR/rename.rs:66:9
+ --> $DIR/rename.rs:65:9
|
LL | #![warn(clippy::zero_width_space)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
- --> $DIR/rename.rs:67:9
+ --> $DIR/rename.rs:66:9
|
LL | #![warn(clippy::drop_bounds)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
-error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
+error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
+ --> $DIR/rename.rs:67: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:68: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:69:9
+ |
LL | #![warn(clippy::for_loops_over_fallibles)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
- --> $DIR/rename.rs:69:9
+ --> $DIR/rename.rs:70: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:70:9
+ --> $DIR/rename.rs:71: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:71:9
+ --> $DIR/rename.rs:72:9
|
LL | #![warn(clippy::invalid_ref)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
+error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
+ --> $DIR/rename.rs:73: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:72:9
+ --> $DIR/rename.rs:74: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:73:9
+ --> $DIR/rename.rs:75: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:74:9
+ --> $DIR/rename.rs:76: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:75:9
+ --> $DIR/rename.rs:77:9
|
LL | #![warn(clippy::temporary_cstring_as_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
- --> $DIR/rename.rs:76:9
+ --> $DIR/rename.rs:78: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:77:9
+ --> $DIR/rename.rs:79:9
|
LL | #![warn(clippy::unused_label)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
-error: aborting due to 39 previous errors
+error: aborting due to 40 previous errors
diff --git a/src/tools/clippy/tests/ui/result_large_err.rs b/src/tools/clippy/tests/ui/result_large_err.rs
index f7df3b856..1c12cebfd 100644
--- a/src/tools/clippy/tests/ui/result_large_err.rs
+++ b/src/tools/clippy/tests/ui/result_large_err.rs
@@ -50,6 +50,18 @@ impl LargeErrorVariants<()> {
}
}
+enum MultipleLargeVariants {
+ _Biggest([u8; 1024]),
+ _AlsoBig([u8; 512]),
+ _Ok(usize),
+}
+
+impl MultipleLargeVariants {
+ fn large_enum_error() -> Result<(), Self> {
+ Ok(())
+ }
+}
+
trait TraitForcesLargeError {
fn large_error() -> Result<(), [u8; 512]> {
Ok(())
@@ -96,4 +108,10 @@ pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {
Ok(())
}
+// Issue #10005
+enum Empty {}
+fn _empty_error() -> Result<(), Empty> {
+ Ok(())
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/result_large_err.stderr b/src/tools/clippy/tests/ui/result_large_err.stderr
index bea101fe2..c386edfd2 100644
--- a/src/tools/clippy/tests/ui/result_large_err.stderr
+++ b/src/tools/clippy/tests/ui/result_large_err.stderr
@@ -42,13 +42,29 @@ LL | pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeErro
error: the `Err`-variant returned from this function is very large
--> $DIR/result_large_err.rs:48:34
|
+LL | _Omg([u8; 512]),
+ | --------------- the largest variant contains at least 512 bytes
+...
LL | pub fn large_enum_error() -> Result<(), Self> {
- | ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 513 bytes
+ | ^^^^^^^^^^^^^^^^
|
= 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:54:25
+ --> $DIR/result_large_err.rs:60:30
+ |
+LL | _Biggest([u8; 1024]),
+ | -------------------- the largest variant contains at least 1024 bytes
+LL | _AlsoBig([u8; 512]),
+ | ------------------- the variant `_AlsoBig` contains at least 512 bytes
+...
+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
|
LL | fn large_error() -> Result<(), [u8; 512]> {
| ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
@@ -56,7 +72,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:73:29
+ --> $DIR/result_large_err.rs:85:29
|
LL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
@@ -64,7 +80,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:82:40
+ --> $DIR/result_large_err.rs:94:40
|
LL | pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
@@ -72,7 +88,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:91:34
+ --> $DIR/result_large_err.rs:103:34
|
LL | pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes
@@ -80,12 +96,12 @@ 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:95:31
+ --> $DIR/result_large_err.rs:107:31
|
LL | pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes
|
= help: try reducing the size of `ArrayError<(i32, T), U>`, for example by boxing large elements or replacing it with `Box<ArrayError<(i32, T), U>>`
-error: aborting due to 11 previous errors
+error: aborting due to 12 previous errors
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 88e4efdb0..2e1eb8eb1 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
@@ -20,14 +20,14 @@ error: called `map(f)` on an `Result` value where `f` is a closure that returns
--> $DIR/result_map_unit_fn_unfixable.rs:29:5
|
LL | x.field.map(|value| {
- | _____^
- | |_____|
+ | ______^
+ | | _____|
| ||
LL | || do_nothing(value);
LL | || do_nothing(value)
LL | || });
| ||______^- help: try this: `if let Ok(value) = x.field { ... }`
- | |_______|
+ | |______|
|
error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
diff --git a/src/tools/clippy/tests/ui/seek_from_current.fixed b/src/tools/clippy/tests/ui/seek_from_current.fixed
new file mode 100644
index 000000000..1309c91b8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/seek_from_current.fixed
@@ -0,0 +1,25 @@
+// run-rustfix
+#![warn(clippy::seek_from_current)]
+
+use std::fs::File;
+use std::io::{self, Seek, SeekFrom, Write};
+
+#[clippy::msrv = "1.50"]
+fn _msrv_1_50() -> io::Result<()> {
+ let mut f = File::create("foo.txt")?;
+ f.write_all(b"Hi!")?;
+ f.seek(SeekFrom::Current(0))?;
+ f.seek(SeekFrom::Current(1))?;
+ Ok(())
+}
+
+#[clippy::msrv = "1.51"]
+fn _msrv_1_51() -> io::Result<()> {
+ let mut f = File::create("foo.txt")?;
+ f.write_all(b"Hi!")?;
+ f.stream_position()?;
+ f.seek(SeekFrom::Current(1))?;
+ Ok(())
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/seek_from_current.rs b/src/tools/clippy/tests/ui/seek_from_current.rs
new file mode 100644
index 000000000..5d9b1424c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/seek_from_current.rs
@@ -0,0 +1,25 @@
+// run-rustfix
+#![warn(clippy::seek_from_current)]
+
+use std::fs::File;
+use std::io::{self, Seek, SeekFrom, Write};
+
+#[clippy::msrv = "1.50"]
+fn _msrv_1_50() -> io::Result<()> {
+ let mut f = File::create("foo.txt")?;
+ f.write_all(b"Hi!")?;
+ f.seek(SeekFrom::Current(0))?;
+ f.seek(SeekFrom::Current(1))?;
+ Ok(())
+}
+
+#[clippy::msrv = "1.51"]
+fn _msrv_1_51() -> io::Result<()> {
+ let mut f = File::create("foo.txt")?;
+ f.write_all(b"Hi!")?;
+ f.seek(SeekFrom::Current(0))?;
+ f.seek(SeekFrom::Current(1))?;
+ Ok(())
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/seek_from_current.stderr b/src/tools/clippy/tests/ui/seek_from_current.stderr
new file mode 100644
index 000000000..c079f3611
--- /dev/null
+++ b/src/tools/clippy/tests/ui/seek_from_current.stderr
@@ -0,0 +1,10 @@
+error: using `SeekFrom::Current` to start from current position
+ --> $DIR/seek_from_current.rs:20:5
+ |
+LL | f.seek(SeekFrom::Current(0))?;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `f.stream_position()`
+ |
+ = note: `-D clippy::seek-from-current` implied by `-D warnings`
+
+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
new file mode 100644
index 000000000..9d0d1124c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed
@@ -0,0 +1,134 @@
+// run-rustfix
+#![allow(unused)]
+#![warn(clippy::seek_to_start_instead_of_rewind)]
+
+use std::fs::OpenOptions;
+use std::io::{Read, Seek, SeekFrom, Write};
+
+struct StructWithSeekMethod {}
+
+impl StructWithSeekMethod {
+ fn seek(&mut self, from: SeekFrom) {}
+}
+
+trait MySeekTrait {
+ fn seek(&mut self, from: SeekFrom) {}
+}
+
+struct StructWithSeekTrait {}
+impl MySeekTrait for StructWithSeekTrait {}
+
+// This should NOT trigger clippy warning because
+// StructWithSeekMethod does not implement std::io::Seek;
+fn seek_to_start_false_method(t: &mut StructWithSeekMethod) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should NOT trigger clippy warning because
+// StructWithSeekMethod does not implement std::io::Seek;
+fn seek_to_start_method_owned_false<T>(mut t: StructWithSeekMethod) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should NOT trigger clippy warning because
+// StructWithSeekMethod does not implement std::io::Seek;
+fn seek_to_start_false_trait(t: &mut StructWithSeekTrait) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should NOT trigger clippy warning because
+// StructWithSeekMethod does not implement std::io::Seek;
+fn seek_to_start_false_trait_owned<T>(mut t: StructWithSeekTrait) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should NOT trigger clippy warning because
+// StructWithSeekMethod does not implement std::io::Seek;
+fn seek_to_start_false_trait_bound<T: MySeekTrait>(t: &mut T) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should trigger clippy warning
+fn seek_to_start<T: Seek>(t: &mut T) {
+ t.rewind();
+}
+
+// This should trigger clippy warning
+fn owned_seek_to_start<T: Seek>(mut t: T) {
+ t.rewind();
+}
+
+// This should NOT trigger clippy warning because
+// it does not seek to start
+fn seek_to_5<T: Seek>(t: &mut T) {
+ t.seek(SeekFrom::Start(5));
+}
+
+// This should NOT trigger clippy warning because
+// it does not seek to start
+fn seek_to_end<T: Seek>(t: &mut T) {
+ t.seek(SeekFrom::End(0));
+}
+
+fn main() {
+ let mut f = OpenOptions::new()
+ .write(true)
+ .read(true)
+ .create(true)
+ .open("foo.txt")
+ .unwrap();
+
+ let mut my_struct_trait = StructWithSeekTrait {};
+ seek_to_start_false_trait_bound(&mut my_struct_trait);
+
+ let hello = "Hello!\n";
+ write!(f, "{hello}").unwrap();
+ seek_to_5(&mut f);
+ seek_to_end(&mut f);
+ seek_to_start(&mut f);
+
+ let mut buf = String::new();
+ f.read_to_string(&mut buf).unwrap();
+
+ assert_eq!(&buf, hello);
+}
+
+#[clippy::msrv = "1.54"]
+fn msrv_1_54() {
+ let mut f = OpenOptions::new()
+ .write(true)
+ .read(true)
+ .create(true)
+ .open("foo.txt")
+ .unwrap();
+
+ let hello = "Hello!\n";
+ write!(f, "{hello}").unwrap();
+
+ f.seek(SeekFrom::Start(0));
+
+ let mut buf = String::new();
+ f.read_to_string(&mut buf).unwrap();
+
+ assert_eq!(&buf, hello);
+}
+
+#[clippy::msrv = "1.55"]
+fn msrv_1_55() {
+ let mut f = OpenOptions::new()
+ .write(true)
+ .read(true)
+ .create(true)
+ .open("foo.txt")
+ .unwrap();
+
+ let hello = "Hello!\n";
+ write!(f, "{hello}").unwrap();
+
+ f.rewind();
+
+ let mut buf = String::new();
+ f.read_to_string(&mut buf).unwrap();
+
+ assert_eq!(&buf, hello);
+}
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
new file mode 100644
index 000000000..c5bc57cc3
--- /dev/null
+++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs
@@ -0,0 +1,134 @@
+// run-rustfix
+#![allow(unused)]
+#![warn(clippy::seek_to_start_instead_of_rewind)]
+
+use std::fs::OpenOptions;
+use std::io::{Read, Seek, SeekFrom, Write};
+
+struct StructWithSeekMethod {}
+
+impl StructWithSeekMethod {
+ fn seek(&mut self, from: SeekFrom) {}
+}
+
+trait MySeekTrait {
+ fn seek(&mut self, from: SeekFrom) {}
+}
+
+struct StructWithSeekTrait {}
+impl MySeekTrait for StructWithSeekTrait {}
+
+// This should NOT trigger clippy warning because
+// StructWithSeekMethod does not implement std::io::Seek;
+fn seek_to_start_false_method(t: &mut StructWithSeekMethod) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should NOT trigger clippy warning because
+// StructWithSeekMethod does not implement std::io::Seek;
+fn seek_to_start_method_owned_false<T>(mut t: StructWithSeekMethod) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should NOT trigger clippy warning because
+// StructWithSeekMethod does not implement std::io::Seek;
+fn seek_to_start_false_trait(t: &mut StructWithSeekTrait) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should NOT trigger clippy warning because
+// StructWithSeekMethod does not implement std::io::Seek;
+fn seek_to_start_false_trait_owned<T>(mut t: StructWithSeekTrait) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should NOT trigger clippy warning because
+// StructWithSeekMethod does not implement std::io::Seek;
+fn seek_to_start_false_trait_bound<T: MySeekTrait>(t: &mut T) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should trigger clippy warning
+fn seek_to_start<T: Seek>(t: &mut T) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should trigger clippy warning
+fn owned_seek_to_start<T: Seek>(mut t: T) {
+ t.seek(SeekFrom::Start(0));
+}
+
+// This should NOT trigger clippy warning because
+// it does not seek to start
+fn seek_to_5<T: Seek>(t: &mut T) {
+ t.seek(SeekFrom::Start(5));
+}
+
+// This should NOT trigger clippy warning because
+// it does not seek to start
+fn seek_to_end<T: Seek>(t: &mut T) {
+ t.seek(SeekFrom::End(0));
+}
+
+fn main() {
+ let mut f = OpenOptions::new()
+ .write(true)
+ .read(true)
+ .create(true)
+ .open("foo.txt")
+ .unwrap();
+
+ let mut my_struct_trait = StructWithSeekTrait {};
+ seek_to_start_false_trait_bound(&mut my_struct_trait);
+
+ let hello = "Hello!\n";
+ write!(f, "{hello}").unwrap();
+ seek_to_5(&mut f);
+ seek_to_end(&mut f);
+ seek_to_start(&mut f);
+
+ let mut buf = String::new();
+ f.read_to_string(&mut buf).unwrap();
+
+ assert_eq!(&buf, hello);
+}
+
+#[clippy::msrv = "1.54"]
+fn msrv_1_54() {
+ let mut f = OpenOptions::new()
+ .write(true)
+ .read(true)
+ .create(true)
+ .open("foo.txt")
+ .unwrap();
+
+ let hello = "Hello!\n";
+ write!(f, "{hello}").unwrap();
+
+ f.seek(SeekFrom::Start(0));
+
+ let mut buf = String::new();
+ f.read_to_string(&mut buf).unwrap();
+
+ assert_eq!(&buf, hello);
+}
+
+#[clippy::msrv = "1.55"]
+fn msrv_1_55() {
+ let mut f = OpenOptions::new()
+ .write(true)
+ .read(true)
+ .create(true)
+ .open("foo.txt")
+ .unwrap();
+
+ let hello = "Hello!\n";
+ write!(f, "{hello}").unwrap();
+
+ f.seek(SeekFrom::Start(0));
+
+ let mut buf = String::new();
+ f.read_to_string(&mut buf).unwrap();
+
+ assert_eq!(&buf, hello);
+}
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
new file mode 100644
index 000000000..6cce02535
--- /dev/null
+++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.stderr
@@ -0,0 +1,22 @@
+error: used `seek` to go to the start of the stream
+ --> $DIR/seek_to_start_instead_of_rewind.rs:53:7
+ |
+LL | t.seek(SeekFrom::Start(0));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`
+ |
+ = note: `-D clippy::seek-to-start-instead-of-rewind` implied by `-D warnings`
+
+error: used `seek` to go to the start of the stream
+ --> $DIR/seek_to_start_instead_of_rewind.rs:58: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:128:7
+ |
+LL | f.seek(SeekFrom::Start(0));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`
+
+error: aborting due to 3 previous errors
+
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 509c88ac2..71dcc25d6 100644
--- a/src/tools/clippy/tests/ui/single_component_path_imports.stderr
+++ b/src/tools/clippy/tests/ui/single_component_path_imports.stderr
@@ -1,16 +1,16 @@
error: this import is redundant
- --> $DIR/single_component_path_imports.rs:23:5
+ --> $DIR/single_component_path_imports.rs:5:1
|
-LL | use regex;
- | ^^^^^^^^^^ help: remove it entirely
+LL | use regex;
+ | ^^^^^^^^^^ help: remove it entirely
|
= note: `-D clippy::single-component-path-imports` implied by `-D warnings`
error: this import is redundant
- --> $DIR/single_component_path_imports.rs:5:1
+ --> $DIR/single_component_path_imports.rs:23:5
|
-LL | use regex;
- | ^^^^^^^^^^ help: remove it entirely
+LL | use regex;
+ | ^^^^^^^^^^ help: remove it entirely
error: aborting due to 2 previous errors
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 633546f64..330f28520 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
@@ -1,11 +1,18 @@
error: this import is redundant
+ --> $DIR/single_component_path_imports_nested_first.rs:4:1
+ |
+LL | use regex;
+ | ^^^^^^^^^^ help: remove it entirely
+ |
+ = note: `-D clippy::single-component-path-imports` implied by `-D warnings`
+
+error: this import is redundant
--> $DIR/single_component_path_imports_nested_first.rs:13:10
|
LL | use {regex, serde};
| ^^^^^
|
= help: remove this import
- = note: `-D clippy::single-component-path-imports` implied by `-D warnings`
error: this import is redundant
--> $DIR/single_component_path_imports_nested_first.rs:13:17
@@ -15,11 +22,5 @@ LL | use {regex, serde};
|
= help: remove this import
-error: this import is redundant
- --> $DIR/single_component_path_imports_nested_first.rs:4:1
- |
-LL | use regex;
- | ^^^^^^^^^^ help: remove it entirely
-
error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/string_extend.fixed b/src/tools/clippy/tests/ui/string_extend.fixed
index 1883a9f83..d200d7310 100644
--- a/src/tools/clippy/tests/ui/string_extend.fixed
+++ b/src/tools/clippy/tests/ui/string_extend.fixed
@@ -29,4 +29,7 @@ fn main() {
let f = HasChars;
s.extend(f.chars());
+
+ // issue #9735
+ s.push_str(&abc[0..2]);
}
diff --git a/src/tools/clippy/tests/ui/string_extend.rs b/src/tools/clippy/tests/ui/string_extend.rs
index 07d0baa1b..0dd96a3b2 100644
--- a/src/tools/clippy/tests/ui/string_extend.rs
+++ b/src/tools/clippy/tests/ui/string_extend.rs
@@ -29,4 +29,7 @@ fn main() {
let f = HasChars;
s.extend(f.chars());
+
+ // issue #9735
+ s.extend(abc[0..2].chars());
}
diff --git a/src/tools/clippy/tests/ui/string_extend.stderr b/src/tools/clippy/tests/ui/string_extend.stderr
index 6af8c9e16..b35c77fd9 100644
--- a/src/tools/clippy/tests/ui/string_extend.stderr
+++ b/src/tools/clippy/tests/ui/string_extend.stderr
@@ -18,5 +18,11 @@ error: calling `.extend(_.chars())`
LL | s.extend(def.chars());
| ^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.push_str(&def)`
-error: aborting due to 3 previous errors
+error: calling `.extend(_.chars())`
+ --> $DIR/string_extend.rs:34:5
+ |
+LL | s.extend(abc[0..2].chars());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.push_str(&abc[0..2])`
+
+error: aborting due to 4 previous errors
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
new file mode 100644
index 000000000..eb9fc63fb
--- /dev/null
+++ b/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.rs
@@ -0,0 +1,34 @@
+#![allow(unused)]
+#![warn(clippy::suspicious_xor_used_as_pow)]
+#![allow(clippy::eq_op)]
+
+macro_rules! macro_test {
+ () => {
+ 13
+ };
+}
+
+macro_rules! macro_test_inside {
+ () => {
+ 1 ^ 2 // should warn even if inside macro
+ };
+}
+
+fn main() {
+ // Should warn:
+ let _ = 2 ^ 5;
+ let _ = 2i32 ^ 9i32;
+ let _ = 2i32 ^ 2i32;
+ let _ = 50i32 ^ 3i32;
+ let _ = 5i32 ^ 8i32;
+ let _ = 2i32 ^ 32i32;
+ macro_test_inside!();
+
+ // Should not warn:
+ let x = 0x02;
+ let _ = x ^ 2;
+ let _ = 2 ^ x;
+ let _ = x ^ 5;
+ let _ = 10 ^ 0b0101;
+ let _ = 2i32 ^ macro_test!();
+}
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
new file mode 100644
index 000000000..8bb3c8fbe
--- /dev/null
+++ b/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr
@@ -0,0 +1,51 @@
+error: `^` is not the exponentiation operator
+ --> $DIR/suspicious_xor_used_as_pow.rs:19:13
+ |
+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`
+
+error: `^` is not the exponentiation operator
+ --> $DIR/suspicious_xor_used_as_pow.rs:20:13
+ |
+LL | let _ = 2i32 ^ 9i32;
+ | ^^^^^^^^^^^ help: did you mean to write: `2_i32.pow(9_i32)`
+
+error: `^` is not the exponentiation operator
+ --> $DIR/suspicious_xor_used_as_pow.rs:21:13
+ |
+LL | let _ = 2i32 ^ 2i32;
+ | ^^^^^^^^^^^ help: did you mean to write: `2_i32.pow(2_i32)`
+
+error: `^` is not the exponentiation operator
+ --> $DIR/suspicious_xor_used_as_pow.rs:22:13
+ |
+LL | let _ = 50i32 ^ 3i32;
+ | ^^^^^^^^^^^^ help: did you mean to write: `50_i32.pow(3_i32)`
+
+error: `^` is not the exponentiation operator
+ --> $DIR/suspicious_xor_used_as_pow.rs:23:13
+ |
+LL | let _ = 5i32 ^ 8i32;
+ | ^^^^^^^^^^^ help: did you mean to write: `5_i32.pow(8_i32)`
+
+error: `^` is not the exponentiation operator
+ --> $DIR/suspicious_xor_used_as_pow.rs:24:13
+ |
+LL | let _ = 2i32 ^ 32i32;
+ | ^^^^^^^^^^^^ help: did you mean to write: `2_i32.pow(32_i32)`
+
+error: `^` is not the exponentiation operator
+ --> $DIR/suspicious_xor_used_as_pow.rs:13:9
+ |
+LL | 1 ^ 2 // should warn even if inside macro
+ | ^^^^^ help: did you mean to write: `1.pow(2)`
+...
+LL | macro_test_inside!();
+ | -------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `macro_test_inside` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/swap.fixed b/src/tools/clippy/tests/ui/swap.fixed
index 24b229235..805a2ba5a 100644
--- a/src/tools/clippy/tests/ui/swap.fixed
+++ b/src/tools/clippy/tests/ui/swap.fixed
@@ -155,3 +155,12 @@ fn issue_8154() {
let s = S3(&mut s);
std::mem::swap(&mut s.0.x, &mut s.0.y);
}
+
+const fn issue_9864(mut u: u32) -> u32 {
+ let mut v = 10;
+
+ let temp = u;
+ u = v;
+ v = temp;
+ u + v
+}
diff --git a/src/tools/clippy/tests/ui/swap.rs b/src/tools/clippy/tests/ui/swap.rs
index a318c2791..a8c878479 100644
--- a/src/tools/clippy/tests/ui/swap.rs
+++ b/src/tools/clippy/tests/ui/swap.rs
@@ -179,3 +179,12 @@ fn issue_8154() {
s.0.x = s.0.y;
s.0.y = t;
}
+
+const fn issue_9864(mut u: u32) -> u32 {
+ let mut v = 10;
+
+ let temp = u;
+ u = v;
+ v = temp;
+ u + v
+}
diff --git a/src/tools/clippy/tests/ui/track-diagnostics.rs b/src/tools/clippy/tests/ui/track-diagnostics.rs
new file mode 100644
index 000000000..fa9221ed0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/track-diagnostics.rs
@@ -0,0 +1,12 @@
+// compile-flags: -Z track-diagnostics
+// error-pattern: created at
+
+// Normalize the emitted location so this doesn't need
+// updating everytime someone adds or removes a line.
+// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC"
+
+struct A;
+struct B;
+const S: A = B;
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/track-diagnostics.stderr b/src/tools/clippy/tests/ui/track-diagnostics.stderr
new file mode 100644
index 000000000..ec3031862
--- /dev/null
+++ b/src/tools/clippy/tests/ui/track-diagnostics.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> $DIR/track-diagnostics.rs:LL:CC
+ |
+LL | const S: A = B;
+ | ^ expected struct `A`, found struct `B`
+-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:LL:CC
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/tools/clippy/tests/ui/transmute.rs b/src/tools/clippy/tests/ui/transmute.rs
index 001c91023..1cbacf0fe 100644
--- a/src/tools/clippy/tests/ui/transmute.rs
+++ b/src/tools/clippy/tests/ui/transmute.rs
@@ -1,4 +1,4 @@
-#![allow(dead_code, clippy::borrow_as_ptr)]
+#![allow(dead_code, clippy::borrow_as_ptr, clippy::needless_lifetimes)]
extern crate core;
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 e5fe9133f..074dae5fb 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::transmute_ptr_to_ref)]
#![allow(clippy::match_single_binding)]
@@ -51,8 +50,8 @@ unsafe fn _issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'
}
}
+#[clippy::msrv = "1.38"]
unsafe fn _meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 {
- #![clippy::msrv = "1.38"]
let a = 0u32;
let a = &a as *const u32;
let _: &u32 = &*a;
@@ -63,8 +62,8 @@ unsafe fn _meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 {
}
}
+#[clippy::msrv = "1.37"]
unsafe fn _under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 {
- #![clippy::msrv = "1.37"]
let a = 0u32;
let a = &a as *const u32;
let _: &u32 = &*a;
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 fe49cdc32..2edc122cf 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs
@@ -1,6 +1,5 @@
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::transmute_ptr_to_ref)]
#![allow(clippy::match_single_binding)]
@@ -51,8 +50,8 @@ unsafe fn _issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'
}
}
+#[clippy::msrv = "1.38"]
unsafe fn _meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 {
- #![clippy::msrv = "1.38"]
let a = 0u32;
let a = &a as *const u32;
let _: &u32 = std::mem::transmute(a);
@@ -63,8 +62,8 @@ unsafe fn _meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 {
}
}
+#[clippy::msrv = "1.37"]
unsafe fn _under_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 {
- #![clippy::msrv = "1.37"]
let a = 0u32;
let a = &a as *const u32;
let _: &u32 = std::mem::transmute(a);
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 10117ee91..b3e6c09d2 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr
@@ -1,5 +1,5 @@
error: transmute from a pointer type (`*const T`) to a reference type (`&T`)
- --> $DIR/transmute_ptr_to_ref.rs:8:17
+ --> $DIR/transmute_ptr_to_ref.rs:7:17
|
LL | let _: &T = std::mem::transmute(p);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*p`
@@ -7,127 +7,127 @@ LL | let _: &T = std::mem::transmute(p);
= note: `-D clippy::transmute-ptr-to-ref` implied by `-D warnings`
error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`)
- --> $DIR/transmute_ptr_to_ref.rs:11:21
+ --> $DIR/transmute_ptr_to_ref.rs:10: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:14:17
+ --> $DIR/transmute_ptr_to_ref.rs:13: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:17:21
+ --> $DIR/transmute_ptr_to_ref.rs:16: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:20:17
+ --> $DIR/transmute_ptr_to_ref.rs:19: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:23:21
+ --> $DIR/transmute_ptr_to_ref.rs:22: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:26:17
+ --> $DIR/transmute_ptr_to_ref.rs:25: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:36:32
+ --> $DIR/transmute_ptr_to_ref.rs:35: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:38:33
+ --> $DIR/transmute_ptr_to_ref.rs:37: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:42:14
+ --> $DIR/transmute_ptr_to_ref.rs:41: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:47:14
+ --> $DIR/transmute_ptr_to_ref.rs:46: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:48:14
+ --> $DIR/transmute_ptr_to_ref.rs:47: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:49:14
+ --> $DIR/transmute_ptr_to_ref.rs:48: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:50:14
+ --> $DIR/transmute_ptr_to_ref.rs:49: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:58:19
+ --> $DIR/transmute_ptr_to_ref.rs:57: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:59:19
+ --> $DIR/transmute_ptr_to_ref.rs:58: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:61:14
+ --> $DIR/transmute_ptr_to_ref.rs:60: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:62:14
+ --> $DIR/transmute_ptr_to_ref.rs:61: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:70:19
+ --> $DIR/transmute_ptr_to_ref.rs:69: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:71:19
+ --> $DIR/transmute_ptr_to_ref.rs:70: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:73:14
+ --> $DIR/transmute_ptr_to_ref.rs:72: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:74:14
+ --> $DIR/transmute_ptr_to_ref.rs:73: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/trivially_copy_pass_by_ref.rs b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs
index af4f3b184..c0af011d3 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
@@ -3,6 +3,7 @@
#![deny(clippy::trivially_copy_pass_by_ref)]
#![allow(
clippy::disallowed_names,
+ clippy::needless_lifetimes,
clippy::redundant_field_names,
clippy::uninlined_format_args
)]
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 6a8eca965..8c5cfa8a0 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,5 +1,5 @@
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:50:11
+ --> $DIR/trivially_copy_pass_by_ref.rs:51:11
|
LL | fn bad(x: &u32, y: &Foo, z: &Baz) {}
| ^^^^ help: consider passing by value instead: `u32`
@@ -11,103 +11,103 @@ 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)
- --> $DIR/trivially_copy_pass_by_ref.rs:50:20
+ --> $DIR/trivially_copy_pass_by_ref.rs:51: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)
- --> $DIR/trivially_copy_pass_by_ref.rs:50:29
+ --> $DIR/trivially_copy_pass_by_ref.rs:51: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:57:12
+ --> $DIR/trivially_copy_pass_by_ref.rs:58: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:57:22
+ --> $DIR/trivially_copy_pass_by_ref.rs:58: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:57:31
+ --> $DIR/trivially_copy_pass_by_ref.rs:58: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:57:40
+ --> $DIR/trivially_copy_pass_by_ref.rs:58: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:59:16
+ --> $DIR/trivially_copy_pass_by_ref.rs:60: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:59:25
+ --> $DIR/trivially_copy_pass_by_ref.rs:60: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:59:34
+ --> $DIR/trivially_copy_pass_by_ref.rs:60: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:61:35
+ --> $DIR/trivially_copy_pass_by_ref.rs:62: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:73:16
+ --> $DIR/trivially_copy_pass_by_ref.rs:74: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:73:25
+ --> $DIR/trivially_copy_pass_by_ref.rs:74: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:73:34
+ --> $DIR/trivially_copy_pass_by_ref.rs:74: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:77:34
+ --> $DIR/trivially_copy_pass_by_ref.rs:78: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:109:21
+ --> $DIR/trivially_copy_pass_by_ref.rs:110: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:114:15
+ --> $DIR/trivially_copy_pass_by_ref.rs:115: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:141:37
+ --> $DIR/trivially_copy_pass_by_ref.rs:142: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/unchecked_duration_subtraction.fixed b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed
new file mode 100644
index 000000000..a0e49a8be
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed
@@ -0,0 +1,17 @@
+// run-rustfix
+#![warn(clippy::unchecked_duration_subtraction)]
+
+use std::time::{Duration, Instant};
+
+fn main() {
+ let _first = Instant::now();
+ let second = Duration::from_secs(3);
+
+ let _ = _first.checked_sub(second).unwrap();
+
+ let _ = Instant::now().checked_sub(Duration::from_secs(5)).unwrap();
+
+ let _ = _first.checked_sub(Duration::from_secs(5)).unwrap();
+
+ let _ = Instant::now().checked_sub(second).unwrap();
+}
diff --git a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs
new file mode 100644
index 000000000..a14a7ea57
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs
@@ -0,0 +1,17 @@
+// run-rustfix
+#![warn(clippy::unchecked_duration_subtraction)]
+
+use std::time::{Duration, Instant};
+
+fn main() {
+ let _first = Instant::now();
+ let second = Duration::from_secs(3);
+
+ let _ = _first - second;
+
+ let _ = Instant::now() - Duration::from_secs(5);
+
+ let _ = _first - Duration::from_secs(5);
+
+ let _ = Instant::now() - second;
+}
diff --git a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.stderr b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.stderr
new file mode 100644
index 000000000..a2e0aa1d7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.stderr
@@ -0,0 +1,28 @@
+error: unchecked subtraction of a 'Duration' from an 'Instant'
+ --> $DIR/unchecked_duration_subtraction.rs:10:13
+ |
+LL | let _ = _first - second;
+ | ^^^^^^^^^^^^^^^ help: try: `_first.checked_sub(second).unwrap()`
+ |
+ = note: `-D clippy::unchecked-duration-subtraction` implied by `-D warnings`
+
+error: unchecked subtraction of a 'Duration' from an 'Instant'
+ --> $DIR/unchecked_duration_subtraction.rs:12: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
+ |
+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
+ |
+LL | let _ = Instant::now() - second;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(second).unwrap()`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
index 08aee4332..c05eb447b 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
@@ -1,6 +1,6 @@
// aux-build:proc_macro_unsafe.rs
-#![warn(clippy::undocumented_unsafe_blocks)]
+#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]
#![allow(clippy::let_unit_value, clippy::missing_safety_doc)]
extern crate proc_macro_unsafe;
@@ -490,4 +490,23 @@ 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
+ }
+ };
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
index 2c466ff5c..d1c1bb5ff 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
@@ -239,6 +239,19 @@ 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
+ |
+LL | const BIG_NUMBER: i32 = 1000000;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: consider removing the safety comment
+ --> $DIR/undocumented_unsafe_blocks.rs:470:5
+ |
+LL | // SAFETY:
+ | ^^^^^^^^^^
+ = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`
+
error: unsafe impl missing a safety comment
--> $DIR/undocumented_unsafe_blocks.rs:472:5
|
@@ -263,5 +276,47 @@ LL | unsafe impl CrateRoot for () {}
|
= help: consider adding a safety comment on the preceding line
-error: aborting due to 31 previous errors
+error: unsafe block missing a safety comment
+ --> $DIR/undocumented_unsafe_blocks.rs:498:9
+ |
+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
+ |
+LL | / let _ = {
+LL | | if unsafe { true } {
+LL | | todo!();
+LL | | } else {
+... |
+LL | | }
+LL | | };
+ | |______^
+ |
+help: consider removing the safety comment
+ --> $DIR/undocumented_unsafe_blocks.rs:500: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
+ |
+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
+ |
+LL | let bar = unsafe {};
+ | ^^^^^^^^^
+ |
+ = help: consider adding a safety comment on the preceding line
+
+error: aborting due to 36 previous errors
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.fixed b/src/tools/clippy/tests/ui/uninlined_format_args.fixed
index 106274479..9d08e80cf 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args.fixed
+++ b/src/tools/clippy/tests/ui/uninlined_format_args.fixed
@@ -1,6 +1,5 @@
// aux-build:proc_macro_with_span.rs
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::uninlined_format_args)]
#![allow(named_arguments_used_positionally, unused_imports, unused_macros, unused_variables)]
#![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)]
@@ -44,9 +43,7 @@ fn tester(fn_arg: i32) {
println!("val='{local_i32}'"); // space+tab
println!("val='{local_i32}'"); // tab+space
println!(
- "val='{
- }'",
- local_i32
+ "val='{local_i32}'"
);
println!("{local_i32}");
println!("{fn_arg}");
@@ -57,11 +54,11 @@ fn tester(fn_arg: i32) {
println!("{local_i32:<3}");
println!("{local_i32:#010x}");
println!("{local_f64:.1}");
- println!("Hello {} is {local_f64:.local_i32$}", "x");
- println!("Hello {local_i32} is {local_f64:.*}", 5);
- println!("Hello {local_i32} is {local_f64:.*}", 5);
+ println!("Hello {} is {:.*}", "x", local_i32, local_f64);
+ println!("Hello {} is {:.*}", local_i32, 5, local_f64);
+ println!("Hello {} is {2:.*}", local_i32, 5, local_f64);
println!("{local_i32} {local_f64}");
- println!("{local_i32}, {}", local_opt.unwrap());
+ println!("{}, {}", local_i32, local_opt.unwrap());
println!("{val}");
println!("{val}");
println!("{} {1}", local_i32, 42);
@@ -110,8 +107,7 @@ fn tester(fn_arg: i32) {
println!("{local_f64:width$.prec$}");
println!("{local_f64:width$.prec$} {local_f64} {width} {prec}");
println!(
- "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}",
- local_i32, width, prec,
+ "{local_i32:width$.prec$} {local_i32:prec$.width$} {width:local_i32$.prec$} {width:prec$.local_i32$} {prec:local_i32$.width$} {prec:width$.local_i32$}",
);
println!(
"{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$} {3}",
@@ -142,9 +138,7 @@ fn tester(fn_arg: i32) {
println!(no_param_str!(), local_i32);
println!(
- "{}",
- // comment with a comma , in it
- val,
+ "{val}",
);
println!("{val}");
@@ -169,14 +163,14 @@ fn main() {
tester(42);
}
+#[clippy::msrv = "1.57"]
fn _under_msrv() {
- #![clippy::msrv = "1.57"]
let local_i32 = 1;
println!("don't expand='{}'", local_i32);
}
+#[clippy::msrv = "1.58"]
fn _meets_msrv() {
- #![clippy::msrv = "1.58"]
let local_i32 = 1;
println!("expand='{local_i32}'");
}
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.rs b/src/tools/clippy/tests/ui/uninlined_format_args.rs
index 8e495ebd0..35b3677a8 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args.rs
+++ b/src/tools/clippy/tests/ui/uninlined_format_args.rs
@@ -1,6 +1,5 @@
// aux-build:proc_macro_with_span.rs
// run-rustfix
-#![feature(custom_inner_attributes)]
#![warn(clippy::uninlined_format_args)]
#![allow(named_arguments_used_positionally, unused_imports, unused_macros, unused_variables)]
#![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)]
@@ -169,14 +168,14 @@ fn main() {
tester(42);
}
+#[clippy::msrv = "1.57"]
fn _under_msrv() {
- #![clippy::msrv = "1.57"]
let local_i32 = 1;
println!("don't expand='{}'", local_i32);
}
+#[clippy::msrv = "1.58"]
fn _meets_msrv() {
- #![clippy::msrv = "1.58"]
let local_i32 = 1;
println!("expand='{}'", local_i32);
}
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.stderr b/src/tools/clippy/tests/ui/uninlined_format_args.stderr
index 2ce3b7fa9..a12abf8be 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args.stderr
+++ b/src/tools/clippy/tests/ui/uninlined_format_args.stderr
@@ -1,5 +1,5 @@
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:41:5
+ --> $DIR/uninlined_format_args.rs:40:5
|
LL | println!("val='{}'", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -12,7 +12,7 @@ LL + println!("val='{local_i32}'");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:42:5
+ --> $DIR/uninlined_format_args.rs:41:5
|
LL | println!("val='{ }'", local_i32); // 3 spaces
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL + println!("val='{local_i32}'"); // 3 spaces
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:43:5
+ --> $DIR/uninlined_format_args.rs:42:5
|
LL | println!("val='{ }'", local_i32); // tab
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL + println!("val='{local_i32}'"); // tab
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:44:5
+ --> $DIR/uninlined_format_args.rs:43:5
|
LL | println!("val='{ }'", local_i32); // space+tab
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -48,7 +48,7 @@ LL + println!("val='{local_i32}'"); // space+tab
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:45:5
+ --> $DIR/uninlined_format_args.rs:44:5
|
LL | println!("val='{ }'", local_i32); // tab+space
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +60,17 @@ LL + println!("val='{local_i32}'"); // tab+space
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:51:5
+ --> $DIR/uninlined_format_args.rs:45:5
+ |
+LL | / println!(
+LL | | "val='{
+LL | | }'",
+LL | | local_i32
+LL | | );
+ | |_____^
+
+error: variables can be used directly in the `format!` string
+ --> $DIR/uninlined_format_args.rs:50:5
|
LL | println!("{}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +82,7 @@ LL + println!("{local_i32}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:52:5
+ --> $DIR/uninlined_format_args.rs:51:5
|
LL | println!("{}", fn_arg);
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +94,7 @@ LL + println!("{fn_arg}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:53:5
+ --> $DIR/uninlined_format_args.rs:52:5
|
LL | println!("{:?}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +106,7 @@ LL + println!("{local_i32:?}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:54:5
+ --> $DIR/uninlined_format_args.rs:53:5
|
LL | println!("{:#?}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -108,7 +118,7 @@ LL + println!("{local_i32:#?}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:55:5
+ --> $DIR/uninlined_format_args.rs:54:5
|
LL | println!("{:4}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -120,7 +130,7 @@ LL + println!("{local_i32:4}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:56:5
+ --> $DIR/uninlined_format_args.rs:55:5
|
LL | println!("{:04}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -132,7 +142,7 @@ LL + println!("{local_i32:04}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:57:5
+ --> $DIR/uninlined_format_args.rs:56:5
|
LL | println!("{:<3}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +154,7 @@ LL + println!("{local_i32:<3}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:58:5
+ --> $DIR/uninlined_format_args.rs:57:5
|
LL | println!("{:#010x}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -156,7 +166,7 @@ LL + println!("{local_i32:#010x}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:59:5
+ --> $DIR/uninlined_format_args.rs:58:5
|
LL | println!("{:.1}", local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -168,44 +178,8 @@ LL + println!("{local_f64:.1}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:60:5
- |
-LL | println!("Hello {} is {:.*}", "x", local_i32, local_f64);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: change this to
- |
-LL - println!("Hello {} is {:.*}", "x", local_i32, local_f64);
-LL + println!("Hello {} is {local_f64:.local_i32$}", "x");
- |
-
-error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:61:5
- |
-LL | println!("Hello {} is {:.*}", local_i32, 5, local_f64);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: change this to
- |
-LL - println!("Hello {} is {:.*}", local_i32, 5, local_f64);
-LL + println!("Hello {local_i32} is {local_f64:.*}", 5);
- |
-
-error: variables can be used directly in the `format!` string
--> $DIR/uninlined_format_args.rs:62:5
|
-LL | println!("Hello {} is {2:.*}", local_i32, 5, local_f64);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: change this to
- |
-LL - println!("Hello {} is {2:.*}", local_i32, 5, local_f64);
-LL + println!("Hello {local_i32} is {local_f64:.*}", 5);
- |
-
-error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:63:5
- |
LL | println!("{} {}", local_i32, local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@@ -218,18 +192,6 @@ LL + println!("{local_i32} {local_f64}");
error: variables can be used directly in the `format!` string
--> $DIR/uninlined_format_args.rs:64:5
|
-LL | println!("{}, {}", local_i32, local_opt.unwrap());
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: change this to
- |
-LL - println!("{}, {}", local_i32, local_opt.unwrap());
-LL + println!("{local_i32}, {}", local_opt.unwrap());
- |
-
-error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:65:5
- |
LL | println!("{}", val);
| ^^^^^^^^^^^^^^^^^^^
|
@@ -240,7 +202,7 @@ LL + println!("{val}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:66:5
+ --> $DIR/uninlined_format_args.rs:65:5
|
LL | println!("{}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -252,7 +214,7 @@ LL + println!("{val}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:68:5
+ --> $DIR/uninlined_format_args.rs:67:5
|
LL | println!("val='{/t }'", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -264,7 +226,7 @@ LL + println!("val='{local_i32}'");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:69:5
+ --> $DIR/uninlined_format_args.rs:68:5
|
LL | println!("val='{/n }'", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -276,7 +238,7 @@ LL + println!("val='{local_i32}'");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:70:5
+ --> $DIR/uninlined_format_args.rs:69:5
|
LL | println!("val='{local_i32}'", local_i32 = local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -288,7 +250,7 @@ LL + println!("val='{local_i32}'");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:71:5
+ --> $DIR/uninlined_format_args.rs:70:5
|
LL | println!("val='{local_i32}'", local_i32 = fn_arg);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -300,7 +262,7 @@ LL + println!("val='{fn_arg}'");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:72:5
+ --> $DIR/uninlined_format_args.rs:71:5
|
LL | println!("{0}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -312,7 +274,7 @@ LL + println!("{local_i32}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:73:5
+ --> $DIR/uninlined_format_args.rs:72:5
|
LL | println!("{0:?}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -324,7 +286,7 @@ LL + println!("{local_i32:?}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:74:5
+ --> $DIR/uninlined_format_args.rs:73:5
|
LL | println!("{0:#?}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -336,7 +298,7 @@ LL + println!("{local_i32:#?}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:75:5
+ --> $DIR/uninlined_format_args.rs:74:5
|
LL | println!("{0:04}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -348,7 +310,7 @@ LL + println!("{local_i32:04}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:76:5
+ --> $DIR/uninlined_format_args.rs:75:5
|
LL | println!("{0:<3}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -360,7 +322,7 @@ LL + println!("{local_i32:<3}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:77:5
+ --> $DIR/uninlined_format_args.rs:76:5
|
LL | println!("{0:#010x}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -372,7 +334,7 @@ LL + println!("{local_i32:#010x}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:78:5
+ --> $DIR/uninlined_format_args.rs:77:5
|
LL | println!("{0:.1}", local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -384,7 +346,7 @@ LL + println!("{local_f64:.1}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:79:5
+ --> $DIR/uninlined_format_args.rs:78:5
|
LL | println!("{0} {0}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -396,7 +358,7 @@ LL + println!("{local_i32} {local_i32}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:80:5
+ --> $DIR/uninlined_format_args.rs:79:5
|
LL | println!("{1} {} {0} {}", local_i32, local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -408,7 +370,7 @@ LL + println!("{local_f64} {local_i32} {local_i32} {local_f64}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:81:5
+ --> $DIR/uninlined_format_args.rs:80:5
|
LL | println!("{0} {1}", local_i32, local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -420,7 +382,7 @@ LL + println!("{local_i32} {local_f64}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:82:5
+ --> $DIR/uninlined_format_args.rs:81:5
|
LL | println!("{1} {0}", local_i32, local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -432,7 +394,7 @@ LL + println!("{local_f64} {local_i32}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:83:5
+ --> $DIR/uninlined_format_args.rs:82:5
|
LL | println!("{1} {0} {1} {0}", local_i32, local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -444,7 +406,7 @@ LL + println!("{local_f64} {local_i32} {local_f64} {local_i32}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:85:5
+ --> $DIR/uninlined_format_args.rs:84:5
|
LL | println!("{v}", v = local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -456,7 +418,7 @@ LL + println!("{local_i32}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:86:5
+ --> $DIR/uninlined_format_args.rs:85:5
|
LL | println!("{local_i32:0$}", width);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -468,7 +430,7 @@ LL + println!("{local_i32:width$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:87:5
+ --> $DIR/uninlined_format_args.rs:86:5
|
LL | println!("{local_i32:w$}", w = width);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -480,7 +442,7 @@ LL + println!("{local_i32:width$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:88:5
+ --> $DIR/uninlined_format_args.rs:87:5
|
LL | println!("{local_i32:.0$}", prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -492,7 +454,7 @@ LL + println!("{local_i32:.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:89:5
+ --> $DIR/uninlined_format_args.rs:88:5
|
LL | println!("{local_i32:.p$}", p = prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -504,7 +466,7 @@ LL + println!("{local_i32:.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:90:5
+ --> $DIR/uninlined_format_args.rs:89:5
|
LL | println!("{:0$}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -516,7 +478,7 @@ LL + println!("{val:val$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:91:5
+ --> $DIR/uninlined_format_args.rs:90:5
|
LL | println!("{0:0$}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -528,7 +490,7 @@ LL + println!("{val:val$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:92:5
+ --> $DIR/uninlined_format_args.rs:91:5
|
LL | println!("{:0$.0$}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -540,7 +502,7 @@ LL + println!("{val:val$.val$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:93:5
+ --> $DIR/uninlined_format_args.rs:92:5
|
LL | println!("{0:0$.0$}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -552,7 +514,7 @@ LL + println!("{val:val$.val$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:94:5
+ --> $DIR/uninlined_format_args.rs:93:5
|
LL | println!("{0:0$.v$}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -564,7 +526,7 @@ LL + println!("{val:val$.val$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:95:5
+ --> $DIR/uninlined_format_args.rs:94:5
|
LL | println!("{0:v$.0$}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -576,7 +538,7 @@ LL + println!("{val:val$.val$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:96:5
+ --> $DIR/uninlined_format_args.rs:95:5
|
LL | println!("{v:0$.0$}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -588,7 +550,7 @@ LL + println!("{val:val$.val$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:97:5
+ --> $DIR/uninlined_format_args.rs:96:5
|
LL | println!("{v:v$.0$}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -600,7 +562,7 @@ LL + println!("{val:val$.val$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:98:5
+ --> $DIR/uninlined_format_args.rs:97:5
|
LL | println!("{v:0$.v$}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -612,7 +574,7 @@ LL + println!("{val:val$.val$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:99:5
+ --> $DIR/uninlined_format_args.rs:98:5
|
LL | println!("{v:v$.v$}", v = val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -624,7 +586,7 @@ LL + println!("{val:val$.val$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:100:5
+ --> $DIR/uninlined_format_args.rs:99:5
|
LL | println!("{:0$}", width);
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -636,7 +598,7 @@ LL + println!("{width:width$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:101:5
+ --> $DIR/uninlined_format_args.rs:100:5
|
LL | println!("{:1$}", local_i32, width);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -648,7 +610,7 @@ LL + println!("{local_i32:width$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:102:5
+ --> $DIR/uninlined_format_args.rs:101:5
|
LL | println!("{:w$}", w = width);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -660,7 +622,7 @@ LL + println!("{width:width$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:103:5
+ --> $DIR/uninlined_format_args.rs:102:5
|
LL | println!("{:w$}", local_i32, w = width);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -672,7 +634,7 @@ LL + println!("{local_i32:width$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:104:5
+ --> $DIR/uninlined_format_args.rs:103:5
|
LL | println!("{:.0$}", prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -684,7 +646,7 @@ LL + println!("{prec:.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:105:5
+ --> $DIR/uninlined_format_args.rs:104:5
|
LL | println!("{:.1$}", local_i32, prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -696,7 +658,7 @@ LL + println!("{local_i32:.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:106:5
+ --> $DIR/uninlined_format_args.rs:105:5
|
LL | println!("{:.p$}", p = prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -708,7 +670,7 @@ LL + println!("{prec:.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:107:5
+ --> $DIR/uninlined_format_args.rs:106:5
|
LL | println!("{:.p$}", local_i32, p = prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -720,7 +682,7 @@ LL + println!("{local_i32:.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:108:5
+ --> $DIR/uninlined_format_args.rs:107:5
|
LL | println!("{:0$.1$}", width, prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -732,7 +694,7 @@ LL + println!("{width:width$.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:109:5
+ --> $DIR/uninlined_format_args.rs:108:5
|
LL | println!("{:0$.w$}", width, w = prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -744,7 +706,7 @@ LL + println!("{width:width$.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:110:5
+ --> $DIR/uninlined_format_args.rs:109:5
|
LL | println!("{:1$.2$}", local_f64, width, prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -756,7 +718,7 @@ LL + println!("{local_f64:width$.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:111:5
+ --> $DIR/uninlined_format_args.rs:110:5
|
LL | println!("{:1$.2$} {0} {1} {2}", local_f64, width, prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -768,7 +730,16 @@ LL + println!("{local_f64:width$.prec$} {local_f64} {width} {prec}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:123:5
+ --> $DIR/uninlined_format_args.rs:111:5
+ |
+LL | / println!(
+LL | | "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}",
+LL | | local_i32, width, prec,
+LL | | );
+ | |_____^
+
+error: variables can be used directly in the `format!` string
+ --> $DIR/uninlined_format_args.rs:122:5
|
LL | println!("Width = {}, value with width = {:0$}", local_i32, local_f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -780,7 +751,7 @@ LL + println!("Width = {local_i32}, value with width = {local_f64:local_i32$
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:124:5
+ --> $DIR/uninlined_format_args.rs:123:5
|
LL | println!("{:w$.p$}", local_i32, w = width, p = prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -792,7 +763,7 @@ LL + println!("{local_i32:width$.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:125:5
+ --> $DIR/uninlined_format_args.rs:124:5
|
LL | println!("{:w$.p$}", w = width, p = prec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -804,7 +775,7 @@ LL + println!("{width:width$.prec$}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:126:20
+ --> $DIR/uninlined_format_args.rs:125:20
|
LL | println!("{}", format!("{}", local_i32));
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -816,7 +787,17 @@ LL + println!("{}", format!("{local_i32}"));
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:149:5
+ --> $DIR/uninlined_format_args.rs:143:5
+ |
+LL | / println!(
+LL | | "{}",
+LL | | // comment with a comma , in it
+LL | | val,
+LL | | );
+ | |_____^
+
+error: variables can be used directly in the `format!` string
+ --> $DIR/uninlined_format_args.rs:148:5
|
LL | println!("{}", /* comment with a comma , in it */ val);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -828,7 +809,7 @@ LL + println!("{val}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:155:9
+ --> $DIR/uninlined_format_args.rs:154:9
|
LL | panic!("p1 {}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -840,7 +821,7 @@ LL + panic!("p1 {local_i32}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:158:9
+ --> $DIR/uninlined_format_args.rs:157:9
|
LL | panic!("p2 {0}", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -852,7 +833,7 @@ LL + panic!("p2 {local_i32}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:161:9
+ --> $DIR/uninlined_format_args.rs:160:9
|
LL | panic!("p3 {local_i32}", local_i32 = local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -864,7 +845,7 @@ LL + panic!("p3 {local_i32}");
|
error: variables can be used directly in the `format!` string
- --> $DIR/uninlined_format_args.rs:181:5
+ --> $DIR/uninlined_format_args.rs:180:5
|
LL | println!("expand='{}'", local_i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -875,5 +856,5 @@ LL - println!("expand='{}'", local_i32);
LL + println!("expand='{local_i32}'");
|
-error: aborting due to 73 previous errors
+error: aborting due to 72 previous errors
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.fixed b/src/tools/clippy/tests/ui/unnecessary_cast.fixed
index ec8c6abfa..2f7e2997e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.fixed
@@ -41,6 +41,17 @@ fn main() {
// do not lint cast to alias type
1 as I32Alias;
&1 as &I32Alias;
+
+ // issue #9960
+ macro_rules! bind_var {
+ ($id:ident, $e:expr) => {{
+ let $id = 0usize;
+ let _ = $e != 0usize;
+ let $id = 0isize;
+ let _ = $e != 0usize;
+ }}
+ }
+ bind_var!(x, (x as usize) + 1);
}
type I32Alias = i32;
@@ -85,6 +96,9 @@ mod fixable {
let _ = 1 as I32Alias;
let _ = &1 as &I32Alias;
+
+ let x = 1i32;
+ let _ = &{ x };
}
type I32Alias = i32;
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.rs b/src/tools/clippy/tests/ui/unnecessary_cast.rs
index 5213cdc26..54dd46ba5 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.rs
@@ -41,6 +41,17 @@ fn main() {
// do not lint cast to alias type
1 as I32Alias;
&1 as &I32Alias;
+
+ // issue #9960
+ macro_rules! bind_var {
+ ($id:ident, $e:expr) => {{
+ let $id = 0usize;
+ let _ = $e != 0usize;
+ let $id = 0isize;
+ let _ = $e != 0usize;
+ }}
+ }
+ bind_var!(x, (x as usize) + 1);
}
type I32Alias = i32;
@@ -85,6 +96,9 @@ mod fixable {
let _ = 1 as I32Alias;
let _ = &1 as &I32Alias;
+
+ let x = 1i32;
+ let _ = &(x as i32);
}
type I32Alias = i32;
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.stderr b/src/tools/clippy/tests/ui/unnecessary_cast.stderr
index e5c3dd5e5..fcee4ee2a 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.stderr
@@ -49,136 +49,142 @@ LL | 1_f32 as f32;
| ^^^^^^^^^^^^ help: try: `1_f32`
error: casting integer literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:53:9
+ --> $DIR/unnecessary_cast.rs:64:9
|
LL | 100 as f32;
| ^^^^^^^^^^ help: try: `100_f32`
error: casting integer literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:54:9
+ --> $DIR/unnecessary_cast.rs:65:9
|
LL | 100 as f64;
| ^^^^^^^^^^ help: try: `100_f64`
error: casting integer literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:55:9
+ --> $DIR/unnecessary_cast.rs:66:9
|
LL | 100_i32 as f64;
| ^^^^^^^^^^^^^^ help: try: `100_f64`
error: casting integer literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:56:17
+ --> $DIR/unnecessary_cast.rs:67:17
|
LL | let _ = -100 as f32;
| ^^^^^^^^^^^ help: try: `-100_f32`
error: casting integer literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:57:17
+ --> $DIR/unnecessary_cast.rs:68:17
|
LL | let _ = -100 as f64;
| ^^^^^^^^^^^ help: try: `-100_f64`
error: casting integer literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:58:17
+ --> $DIR/unnecessary_cast.rs:69:17
|
LL | let _ = -100_i32 as f64;
| ^^^^^^^^^^^^^^^ help: try: `-100_f64`
error: casting float literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:59:9
+ --> $DIR/unnecessary_cast.rs:70:9
|
LL | 100. as f32;
| ^^^^^^^^^^^ help: try: `100_f32`
error: casting float literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:60:9
+ --> $DIR/unnecessary_cast.rs:71:9
|
LL | 100. as f64;
| ^^^^^^^^^^^ help: try: `100_f64`
error: casting integer literal to `u32` is unnecessary
- --> $DIR/unnecessary_cast.rs:72:9
+ --> $DIR/unnecessary_cast.rs:83:9
|
LL | 1 as u32;
| ^^^^^^^^ help: try: `1_u32`
error: casting integer literal to `i32` is unnecessary
- --> $DIR/unnecessary_cast.rs:73:9
+ --> $DIR/unnecessary_cast.rs:84:9
|
LL | 0x10 as i32;
| ^^^^^^^^^^^ help: try: `0x10_i32`
error: casting integer literal to `usize` is unnecessary
- --> $DIR/unnecessary_cast.rs:74:9
+ --> $DIR/unnecessary_cast.rs:85:9
|
LL | 0b10 as usize;
| ^^^^^^^^^^^^^ help: try: `0b10_usize`
error: casting integer literal to `u16` is unnecessary
- --> $DIR/unnecessary_cast.rs:75:9
+ --> $DIR/unnecessary_cast.rs:86:9
|
LL | 0o73 as u16;
| ^^^^^^^^^^^ help: try: `0o73_u16`
error: casting integer literal to `u32` is unnecessary
- --> $DIR/unnecessary_cast.rs:76:9
+ --> $DIR/unnecessary_cast.rs:87: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:78:9
+ --> $DIR/unnecessary_cast.rs:89:9
|
LL | 1.0 as f64;
| ^^^^^^^^^^ help: try: `1.0_f64`
error: casting float literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:79:9
+ --> $DIR/unnecessary_cast.rs:90:9
|
LL | 0.5 as f32;
| ^^^^^^^^^^ help: try: `0.5_f32`
error: casting integer literal to `i32` is unnecessary
- --> $DIR/unnecessary_cast.rs:83:17
+ --> $DIR/unnecessary_cast.rs:94:17
|
LL | let _ = -1 as i32;
| ^^^^^^^^^ help: try: `-1_i32`
error: casting float literal to `f32` is unnecessary
- --> $DIR/unnecessary_cast.rs:84:17
+ --> $DIR/unnecessary_cast.rs:95: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:101:18
+ |
+LL | let _ = &(x as i32);
+ | ^^^^^^^^^^ help: try: `{ x }`
+
error: casting integer literal to `i32` is unnecessary
- --> $DIR/unnecessary_cast.rs:93:22
+ --> $DIR/unnecessary_cast.rs:107:22
|
LL | let _: i32 = -(1) as i32;
| ^^^^^^^^^^^ help: try: `-1_i32`
error: casting integer literal to `i64` is unnecessary
- --> $DIR/unnecessary_cast.rs:95:22
+ --> $DIR/unnecessary_cast.rs:109:22
|
LL | let _: i64 = -(1) as i64;
| ^^^^^^^^^^^ help: try: `-1_i64`
error: casting float literal to `f64` is unnecessary
- --> $DIR/unnecessary_cast.rs:102:22
+ --> $DIR/unnecessary_cast.rs:116: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:104:23
+ --> $DIR/unnecessary_cast.rs:118: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:112:20
+ --> $DIR/unnecessary_cast.rs:126:20
|
LL | let _num = foo() as f32;
| ^^^^^^^^^^^^ help: try: `foo()`
-error: aborting due to 30 previous errors
+error: aborting due to 31 previous errors
diff --git a/src/tools/clippy/tests/ui/unnecessary_join.stderr b/src/tools/clippy/tests/ui/unnecessary_join.stderr
index 0b14b143a..e919a6d1d 100644
--- a/src/tools/clippy/tests/ui/unnecessary_join.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_join.stderr
@@ -1,4 +1,4 @@
-error: called `.collect<Vec<String>>().join("")` on an iterator
+error: called `.collect::<Vec<String>>().join("")` on an iterator
--> $DIR/unnecessary_join.rs:11:10
|
LL | .collect::<Vec<String>>()
@@ -8,7 +8,7 @@ LL | | .join("");
|
= note: `-D clippy::unnecessary-join` implied by `-D warnings`
-error: called `.collect<Vec<String>>().join("")` on an iterator
+error: called `.collect::<Vec<String>>().join("")` on an iterator
--> $DIR/unnecessary_join.rs:20: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 ce4a82e02..22e9bd8bd 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed
@@ -33,6 +33,14 @@ impl Drop for Issue9427 {
}
}
+struct Issue9427FollowUp;
+
+impl Drop for Issue9427FollowUp {
+ fn drop(&mut self) {
+ panic!("side effect drop");
+ }
+}
+
fn main() {
let astronomers_pi = 10;
let ext_arr: [usize; 1] = [2];
@@ -87,6 +95,7 @@ fn main() {
// Should not lint - bool
let _ = (0 == 1).then(|| Issue9427(0)); // Issue9427 has a significant drop
+ let _ = false.then(|| Issue9427FollowUp); // Issue9427FollowUp has a significant drop
// should not lint, bind_instead_of_map takes priority
let _ = Some(10).and_then(|idx| Some(ext_arr[idx]));
@@ -133,13 +142,13 @@ fn main() {
let _: Result<usize, usize> = res.or(Ok(astronomers_pi));
let _: Result<usize, usize> = res.or(Ok(ext_str.some_field));
let _: Result<usize, usize> = res.
- // some lines
- // some lines
- // some lines
- // some lines
- // some lines
- // some lines
- or(Ok(ext_str.some_field));
+ // some lines
+ // some lines
+ // some lines
+ // some lines
+ // some lines
+ // some lines
+ or(Ok(ext_str.some_field));
// neither bind_instead_of_map nor unnecessary_lazy_eval applies here
let _: Result<usize, usize> = res.and_then(|x| Err(x));
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs
index 59cdf6628..8726d84a2 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs
@@ -33,6 +33,14 @@ impl Drop for Issue9427 {
}
}
+struct Issue9427FollowUp;
+
+impl Drop for Issue9427FollowUp {
+ fn drop(&mut self) {
+ panic!("side effect drop");
+ }
+}
+
fn main() {
let astronomers_pi = 10;
let ext_arr: [usize; 1] = [2];
@@ -87,6 +95,7 @@ fn main() {
// Should not lint - bool
let _ = (0 == 1).then(|| Issue9427(0)); // Issue9427 has a significant drop
+ let _ = false.then(|| Issue9427FollowUp); // Issue9427FollowUp has a significant drop
// should not lint, bind_instead_of_map takes priority
let _ = Some(10).and_then(|idx| Some(ext_arr[idx]));
@@ -133,13 +142,13 @@ fn main() {
let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
let _: Result<usize, usize> = res.
- // some lines
- // some lines
- // some lines
- // some lines
- // some lines
- // some lines
- or_else(|_| Ok(ext_str.some_field));
+ // some lines
+ // some lines
+ // some lines
+ // some lines
+ // some lines
+ // some lines
+ or_else(|_| Ok(ext_str.some_field));
// neither bind_instead_of_map nor unnecessary_lazy_eval applies here
let _: Result<usize, usize> = res.and_then(|x| Err(x));
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
index 8a9ece4aa..033975544 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:48:13
+ --> $DIR/unnecessary_lazy_eval.rs:56:13
|
LL | let _ = opt.unwrap_or_else(|| 2);
| ^^^^--------------------
@@ -9,7 +9,7 @@ LL | let _ = opt.unwrap_or_else(|| 2);
= note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`
error: unnecessary closure used to substitute value for `Option::None`
- --> $DIR/unnecessary_lazy_eval.rs:49:13
+ --> $DIR/unnecessary_lazy_eval.rs:57:13
|
LL | let _ = opt.unwrap_or_else(|| astronomers_pi);
| ^^^^---------------------------------
@@ -17,7 +17,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:50:13
+ --> $DIR/unnecessary_lazy_eval.rs:58:13
|
LL | let _ = opt.unwrap_or_else(|| ext_str.some_field);
| ^^^^-------------------------------------
@@ -25,7 +25,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:52:13
+ --> $DIR/unnecessary_lazy_eval.rs:60:13
|
LL | let _ = opt.and_then(|_| ext_opt);
| ^^^^---------------------
@@ -33,7 +33,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:53:13
+ --> $DIR/unnecessary_lazy_eval.rs:61:13
|
LL | let _ = opt.or_else(|| ext_opt);
| ^^^^-------------------
@@ -41,7 +41,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:54:13
+ --> $DIR/unnecessary_lazy_eval.rs:62:13
|
LL | let _ = opt.or_else(|| None);
| ^^^^----------------
@@ -49,7 +49,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:55:13
+ --> $DIR/unnecessary_lazy_eval.rs:63:13
|
LL | let _ = opt.get_or_insert_with(|| 2);
| ^^^^------------------------
@@ -57,7 +57,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:56:13
+ --> $DIR/unnecessary_lazy_eval.rs:64:13
|
LL | let _ = opt.ok_or_else(|| 2);
| ^^^^----------------
@@ -65,7 +65,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:57:13
+ --> $DIR/unnecessary_lazy_eval.rs:65:13
|
LL | let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
| ^^^^^^^^^^^^^^^^^-------------------------------
@@ -73,7 +73,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:58:13
+ --> $DIR/unnecessary_lazy_eval.rs:66:13
|
LL | let _ = cond.then(|| astronomers_pi);
| ^^^^^-----------------------
@@ -81,7 +81,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:61:13
+ --> $DIR/unnecessary_lazy_eval.rs:69:13
|
LL | let _ = Some(10).unwrap_or_else(|| 2);
| ^^^^^^^^^--------------------
@@ -89,7 +89,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:62:13
+ --> $DIR/unnecessary_lazy_eval.rs:70:13
|
LL | let _ = Some(10).and_then(|_| ext_opt);
| ^^^^^^^^^---------------------
@@ -97,7 +97,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:63:28
+ --> $DIR/unnecessary_lazy_eval.rs:71:28
|
LL | let _: Option<usize> = None.or_else(|| ext_opt);
| ^^^^^-------------------
@@ -105,7 +105,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:64:13
+ --> $DIR/unnecessary_lazy_eval.rs:72:13
|
LL | let _ = None.get_or_insert_with(|| 2);
| ^^^^^------------------------
@@ -113,7 +113,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:65:35
+ --> $DIR/unnecessary_lazy_eval.rs:73:35
|
LL | let _: Result<usize, usize> = None.ok_or_else(|| 2);
| ^^^^^----------------
@@ -121,7 +121,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:66:28
+ --> $DIR/unnecessary_lazy_eval.rs:74:28
|
LL | let _: Option<usize> = None.or_else(|| None);
| ^^^^^----------------
@@ -129,7 +129,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:69:13
+ --> $DIR/unnecessary_lazy_eval.rs:77:13
|
LL | let _ = deep.0.unwrap_or_else(|| 2);
| ^^^^^^^--------------------
@@ -137,7 +137,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:70:13
+ --> $DIR/unnecessary_lazy_eval.rs:78:13
|
LL | let _ = deep.0.and_then(|_| ext_opt);
| ^^^^^^^---------------------
@@ -145,7 +145,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:71:13
+ --> $DIR/unnecessary_lazy_eval.rs:79:13
|
LL | let _ = deep.0.or_else(|| None);
| ^^^^^^^----------------
@@ -153,7 +153,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:72:13
+ --> $DIR/unnecessary_lazy_eval.rs:80:13
|
LL | let _ = deep.0.get_or_insert_with(|| 2);
| ^^^^^^^------------------------
@@ -161,7 +161,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:73:13
+ --> $DIR/unnecessary_lazy_eval.rs:81:13
|
LL | let _ = deep.0.ok_or_else(|| 2);
| ^^^^^^^----------------
@@ -169,7 +169,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:96:28
+ --> $DIR/unnecessary_lazy_eval.rs:105:28
|
LL | let _: Option<usize> = None.or_else(|| Some(3));
| ^^^^^-------------------
@@ -177,7 +177,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:97:13
+ --> $DIR/unnecessary_lazy_eval.rs:106:13
|
LL | let _ = deep.0.or_else(|| Some(3));
| ^^^^^^^-------------------
@@ -185,7 +185,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:98:13
+ --> $DIR/unnecessary_lazy_eval.rs:107:13
|
LL | let _ = opt.or_else(|| Some(3));
| ^^^^-------------------
@@ -193,7 +193,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:104:13
+ --> $DIR/unnecessary_lazy_eval.rs:113:13
|
LL | let _ = res2.unwrap_or_else(|_| 2);
| ^^^^^---------------------
@@ -201,7 +201,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:105:13
+ --> $DIR/unnecessary_lazy_eval.rs:114:13
|
LL | let _ = res2.unwrap_or_else(|_| astronomers_pi);
| ^^^^^----------------------------------
@@ -209,7 +209,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:106:13
+ --> $DIR/unnecessary_lazy_eval.rs:115:13
|
LL | let _ = res2.unwrap_or_else(|_| ext_str.some_field);
| ^^^^^--------------------------------------
@@ -217,7 +217,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:128:35
+ --> $DIR/unnecessary_lazy_eval.rs:137:35
|
LL | let _: Result<usize, usize> = res.and_then(|_| Err(2));
| ^^^^--------------------
@@ -225,7 +225,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:129:35
+ --> $DIR/unnecessary_lazy_eval.rs:138:35
|
LL | let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
| ^^^^---------------------------------
@@ -233,7 +233,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:130:35
+ --> $DIR/unnecessary_lazy_eval.rs:139:35
|
LL | let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));
| ^^^^-------------------------------------
@@ -241,7 +241,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:132:35
+ --> $DIR/unnecessary_lazy_eval.rs:141:35
|
LL | let _: Result<usize, usize> = res.or_else(|_| Ok(2));
| ^^^^------------------
@@ -249,7 +249,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:133:35
+ --> $DIR/unnecessary_lazy_eval.rs:142:35
|
LL | let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
| ^^^^-------------------------------
@@ -257,7 +257,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:134:35
+ --> $DIR/unnecessary_lazy_eval.rs:143:35
|
LL | let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
| ^^^^-----------------------------------
@@ -265,19 +265,19 @@ 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:135:35
+ --> $DIR/unnecessary_lazy_eval.rs:144:35
|
LL | let _: Result<usize, usize> = res.
| ___________________________________^
-LL | | // some lines
-LL | | // some lines
-LL | | // some lines
+LL | | // some lines
+LL | | // some lines
+LL | | // some lines
... |
-LL | | // some lines
-LL | | or_else(|_| Ok(ext_str.some_field));
- | |_________----------------------------------^
- | |
- | help: use `or(..)` instead: `or(Ok(ext_str.some_field))`
+LL | | // some lines
+LL | | or_else(|_| Ok(ext_str.some_field));
+ | |_____----------------------------------^
+ | |
+ | help: use `or(..)` instead: `or(Ok(ext_str.some_field))`
error: aborting due to 34 previous errors
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.fixed b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
index bf0ec8deb..d37163570 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
@@ -76,4 +76,13 @@ fn main() {
DropStruct { ..get_drop_struct() };
DropEnum::Tuple(get_number());
DropEnum::Struct { field: get_number() };
+
+ // Issue #9954
+ fn one() -> i8 {
+ 1
+ }
+ macro_rules! use_expr {
+ ($($e:expr),*) => {{ $($e;)* }}
+ }
+ use_expr!(isize::MIN / -(one() as isize), i8::MIN / -one());
}
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.rs b/src/tools/clippy/tests/ui/unnecessary_operation.rs
index 08cb9ab52..a14fd4bca 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.rs
@@ -80,4 +80,13 @@ fn main() {
DropStruct { ..get_drop_struct() };
DropEnum::Tuple(get_number());
DropEnum::Struct { field: get_number() };
+
+ // Issue #9954
+ fn one() -> i8 {
+ 1
+ }
+ macro_rules! use_expr {
+ ($($e:expr),*) => {{ $($e;)* }}
+ }
+ use_expr!(isize::MIN / -(one() as isize), i8::MIN / -one());
}
diff --git a/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs b/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs
new file mode 100644
index 000000000..7fefea705
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_safety_comment.rs
@@ -0,0 +1,51 @@
+#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]
+#![allow(clippy::let_unit_value, clippy::missing_safety_doc)]
+
+mod unsafe_items_invalid_comment {
+ // SAFETY:
+ const CONST: u32 = 0;
+ // SAFETY:
+ static STATIC: u32 = 0;
+ // SAFETY:
+ struct Struct;
+ // SAFETY:
+ enum Enum {}
+ // SAFETY:
+ mod module {}
+}
+
+mod unnecessary_from_macro {
+ trait T {}
+
+ macro_rules! no_safety_comment {
+ ($t:ty) => {
+ impl T for $t {}
+ };
+ }
+
+ // FIXME: This is not caught
+ // Safety: unnecessary
+ no_safety_comment!(());
+
+ macro_rules! with_safety_comment {
+ ($t:ty) => {
+ // Safety: unnecessary
+ impl T for $t {}
+ };
+ }
+
+ with_safety_comment!(i32);
+}
+
+fn unnecessary_on_stmt_and_expr() -> u32 {
+ // SAFETY: unnecessary
+ let num = 42;
+
+ // SAFETY: unnecessary
+ if num > 24 {}
+
+ // SAFETY: unnecessary
+ 24
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr b/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr
new file mode 100644
index 000000000..7b2af67d6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr
@@ -0,0 +1,115 @@
+error: constant item has unnecessary safety comment
+ --> $DIR/unnecessary_safety_comment.rs:6:5
+ |
+LL | const CONST: u32 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+help: consider removing the safety comment
+ --> $DIR/unnecessary_safety_comment.rs:5:5
+ |
+LL | // SAFETY:
+ | ^^^^^^^^^^
+ = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`
+
+error: static item has unnecessary safety comment
+ --> $DIR/unnecessary_safety_comment.rs:8:5
+ |
+LL | static STATIC: u32 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: consider removing the safety comment
+ --> $DIR/unnecessary_safety_comment.rs:7:5
+ |
+LL | // SAFETY:
+ | ^^^^^^^^^^
+
+error: struct has unnecessary safety comment
+ --> $DIR/unnecessary_safety_comment.rs:10:5
+ |
+LL | struct Struct;
+ | ^^^^^^^^^^^^^^
+ |
+help: consider removing the safety comment
+ --> $DIR/unnecessary_safety_comment.rs:9:5
+ |
+LL | // SAFETY:
+ | ^^^^^^^^^^
+
+error: enum has unnecessary safety comment
+ --> $DIR/unnecessary_safety_comment.rs:12:5
+ |
+LL | enum Enum {}
+ | ^^^^^^^^^^^^
+ |
+help: consider removing the safety comment
+ --> $DIR/unnecessary_safety_comment.rs:11:5
+ |
+LL | // SAFETY:
+ | ^^^^^^^^^^
+
+error: module has unnecessary safety comment
+ --> $DIR/unnecessary_safety_comment.rs:14:5
+ |
+LL | mod module {}
+ | ^^^^^^^^^^^^^
+ |
+help: consider removing the safety comment
+ --> $DIR/unnecessary_safety_comment.rs:13:5
+ |
+LL | // SAFETY:
+ | ^^^^^^^^^^
+
+error: impl has unnecessary safety comment
+ --> $DIR/unnecessary_safety_comment.rs:33:13
+ |
+LL | impl T for $t {}
+ | ^^^^^^^^^^^^^^^^
+...
+LL | with_safety_comment!(i32);
+ | ------------------------- in this macro invocation
+ |
+help: consider removing the safety comment
+ --> $DIR/unnecessary_safety_comment.rs:32: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
+ |
+LL | 24
+ | ^^
+ |
+help: consider removing the safety comment
+ --> $DIR/unnecessary_safety_comment.rs:47:5
+ |
+LL | // SAFETY: unnecessary
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: statement has unnecessary safety comment
+ --> $DIR/unnecessary_safety_comment.rs:42:5
+ |
+LL | let num = 42;
+ | ^^^^^^^^^^^^^
+ |
+help: consider removing the safety comment
+ --> $DIR/unnecessary_safety_comment.rs:41:5
+ |
+LL | // SAFETY: unnecessary
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: statement has unnecessary safety comment
+ --> $DIR/unnecessary_safety_comment.rs:45:5
+ |
+LL | if num > 24 {}
+ | ^^^^^^^^^^^^^^
+ |
+help: consider removing the safety comment
+ --> $DIR/unnecessary_safety_comment.rs:44:5
+ |
+LL | // SAFETY: unnecessary
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 9 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index fe09aad06..ddeda795f 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -2,7 +2,6 @@
#![allow(clippy::needless_borrow, clippy::ptr_arg)]
#![warn(clippy::unnecessary_to_owned)]
-#![feature(custom_inner_attributes)]
use std::borrow::Cow;
use std::ffi::{CStr, CString, OsStr, OsString};
@@ -215,14 +214,14 @@ fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::E
fn require_string(_: &String) {}
+#[clippy::msrv = "1.35"]
fn _msrv_1_35() {
- #![clippy::msrv = "1.35"]
// `copied` was stabilized in 1.36, so clippy should use `cloned`.
let _ = &["x"][..].iter().cloned();
}
+#[clippy::msrv = "1.36"]
fn _msrv_1_36() {
- #![clippy::msrv = "1.36"]
let _ = &["x"][..].iter().copied();
}
@@ -426,3 +425,32 @@ mod issue_9504 {
foo(std::path::PathBuf::new().to_string_lossy().to_string()).await;
}
}
+
+mod issue_9771a {
+ #![allow(dead_code)]
+
+ use std::marker::PhantomData;
+
+ pub struct Key<K: AsRef<[u8]>, V: ?Sized>(K, PhantomData<V>);
+
+ impl<K: AsRef<[u8]>, V: ?Sized> Key<K, V> {
+ pub fn new(key: K) -> Key<K, V> {
+ Key(key, PhantomData)
+ }
+ }
+
+ pub fn pkh(pkh: &[u8]) -> Key<Vec<u8>, String> {
+ Key::new([b"pkh-", pkh].concat().to_vec())
+ }
+}
+
+mod issue_9771b {
+ #![allow(dead_code)]
+
+ pub struct Key<K: AsRef<[u8]>>(K);
+
+ pub fn from(c: &[u8]) -> Key<Vec<u8>> {
+ let v = [c].concat();
+ Key(v.to_vec())
+ }
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index 3de6d0903..95d257673 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -2,7 +2,6 @@
#![allow(clippy::needless_borrow, clippy::ptr_arg)]
#![warn(clippy::unnecessary_to_owned)]
-#![feature(custom_inner_attributes)]
use std::borrow::Cow;
use std::ffi::{CStr, CString, OsStr, OsString};
@@ -215,14 +214,14 @@ fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::E
fn require_string(_: &String) {}
+#[clippy::msrv = "1.35"]
fn _msrv_1_35() {
- #![clippy::msrv = "1.35"]
// `copied` was stabilized in 1.36, so clippy should use `cloned`.
let _ = &["x"][..].to_vec().into_iter();
}
+#[clippy::msrv = "1.36"]
fn _msrv_1_36() {
- #![clippy::msrv = "1.36"]
let _ = &["x"][..].to_vec().into_iter();
}
@@ -426,3 +425,32 @@ mod issue_9504 {
foo(std::path::PathBuf::new().to_string_lossy().to_string()).await;
}
}
+
+mod issue_9771a {
+ #![allow(dead_code)]
+
+ use std::marker::PhantomData;
+
+ pub struct Key<K: AsRef<[u8]>, V: ?Sized>(K, PhantomData<V>);
+
+ impl<K: AsRef<[u8]>, V: ?Sized> Key<K, V> {
+ pub fn new(key: K) -> Key<K, V> {
+ Key(key, PhantomData)
+ }
+ }
+
+ pub fn pkh(pkh: &[u8]) -> Key<Vec<u8>, String> {
+ Key::new([b"pkh-", pkh].concat().to_vec())
+ }
+}
+
+mod issue_9771b {
+ #![allow(dead_code)]
+
+ pub struct Key<K: AsRef<[u8]>>(K);
+
+ pub fn from(c: &[u8]) -> Key<Vec<u8>> {
+ let v = [c].concat();
+ Key(v.to_vec())
+ }
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
index 02bf45a33..4918fe355 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
@@ -1,66 +1,66 @@
error: redundant clone
- --> $DIR/unnecessary_to_owned.rs:151:64
+ --> $DIR/unnecessary_to_owned.rs:150: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:151:20
+ --> $DIR/unnecessary_to_owned.rs:150:20
|
LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `-D clippy::redundant-clone` implied by `-D warnings`
error: redundant clone
- --> $DIR/unnecessary_to_owned.rs:152:40
+ --> $DIR/unnecessary_to_owned.rs:151: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:152:21
+ --> $DIR/unnecessary_to_owned.rs:151:21
|
LL | require_os_str(&OsString::from("x").to_os_string());
| ^^^^^^^^^^^^^^^^^^^
error: redundant clone
- --> $DIR/unnecessary_to_owned.rs:153:48
+ --> $DIR/unnecessary_to_owned.rs:152: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:153:19
+ --> $DIR/unnecessary_to_owned.rs:152:19
|
LL | require_path(&std::path::PathBuf::from("x").to_path_buf());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: redundant clone
- --> $DIR/unnecessary_to_owned.rs:154:35
+ --> $DIR/unnecessary_to_owned.rs:153: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:154:18
+ --> $DIR/unnecessary_to_owned.rs:153:18
|
LL | require_str(&String::from("x").to_string());
| ^^^^^^^^^^^^^^^^^
error: redundant clone
- --> $DIR/unnecessary_to_owned.rs:155:39
+ --> $DIR/unnecessary_to_owned.rs:154: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:155:20
+ --> $DIR/unnecessary_to_owned.rs:154:20
|
LL | require_slice(&[String::from("x")].to_owned());
| ^^^^^^^^^^^^^^^^^^^
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:60:36
+ --> $DIR/unnecessary_to_owned.rs:59:36
|
LL | require_c_str(&Cow::from(c_str).into_owned());
| ^^^^^^^^^^^^^ help: remove this
@@ -68,415 +68,415 @@ LL | require_c_str(&Cow::from(c_str).into_owned());
= note: `-D clippy::unnecessary-to-owned` implied by `-D warnings`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:61:19
+ --> $DIR/unnecessary_to_owned.rs:60: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:63:20
+ --> $DIR/unnecessary_to_owned.rs:62: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:64:38
+ --> $DIR/unnecessary_to_owned.rs:63: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:65:20
+ --> $DIR/unnecessary_to_owned.rs:64: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:67:18
+ --> $DIR/unnecessary_to_owned.rs:66:18
|
LL | require_path(&path.to_path_buf());
| ^^^^^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:68:34
+ --> $DIR/unnecessary_to_owned.rs:67:34
|
LL | require_path(&Cow::from(path).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:69:18
+ --> $DIR/unnecessary_to_owned.rs:68:18
|
LL | require_path(&path.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_string`
- --> $DIR/unnecessary_to_owned.rs:71:17
+ --> $DIR/unnecessary_to_owned.rs:70:17
|
LL | require_str(&s.to_string());
| ^^^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:72:30
+ --> $DIR/unnecessary_to_owned.rs:71:30
|
LL | require_str(&Cow::from(s).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:73:17
+ --> $DIR/unnecessary_to_owned.rs:72:17
|
LL | require_str(&s.to_owned());
| ^^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_string`
- --> $DIR/unnecessary_to_owned.rs:74:17
+ --> $DIR/unnecessary_to_owned.rs:73: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:76:19
+ --> $DIR/unnecessary_to_owned.rs:75:19
|
LL | require_slice(&slice.to_vec());
| ^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:77:36
+ --> $DIR/unnecessary_to_owned.rs:76:36
|
LL | require_slice(&Cow::from(slice).into_owned());
| ^^^^^^^^^^^^^ help: remove this
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:78:19
+ --> $DIR/unnecessary_to_owned.rs:77:19
|
LL | require_slice(&array.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:79:19
+ --> $DIR/unnecessary_to_owned.rs:78: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:80:19
+ --> $DIR/unnecessary_to_owned.rs:79:19
|
LL | require_slice(&slice.to_owned());
| ^^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `into_owned`
- --> $DIR/unnecessary_to_owned.rs:83:42
+ --> $DIR/unnecessary_to_owned.rs:82: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:86:25
+ --> $DIR/unnecessary_to_owned.rs:85: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:87:26
+ --> $DIR/unnecessary_to_owned.rs:86: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:88:24
+ --> $DIR/unnecessary_to_owned.rs:87:24
|
LL | require_deref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:89:23
+ --> $DIR/unnecessary_to_owned.rs:88:23
|
LL | require_deref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:90:25
+ --> $DIR/unnecessary_to_owned.rs:89:25
|
LL | require_deref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:92:30
+ --> $DIR/unnecessary_to_owned.rs:91: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:93:31
+ --> $DIR/unnecessary_to_owned.rs:92: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:94:29
+ --> $DIR/unnecessary_to_owned.rs:93:29
|
LL | require_impl_deref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:95:28
+ --> $DIR/unnecessary_to_owned.rs:94:28
|
LL | require_impl_deref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:96:30
+ --> $DIR/unnecessary_to_owned.rs:95:30
|
LL | require_impl_deref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:98:29
+ --> $DIR/unnecessary_to_owned.rs:97: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:98:43
+ --> $DIR/unnecessary_to_owned.rs:97: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:99:29
+ --> $DIR/unnecessary_to_owned.rs:98: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:99:47
+ --> $DIR/unnecessary_to_owned.rs:98: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:101:26
+ --> $DIR/unnecessary_to_owned.rs:100: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:102:27
+ --> $DIR/unnecessary_to_owned.rs:101: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:103:25
+ --> $DIR/unnecessary_to_owned.rs:102:25
|
LL | require_as_ref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:104:24
+ --> $DIR/unnecessary_to_owned.rs:103:24
|
LL | require_as_ref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:105:24
+ --> $DIR/unnecessary_to_owned.rs:104:24
|
LL | require_as_ref_str(x.to_owned());
| ^^^^^^^^^^^^ help: use: `&x`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:106:26
+ --> $DIR/unnecessary_to_owned.rs:105:26
|
LL | require_as_ref_slice(array.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:107:26
+ --> $DIR/unnecessary_to_owned.rs:106: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:108:26
+ --> $DIR/unnecessary_to_owned.rs:107:26
|
LL | require_as_ref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:110:31
+ --> $DIR/unnecessary_to_owned.rs:109: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:111:32
+ --> $DIR/unnecessary_to_owned.rs:110: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:112:30
+ --> $DIR/unnecessary_to_owned.rs:111:30
|
LL | require_impl_as_ref_path(path.to_owned());
| ^^^^^^^^^^^^^^^ help: use: `path`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:113:29
+ --> $DIR/unnecessary_to_owned.rs:112:29
|
LL | require_impl_as_ref_str(s.to_owned());
| ^^^^^^^^^^^^ help: use: `s`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:114:29
+ --> $DIR/unnecessary_to_owned.rs:113:29
|
LL | require_impl_as_ref_str(x.to_owned());
| ^^^^^^^^^^^^ help: use: `&x`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:115:31
+ --> $DIR/unnecessary_to_owned.rs:114:31
|
LL | require_impl_as_ref_slice(array.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `array`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:116:31
+ --> $DIR/unnecessary_to_owned.rs:115: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:117:31
+ --> $DIR/unnecessary_to_owned.rs:116:31
|
LL | require_impl_as_ref_slice(slice.to_owned());
| ^^^^^^^^^^^^^^^^ help: use: `slice`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:119:30
+ --> $DIR/unnecessary_to_owned.rs:118: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:119:44
+ --> $DIR/unnecessary_to_owned.rs:118: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:120:30
+ --> $DIR/unnecessary_to_owned.rs:119: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:120:44
+ --> $DIR/unnecessary_to_owned.rs:119: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:121:30
+ --> $DIR/unnecessary_to_owned.rs:120: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:121:44
+ --> $DIR/unnecessary_to_owned.rs:120: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:122:30
+ --> $DIR/unnecessary_to_owned.rs:121: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:122:48
+ --> $DIR/unnecessary_to_owned.rs:121: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:123:30
+ --> $DIR/unnecessary_to_owned.rs:122: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:123:52
+ --> $DIR/unnecessary_to_owned.rs:122: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:124:30
+ --> $DIR/unnecessary_to_owned.rs:123: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:124:48
+ --> $DIR/unnecessary_to_owned.rs:123: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:126:20
+ --> $DIR/unnecessary_to_owned.rs:125:20
|
LL | let _ = x.join(&x_ref.to_string());
| ^^^^^^^^^^^^^^^^^^ help: use: `x_ref`
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:128:13
+ --> $DIR/unnecessary_to_owned.rs:127:13
|
LL | let _ = slice.to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
error: unnecessary use of `to_owned`
- --> $DIR/unnecessary_to_owned.rs:129:13
+ --> $DIR/unnecessary_to_owned.rs:128:13
|
LL | let _ = slice.to_owned().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:130:13
+ --> $DIR/unnecessary_to_owned.rs:129: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:131:13
+ --> $DIR/unnecessary_to_owned.rs:130: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:133:13
+ --> $DIR/unnecessary_to_owned.rs:132: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:134:13
+ --> $DIR/unnecessary_to_owned.rs:133: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:135:13
+ --> $DIR/unnecessary_to_owned.rs:134: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:136:13
+ --> $DIR/unnecessary_to_owned.rs:135: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:198:14
+ --> $DIR/unnecessary_to_owned.rs:197:14
|
LL | for t in file_types.to_vec() {
| ^^^^^^^^^^^^^^^^^^^
@@ -492,25 +492,25 @@ LL + let path = match get_file_path(t) {
|
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:221:14
+ --> $DIR/unnecessary_to_owned.rs:220:14
|
LL | let _ = &["x"][..].to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()`
error: unnecessary use of `to_vec`
- --> $DIR/unnecessary_to_owned.rs:226:14
+ --> $DIR/unnecessary_to_owned.rs:225:14
|
LL | let _ = &["x"][..].to_vec().into_iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()`
error: unnecessary use of `to_string`
- --> $DIR/unnecessary_to_owned.rs:273:24
+ --> $DIR/unnecessary_to_owned.rs:272:24
|
LL | Box::new(build(y.to_string()))
| ^^^^^^^^^^^^^ help: use: `y`
error: unnecessary use of `to_string`
- --> $DIR/unnecessary_to_owned.rs:381:12
+ --> $DIR/unnecessary_to_owned.rs:380: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
new file mode 100644
index 000000000..c160e31af
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs
@@ -0,0 +1,149 @@
+// aux-build:doc_unsafe_macros.rs
+
+#![allow(clippy::let_unit_value)]
+#![warn(clippy::unnecessary_safety_doc)]
+
+#[macro_use]
+extern crate doc_unsafe_macros;
+
+/// This is has no safety section, and does not need one either
+pub fn destroy_the_planet() {
+ unimplemented!();
+}
+
+/// This one does not need a `Safety` section
+///
+/// # Safety
+///
+/// This function shouldn't be called unless the horsemen are ready
+pub fn apocalypse(universe: &mut ()) {
+ unimplemented!();
+}
+
+/// This is a private function, skip to match behavior with `missing_safety_doc`.
+///
+/// # Safety
+///
+/// Boo!
+fn you_dont_see_me() {
+ unimplemented!();
+}
+
+mod private_mod {
+ /// This is public but unexported function, skip to match behavior with `missing_safety_doc`.
+ ///
+ /// # Safety
+ ///
+ /// Very safe!
+ pub fn only_crate_wide_accessible() {
+ unimplemented!();
+ }
+
+ /// # Safety
+ ///
+ /// Unnecessary safety!
+ pub fn republished() {
+ unimplemented!();
+ }
+}
+
+pub use private_mod::republished;
+
+pub trait SafeTraitSafeMethods {
+ fn woefully_underdocumented(self);
+
+ /// # Safety
+ ///
+ /// Unnecessary!
+ fn documented(self);
+}
+
+pub trait SafeTrait {
+ fn method();
+}
+
+/// # Safety
+///
+/// Unnecessary!
+pub trait DocumentedSafeTrait {
+ fn method2();
+}
+
+pub struct Struct;
+
+impl SafeTraitSafeMethods for Struct {
+ fn woefully_underdocumented(self) {
+ // all is well
+ }
+
+ fn documented(self) {
+ // all is still well
+ }
+}
+
+impl SafeTrait for Struct {
+ fn method() {}
+}
+
+impl DocumentedSafeTrait for Struct {
+ fn method2() {}
+}
+
+impl Struct {
+ /// # Safety
+ ///
+ /// Unnecessary!
+ pub fn documented() -> Self {
+ unimplemented!();
+ }
+
+ pub fn undocumented(&self) {
+ unimplemented!();
+ }
+
+ /// Private, fine again to stay consistent with `missing_safety_doc`.
+ ///
+ /// # Safety
+ ///
+ /// Unnecessary!
+ fn private(&self) {
+ unimplemented!();
+ }
+}
+
+macro_rules! very_safe {
+ () => {
+ pub fn whee() {
+ unimplemented!()
+ }
+
+ /// # Safety
+ ///
+ /// Driving is very safe already!
+ pub fn drive() {
+ whee()
+ }
+ };
+}
+
+very_safe!();
+
+// we don't lint code from external macros
+undocd_safe!();
+
+fn main() {}
+
+// do not lint if any parent has `#[doc(hidden)]` attribute
+// see #7347
+#[doc(hidden)]
+pub mod __macro {
+ pub struct T;
+ impl T {
+ pub unsafe fn f() {}
+ }
+}
+
+/// # Implementation safety
+pub trait DocumentedSafeTraitWithImplementationHeader {
+ fn method();
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr
new file mode 100644
index 000000000..72898c93f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.stderr
@@ -0,0 +1,51 @@
+error: safe function's docs have unnecessary `# Safety` section
+ --> $DIR/unnecessary_unsafety_doc.rs:19:1
+ |
+LL | pub fn apocalypse(universe: &mut ()) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `-D clippy::unnecessary-safety-doc` implied by `-D warnings`
+
+error: safe function's docs have unnecessary `# Safety` section
+ --> $DIR/unnecessary_unsafety_doc.rs:45:5
+ |
+LL | pub fn republished() {
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: safe function's docs have unnecessary `# Safety` section
+ --> $DIR/unnecessary_unsafety_doc.rs:58:5
+ |
+LL | fn documented(self);
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: docs for safe trait have unnecessary `# Safety` section
+ --> $DIR/unnecessary_unsafety_doc.rs:68:1
+ |
+LL | pub trait DocumentedSafeTrait {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: safe function's docs have unnecessary `# Safety` section
+ --> $DIR/unnecessary_unsafety_doc.rs:96:5
+ |
+LL | pub fn documented() -> Self {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: safe function's docs have unnecessary `# Safety` section
+ --> $DIR/unnecessary_unsafety_doc.rs:123:9
+ |
+LL | pub fn drive() {
+ | ^^^^^^^^^^^^^^
+...
+LL | very_safe!();
+ | ------------ in this macro invocation
+ |
+ = note: this error originates in the macro `very_safe` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: docs for safe trait have unnecessary `# Safety` section
+ --> $DIR/unnecessary_unsafety_doc.rs:147:1
+ |
+LL | pub trait DocumentedSafeTraitWithImplementationHeader {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
index 9786c7b12..0a8e7b34d 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
@@ -1,6 +1,6 @@
// run-rustfix
-#![feature(box_patterns, custom_inner_attributes)]
+#![feature(box_patterns)]
#![warn(clippy::unnested_or_patterns)]
#![allow(clippy::cognitive_complexity, clippy::match_ref_pats, clippy::upper_case_acronyms)]
#![allow(unreachable_patterns, irrefutable_let_patterns, unused)]
@@ -34,14 +34,12 @@ fn main() {
if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
}
+#[clippy::msrv = "1.52"]
fn msrv_1_52() {
- #![clippy::msrv = "1.52"]
-
if let [1] | [52] = [0] {}
}
+#[clippy::msrv = "1.53"]
fn msrv_1_53() {
- #![clippy::msrv = "1.53"]
-
if let [1 | 53] = [0] {}
}
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.rs b/src/tools/clippy/tests/ui/unnested_or_patterns.rs
index f57322396..2c454adfe 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.rs
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.rs
@@ -1,6 +1,6 @@
// run-rustfix
-#![feature(box_patterns, custom_inner_attributes)]
+#![feature(box_patterns)]
#![warn(clippy::unnested_or_patterns)]
#![allow(clippy::cognitive_complexity, clippy::match_ref_pats, clippy::upper_case_acronyms)]
#![allow(unreachable_patterns, irrefutable_let_patterns, unused)]
@@ -34,14 +34,12 @@ fn main() {
if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
}
+#[clippy::msrv = "1.52"]
fn msrv_1_52() {
- #![clippy::msrv = "1.52"]
-
if let [1] | [52] = [0] {}
}
+#[clippy::msrv = "1.53"]
fn msrv_1_53() {
- #![clippy::msrv = "1.53"]
-
if let [1] | [53] = [0] {}
}
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
index fbc12fff0..a1f193db5 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
@@ -176,7 +176,7 @@ LL | if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}
| ~~~~~~~~~~~~~~~~~
error: unnested or-patterns
- --> $DIR/unnested_or_patterns.rs:46:12
+ --> $DIR/unnested_or_patterns.rs:44:12
|
LL | if let [1] | [53] = [0] {}
| ^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unused_rounding.fixed b/src/tools/clippy/tests/ui/unused_rounding.fixed
index 54f85806a..f6f734c05 100644
--- a/src/tools/clippy/tests/ui/unused_rounding.fixed
+++ b/src/tools/clippy/tests/ui/unused_rounding.fixed
@@ -6,4 +6,12 @@ fn main() {
let _ = 1.0f64;
let _ = 1.00f32;
let _ = 2e-54f64.floor();
+
+ // issue9866
+ let _ = 3.3_f32.round();
+ let _ = 3.3_f64.round();
+ let _ = 3.0_f32;
+
+ let _ = 3_3.0_0_f32;
+ let _ = 3_3.0_1_f64.round();
}
diff --git a/src/tools/clippy/tests/ui/unused_rounding.rs b/src/tools/clippy/tests/ui/unused_rounding.rs
index 8d007bc4a..a0267d814 100644
--- a/src/tools/clippy/tests/ui/unused_rounding.rs
+++ b/src/tools/clippy/tests/ui/unused_rounding.rs
@@ -6,4 +6,12 @@ fn main() {
let _ = 1.0f64.floor();
let _ = 1.00f32.round();
let _ = 2e-54f64.floor();
+
+ // issue9866
+ let _ = 3.3_f32.round();
+ let _ = 3.3_f64.round();
+ let _ = 3.0_f32.round();
+
+ let _ = 3_3.0_0_f32.round();
+ let _ = 3_3.0_1_f64.round();
}
diff --git a/src/tools/clippy/tests/ui/unused_rounding.stderr b/src/tools/clippy/tests/ui/unused_rounding.stderr
index 6cfb02e04..b867996fe 100644
--- a/src/tools/clippy/tests/ui/unused_rounding.stderr
+++ b/src/tools/clippy/tests/ui/unused_rounding.stderr
@@ -18,5 +18,17 @@ error: used the `round` method with a whole number float
LL | let _ = 1.00f32.round();
| ^^^^^^^^^^^^^^^ help: remove the `round` method call: `1.00f32`
-error: aborting due to 3 previous errors
+error: used the `round` method with a whole number float
+ --> $DIR/unused_rounding.rs:13: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
+ |
+LL | let _ = 3_3.0_0_f32.round();
+ | ^^^^^^^^^^^^^^^^^^^ help: remove the `round` method call: `3_3.0_0_f32`
+
+error: aborting due to 5 previous errors
diff --git a/src/tools/clippy/tests/ui/unused_unit.fixed b/src/tools/clippy/tests/ui/unused_unit.fixed
index 7bb43cf7a..3dd640b86 100644
--- a/src/tools/clippy/tests/ui/unused_unit.fixed
+++ b/src/tools/clippy/tests/ui/unused_unit.fixed
@@ -7,6 +7,7 @@
// test of the JSON error format.
#![feature(custom_inner_attributes)]
+#![feature(closure_lifetime_binder)]
#![rustfmt::skip]
#![deny(clippy::unused_unit)]
@@ -87,3 +88,9 @@ fn macro_expr() {
}
e!()
}
+
+mod issue9748 {
+ fn main() {
+ let _ = for<'a> |_: &'a u32| -> () {};
+ }
+}
diff --git a/src/tools/clippy/tests/ui/unused_unit.rs b/src/tools/clippy/tests/ui/unused_unit.rs
index 21073fb80..bddecf06f 100644
--- a/src/tools/clippy/tests/ui/unused_unit.rs
+++ b/src/tools/clippy/tests/ui/unused_unit.rs
@@ -7,6 +7,7 @@
// test of the JSON error format.
#![feature(custom_inner_attributes)]
+#![feature(closure_lifetime_binder)]
#![rustfmt::skip]
#![deny(clippy::unused_unit)]
@@ -87,3 +88,9 @@ fn macro_expr() {
}
e!()
}
+
+mod issue9748 {
+ fn main() {
+ let _ = for<'a> |_: &'a u32| -> () {};
+ }
+}
diff --git a/src/tools/clippy/tests/ui/unused_unit.stderr b/src/tools/clippy/tests/ui/unused_unit.stderr
index 0d2cb7785..ce06738cf 100644
--- a/src/tools/clippy/tests/ui/unused_unit.stderr
+++ b/src/tools/clippy/tests/ui/unused_unit.stderr
@@ -1,119 +1,119 @@
error: unneeded unit return type
- --> $DIR/unused_unit.rs:19:58
+ --> $DIR/unused_unit.rs:20:58
|
LL | pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
| ^^^^^^ help: remove the `-> ()`
|
note: the lint level is defined here
- --> $DIR/unused_unit.rs:12:9
+ --> $DIR/unused_unit.rs:13:9
|
LL | #![deny(clippy::unused_unit)]
| ^^^^^^^^^^^^^^^^^^^
error: unneeded unit return type
- --> $DIR/unused_unit.rs:19:28
+ --> $DIR/unused_unit.rs:20:28
|
LL | pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:20:18
+ --> $DIR/unused_unit.rs:21:18
|
LL | where G: Fn() -> () {
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:21:26
+ --> $DIR/unused_unit.rs:22:26
|
LL | let _y: &dyn Fn() -> () = &f;
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:28:18
+ --> $DIR/unused_unit.rs:29:18
|
LL | fn into(self) -> () {
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit expression
- --> $DIR/unused_unit.rs:29:9
+ --> $DIR/unused_unit.rs:30:9
|
LL | ()
| ^^ help: remove the final `()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:34:29
+ --> $DIR/unused_unit.rs:35:29
|
LL | fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:36:19
+ --> $DIR/unused_unit.rs:37:19
|
LL | G: FnMut() -> (),
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:37:16
+ --> $DIR/unused_unit.rs:38:16
|
LL | H: Fn() -> ();
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:41:29
+ --> $DIR/unused_unit.rs:42:29
|
LL | fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:43:19
+ --> $DIR/unused_unit.rs:44:19
|
LL | G: FnMut() -> (),
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:44:16
+ --> $DIR/unused_unit.rs:45:16
|
LL | H: Fn() -> () {}
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:47:17
+ --> $DIR/unused_unit.rs:48:17
|
LL | fn return_unit() -> () { () }
| ^^^^^^ help: remove the `-> ()`
error: unneeded unit expression
- --> $DIR/unused_unit.rs:47:26
+ --> $DIR/unused_unit.rs:48:26
|
LL | fn return_unit() -> () { () }
| ^^ help: remove the final `()`
error: unneeded `()`
- --> $DIR/unused_unit.rs:57:14
+ --> $DIR/unused_unit.rs:58:14
|
LL | break();
| ^^ help: remove the `()`
error: unneeded `()`
- --> $DIR/unused_unit.rs:59:11
+ --> $DIR/unused_unit.rs:60:11
|
LL | return();
| ^^ help: remove the `()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:76:10
+ --> $DIR/unused_unit.rs:77:10
|
LL | fn test()->(){}
| ^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:79:11
+ --> $DIR/unused_unit.rs:80:11
|
LL | fn test2() ->(){}
| ^^^^^ help: remove the `-> ()`
error: unneeded unit return type
- --> $DIR/unused_unit.rs:82:11
+ --> $DIR/unused_unit.rs:83:11
|
LL | fn test3()-> (){}
| ^^^^^ help: remove the `-> ()`
diff --git a/src/tools/clippy/tests/ui/unwrap.stderr b/src/tools/clippy/tests/ui/unwrap.stderr
index e88d580f7..d49bf2b32 100644
--- a/src/tools/clippy/tests/ui/unwrap.stderr
+++ b/src/tools/clippy/tests/ui/unwrap.stderr
@@ -1,4 +1,4 @@
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap.rs:5:13
|
LL | let _ = opt.unwrap();
@@ -7,7 +7,7 @@ LL | let _ = opt.unwrap();
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message
= note: `-D clippy::unwrap-used` implied by `-D warnings`
-error: used `unwrap()` on `a Result` value
+error: used `unwrap()` on a `Result` value
--> $DIR/unwrap.rs:10:13
|
LL | let _ = res.unwrap();
@@ -15,7 +15,7 @@ LL | let _ = res.unwrap();
|
= help: if you don't want to handle the `Err` case gracefully, consider using `expect()` to provide a better panic message
-error: used `unwrap_err()` on `a Result` value
+error: used `unwrap_err()` on a `Result` value
--> $DIR/unwrap.rs:11:13
|
LL | let _ = res.unwrap_err();
diff --git a/src/tools/clippy/tests/ui/unwrap_expect_used.stderr b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
index 211d2be18..fe4ecef11 100644
--- a/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
+++ b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr
@@ -1,4 +1,4 @@
-error: used `unwrap()` on `an Option` value
+error: used `unwrap()` on an `Option` value
--> $DIR/unwrap_expect_used.rs:23:5
|
LL | Some(3).unwrap();
@@ -7,7 +7,7 @@ LL | Some(3).unwrap();
= help: if this value is `None`, it will panic
= note: `-D clippy::unwrap-used` implied by `-D warnings`
-error: used `expect()` on `an Option` value
+error: used `expect()` on an `Option` value
--> $DIR/unwrap_expect_used.rs:24:5
|
LL | Some(3).expect("Hello world!");
@@ -16,7 +16,7 @@ LL | Some(3).expect("Hello world!");
= help: if this value is `None`, it will panic
= note: `-D clippy::expect-used` implied by `-D warnings`
-error: used `unwrap()` on `a Result` value
+error: used `unwrap()` on a `Result` value
--> $DIR/unwrap_expect_used.rs:31:5
|
LL | a.unwrap();
@@ -24,7 +24,7 @@ LL | a.unwrap();
|
= help: if this value is an `Err`, it will panic
-error: used `expect()` on `a Result` value
+error: used `expect()` on a `Result` value
--> $DIR/unwrap_expect_used.rs:32:5
|
LL | a.expect("Hello world!");
@@ -32,7 +32,7 @@ LL | a.expect("Hello world!");
|
= help: if this value is an `Err`, it will panic
-error: used `unwrap_err()` on `a Result` value
+error: used `unwrap_err()` on a `Result` value
--> $DIR/unwrap_expect_used.rs:33:5
|
LL | a.unwrap_err();
@@ -40,7 +40,7 @@ LL | a.unwrap_err();
|
= help: if this value is an `Ok`, it will panic
-error: used `expect_err()` on `a Result` value
+error: used `expect_err()` on a `Result` value
--> $DIR/unwrap_expect_used.rs:34:5
|
LL | a.expect_err("Hello error!");
diff --git a/src/tools/clippy/tests/ui/unwrap_or.rs b/src/tools/clippy/tests/ui/unwrap_or.rs
index bfb41e439..a0c003f5b 100644
--- a/src/tools/clippy/tests/ui/unwrap_or.rs
+++ b/src/tools/clippy/tests/ui/unwrap_or.rs
@@ -1,4 +1,4 @@
-#![warn(clippy::all)]
+#![warn(clippy::all, clippy::or_fun_call)]
fn main() {
let s = Some(String::from("test string")).unwrap_or("Fail".to_string()).len();
diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed
index 3b54fe9d5..0a6166571 100644
--- a/src/tools/clippy/tests/ui/use_self.fixed
+++ b/src/tools/clippy/tests/ui/use_self.fixed
@@ -1,7 +1,6 @@
// run-rustfix
// aux-build:proc_macro_derive.rs
-#![feature(custom_inner_attributes)]
#![warn(clippy::use_self)]
#![allow(dead_code, unreachable_code)]
#![allow(
@@ -619,9 +618,8 @@ mod issue6902 {
}
}
+#[clippy::msrv = "1.36"]
fn msrv_1_36() {
- #![clippy::msrv = "1.36"]
-
enum E {
A,
}
@@ -635,9 +633,8 @@ fn msrv_1_36() {
}
}
+#[clippy::msrv = "1.37"]
fn msrv_1_37() {
- #![clippy::msrv = "1.37"]
-
enum E {
A,
}
diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs
index bf87633cd..39c2b431f 100644
--- a/src/tools/clippy/tests/ui/use_self.rs
+++ b/src/tools/clippy/tests/ui/use_self.rs
@@ -1,7 +1,6 @@
// run-rustfix
// aux-build:proc_macro_derive.rs
-#![feature(custom_inner_attributes)]
#![warn(clippy::use_self)]
#![allow(dead_code, unreachable_code)]
#![allow(
@@ -619,9 +618,8 @@ mod issue6902 {
}
}
+#[clippy::msrv = "1.36"]
fn msrv_1_36() {
- #![clippy::msrv = "1.36"]
-
enum E {
A,
}
@@ -635,9 +633,8 @@ fn msrv_1_36() {
}
}
+#[clippy::msrv = "1.37"]
fn msrv_1_37() {
- #![clippy::msrv = "1.37"]
-
enum E {
A,
}
diff --git a/src/tools/clippy/tests/ui/use_self.stderr b/src/tools/clippy/tests/ui/use_self.stderr
index 16fb06092..48364c40c 100644
--- a/src/tools/clippy/tests/ui/use_self.stderr
+++ b/src/tools/clippy/tests/ui/use_self.stderr
@@ -1,5 +1,5 @@
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:23:21
+ --> $DIR/use_self.rs:22:21
|
LL | fn new() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
@@ -7,247 +7,247 @@ LL | fn new() -> Foo {
= note: `-D clippy::use-self` implied by `-D warnings`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:24:13
+ --> $DIR/use_self.rs:23:13
|
LL | Foo {}
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:26:22
+ --> $DIR/use_self.rs:25:22
|
LL | fn test() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:27:13
+ --> $DIR/use_self.rs:26:13
|
LL | Foo::new()
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:32:25
+ --> $DIR/use_self.rs:31:25
|
LL | fn default() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:33:13
+ --> $DIR/use_self.rs:32:13
|
LL | Foo::new()
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:98:24
+ --> $DIR/use_self.rs:97: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:98:55
+ --> $DIR/use_self.rs:97: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:113:13
+ --> $DIR/use_self.rs:112:13
|
LL | TS(0)
| ^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:148:29
+ --> $DIR/use_self.rs:147:29
|
LL | fn bar() -> Bar {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:149:21
+ --> $DIR/use_self.rs:148:21
|
LL | Bar { foo: Foo {} }
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:160:21
+ --> $DIR/use_self.rs:159:21
|
LL | fn baz() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:161:13
+ --> $DIR/use_self.rs:160:13
|
LL | Foo {}
| ^^^ 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::B(42);
| ^^^^ 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::C { field: true };
| ^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:180:21
+ --> $DIR/use_self.rs:179:21
|
LL | let _ = Enum::A;
| ^^^^ 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::fun_1();
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:223:13
+ --> $DIR/use_self.rs:222:13
|
LL | nested::A::A;
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:225:13
+ --> $DIR/use_self.rs:224:13
|
LL | nested::A {};
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:244:13
+ --> $DIR/use_self.rs:243:13
|
LL | TestStruct::from_something()
| ^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:258:25
+ --> $DIR/use_self.rs:257:25
|
LL | async fn g() -> S {
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:259:13
+ --> $DIR/use_self.rs:258:13
|
LL | S {}
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:263:16
+ --> $DIR/use_self.rs:262:16
|
LL | &p[S::A..S::B]
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:263:22
+ --> $DIR/use_self.rs:262:22
|
LL | &p[S::A..S::B]
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:286:29
+ --> $DIR/use_self.rs:285:29
|
LL | fn foo(value: T) -> Foo<T> {
| ^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:287:13
+ --> $DIR/use_self.rs:286:13
|
LL | Foo::<T> { value }
| ^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:459:13
+ --> $DIR/use_self.rs:458:13
|
LL | A::new::<submod::B>(submod::B {})
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:496:13
+ --> $DIR/use_self.rs:495:13
|
LL | S2::new()
| ^^ 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::Bar => unimplemented!(),
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:534:17
+ --> $DIR/use_self.rs:533:17
|
LL | Foo::Baz => unimplemented!(),
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:540:20
+ --> $DIR/use_self.rs:539:20
|
LL | if let Foo::Bar = self {
| ^^^ 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::Num(n) => *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::TupleNums(n, _m) => *n,
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:566:17
+ --> $DIR/use_self.rs:565:17
|
LL | Something::StructNums { one, two: _ } => *one,
| ^^^^^^^^^ 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::Num(n) => *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::TupleNums(n, _m) => *n,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:574:17
+ --> $DIR/use_self.rs:573:17
|
LL | crate::issue8845::Something::StructNums { one, two: _ } => *one,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:590:17
+ --> $DIR/use_self.rs:589:17
|
LL | let Foo(x) = self;
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:595:17
+ --> $DIR/use_self.rs:594:17
|
LL | let crate::issue8845::Foo(x) = self;
| ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:602:17
+ --> $DIR/use_self.rs:601:17
|
LL | let Bar { x, .. } = self;
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:607:17
+ --> $DIR/use_self.rs:606:17
|
LL | let crate::issue8845::Bar { x, .. } = self;
| ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:648:17
+ --> $DIR/use_self.rs:645: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 9bcd692fb..4e779308d 100644
--- a/src/tools/clippy/tests/ui/use_self_trait.fixed
+++ b/src/tools/clippy/tests/ui/use_self_trait.fixed
@@ -47,8 +47,7 @@ impl Mul for Bad {
impl Clone for Bad {
fn clone(&self) -> Self {
- // FIXME: applicable here
- Bad
+ Self
}
}
@@ -112,4 +111,42 @@ impl NameTrait for u8 {
}
}
+mod impl_in_macro {
+ macro_rules! parse_ip_impl {
+ // minimized from serde=1.0.118
+ ($ty:ty) => {
+ impl FooTrait for $ty {
+ fn new() -> Self {
+ <$ty>::bar()
+ }
+ }
+ };
+ }
+
+ struct Foo;
+
+ trait FooTrait {
+ fn new() -> Self;
+ }
+
+ impl Foo {
+ fn bar() -> Self {
+ Self
+ }
+ }
+ parse_ip_impl!(Foo); // Should not lint
+}
+
+mod full_path_replacement {
+ trait Error {
+ fn custom<T: std::fmt::Display>(_msg: T) -> Self;
+ }
+
+ impl Error for std::fmt::Error {
+ fn custom<T: std::fmt::Display>(_msg: T) -> Self {
+ Self // Should lint
+ }
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/use_self_trait.rs b/src/tools/clippy/tests/ui/use_self_trait.rs
index de305d40f..325dc73b2 100644
--- a/src/tools/clippy/tests/ui/use_self_trait.rs
+++ b/src/tools/clippy/tests/ui/use_self_trait.rs
@@ -47,7 +47,6 @@ impl Mul for Bad {
impl Clone for Bad {
fn clone(&self) -> Self {
- // FIXME: applicable here
Bad
}
}
@@ -112,4 +111,42 @@ impl NameTrait for u8 {
}
}
+mod impl_in_macro {
+ macro_rules! parse_ip_impl {
+ // minimized from serde=1.0.118
+ ($ty:ty) => {
+ impl FooTrait for $ty {
+ fn new() -> Self {
+ <$ty>::bar()
+ }
+ }
+ };
+ }
+
+ struct Foo;
+
+ trait FooTrait {
+ fn new() -> Self;
+ }
+
+ impl Foo {
+ fn bar() -> Self {
+ Self
+ }
+ }
+ parse_ip_impl!(Foo); // Should not lint
+}
+
+mod full_path_replacement {
+ trait Error {
+ fn custom<T: std::fmt::Display>(_msg: T) -> Self;
+ }
+
+ impl Error for std::fmt::Error {
+ fn custom<T: std::fmt::Display>(_msg: T) -> Self {
+ std::fmt::Error // Should lint
+ }
+ }
+}
+
fn main() {}
diff --git a/src/tools/clippy/tests/ui/use_self_trait.stderr b/src/tools/clippy/tests/ui/use_self_trait.stderr
index 55af3ff2a..090729b9c 100644
--- a/src/tools/clippy/tests/ui/use_self_trait.stderr
+++ b/src/tools/clippy/tests/ui/use_self_trait.stderr
@@ -84,5 +84,17 @@ error: unnecessary structure name repetition
LL | fn mul(self, rhs: Bad) -> Bad {
| ^^^ help: use the applicable keyword: `Self`
-error: aborting due to 14 previous errors
+error: unnecessary structure name repetition
+ --> $DIR/use_self_trait.rs:50:9
+ |
+LL | Bad
+ | ^^^ help: use the applicable keyword: `Self`
+
+error: unnecessary structure name repetition
+ --> $DIR/use_self_trait.rs:147:13
+ |
+LL | std::fmt::Error // Should lint
+ | ^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
+
+error: aborting due to 16 previous errors
diff --git a/src/tools/clippy/tests/ui/useless_attribute.fixed b/src/tools/clippy/tests/ui/useless_attribute.fixed
index c23231a99..871e4fb5c 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.fixed
+++ b/src/tools/clippy/tests/ui/useless_attribute.fixed
@@ -1,6 +1,7 @@
// run-rustfix
// aux-build:proc_macro_derive.rs
+#![allow(unused)]
#![warn(clippy::useless_attribute)]
#![warn(unreachable_pub)]
#![feature(rustc_private)]
@@ -16,6 +17,13 @@ extern crate rustc_middle;
#[macro_use]
extern crate proc_macro_derive;
+fn test_indented_attr() {
+ #![allow(clippy::almost_swapped)]
+ use std::collections::HashSet;
+
+ let _ = HashSet::<u32>::default();
+}
+
// don't lint on unused_import for `use` items
#[allow(unused_imports)]
use std::collections;
@@ -63,13 +71,16 @@ mod c {
pub(crate) struct S;
}
-fn test_indented_attr() {
- #![allow(clippy::almost_swapped)]
- use std::collections::HashSet;
-
- let _ = HashSet::<u32>::default();
+// https://github.com/rust-lang/rust-clippy/issues/7511
+pub mod split {
+ #[allow(clippy::module_name_repetitions)]
+ pub use regex::SplitN;
}
+// https://github.com/rust-lang/rust-clippy/issues/8768
+#[allow(clippy::single_component_path_imports)]
+use regex;
+
fn main() {
test_indented_attr();
}
diff --git a/src/tools/clippy/tests/ui/useless_attribute.rs b/src/tools/clippy/tests/ui/useless_attribute.rs
index 7a7b198ea..cb50736ba 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.rs
+++ b/src/tools/clippy/tests/ui/useless_attribute.rs
@@ -1,6 +1,7 @@
// run-rustfix
// aux-build:proc_macro_derive.rs
+#![allow(unused)]
#![warn(clippy::useless_attribute)]
#![warn(unreachable_pub)]
#![feature(rustc_private)]
@@ -16,6 +17,13 @@ extern crate rustc_middle;
#[macro_use]
extern crate proc_macro_derive;
+fn test_indented_attr() {
+ #[allow(clippy::almost_swapped)]
+ use std::collections::HashSet;
+
+ let _ = HashSet::<u32>::default();
+}
+
// don't lint on unused_import for `use` items
#[allow(unused_imports)]
use std::collections;
@@ -63,13 +71,16 @@ mod c {
pub(crate) struct S;
}
-fn test_indented_attr() {
- #[allow(clippy::almost_swapped)]
- use std::collections::HashSet;
-
- let _ = HashSet::<u32>::default();
+// https://github.com/rust-lang/rust-clippy/issues/7511
+pub mod split {
+ #[allow(clippy::module_name_repetitions)]
+ pub use regex::SplitN;
}
+// https://github.com/rust-lang/rust-clippy/issues/8768
+#[allow(clippy::single_component_path_imports)]
+use regex;
+
fn main() {
test_indented_attr();
}
diff --git a/src/tools/clippy/tests/ui/useless_attribute.stderr b/src/tools/clippy/tests/ui/useless_attribute.stderr
index 255d28763..a7ea0df22 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.stderr
+++ b/src/tools/clippy/tests/ui/useless_attribute.stderr
@@ -1,5 +1,5 @@
error: useless lint attribute
- --> $DIR/useless_attribute.rs:8:1
+ --> $DIR/useless_attribute.rs:9:1
|
LL | #[allow(dead_code)]
| ^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![allow(dead_code)]`
@@ -7,13 +7,13 @@ LL | #[allow(dead_code)]
= note: `-D clippy::useless-attribute` implied by `-D warnings`
error: useless lint attribute
- --> $DIR/useless_attribute.rs:9:1
+ --> $DIR/useless_attribute.rs:10: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:67:5
+ --> $DIR/useless_attribute.rs:21:5
|
LL | #[allow(clippy::almost_swapped)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![allow(clippy::almost_swapped)]`
diff --git a/src/tools/clippy/tests/versioncheck.rs b/src/tools/clippy/tests/versioncheck.rs
index a6d8d0307..7a85386a3 100644
--- a/src/tools/clippy/tests/versioncheck.rs
+++ b/src/tools/clippy/tests/versioncheck.rs
@@ -6,7 +6,7 @@ use rustc_tools_util::VersionInfo;
use std::fs;
#[test]
-fn check_that_clippy_lints_and_clippy_utils_have_the_same_version_as_clippy() {
+fn consistent_clippy_crate_versions() {
fn read_version(path: &str) -> String {
let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("error reading `{path}`: {e:?}"));
contents
@@ -24,11 +24,16 @@ fn check_that_clippy_lints_and_clippy_utils_have_the_same_version_as_clippy() {
}
let clippy_version = read_version("Cargo.toml");
- let clippy_lints_version = read_version("clippy_lints/Cargo.toml");
- let clippy_utils_version = read_version("clippy_utils/Cargo.toml");
- assert_eq!(clippy_version, clippy_lints_version);
- assert_eq!(clippy_version, clippy_utils_version);
+ let paths = [
+ "declare_clippy_lint/Cargo.toml",
+ "clippy_lints/Cargo.toml",
+ "clippy_utils/Cargo.toml",
+ ];
+
+ for path in paths {
+ assert_eq!(clippy_version, read_version(path), "{path} version differs");
+ }
}
#[test]
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index 80c303938..acb476ee6 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -4,9 +4,26 @@ allow-unauthenticated = [
"good-first-issue"
]
-[assign]
-
# Allows shortcuts like `@rustbot ready`
#
# See https://github.com/rust-lang/triagebot/wiki/Shortcuts
[shortcut]
+
+[autolabel."S-waiting-on-review"]
+new_pr = true
+
+[assign]
+contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
+
+[assign.owners]
+"/.github" = ["@flip1995"]
+"*" = [
+ "@flip1995",
+ "@Manishearth",
+ "@llogiq",
+ "@giraffate",
+ "@xFrednet",
+ "@Alexendoo",
+ "@dswij",
+ "@Jarcho",
+]
diff --git a/src/tools/collect-license-metadata/Cargo.toml b/src/tools/collect-license-metadata/Cargo.toml
new file mode 100644
index 000000000..d0820cfc2
--- /dev/null
+++ b/src/tools/collect-license-metadata/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "collect-license-metadata"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+anyhow = "1.0.65"
+serde = { version = "1.0.147", features = ["derive"] }
+serde_json = "1.0.85"
+spdx-rs = "0.5.1"
diff --git a/src/tools/collect-license-metadata/src/licenses.rs b/src/tools/collect-license-metadata/src/licenses.rs
new file mode 100644
index 000000000..1c95b1bc8
--- /dev/null
+++ b/src/tools/collect-license-metadata/src/licenses.rs
@@ -0,0 +1,65 @@
+use std::collections::HashMap;
+
+const COPYRIGHT_PREFIXES: &[&str] = &["SPDX-FileCopyrightText:", "Copyright", "(c)", "(C)", "©"];
+
+pub(crate) struct LicensesInterner {
+ by_id: Vec<License>,
+ by_struct: HashMap<License, usize>,
+}
+
+impl LicensesInterner {
+ pub(crate) fn new() -> Self {
+ LicensesInterner { by_id: Vec::new(), by_struct: HashMap::new() }
+ }
+
+ pub(crate) fn intern(&mut self, mut license: License) -> LicenseId {
+ license.simplify();
+ if let Some(id) = self.by_struct.get(&license) {
+ LicenseId(*id)
+ } else {
+ let id = self.by_id.len();
+ self.by_id.push(license.clone());
+ self.by_struct.insert(license, id);
+ LicenseId(id)
+ }
+ }
+
+ pub(crate) fn resolve(&self, id: LicenseId) -> &License {
+ &self.by_id[id.0]
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
+#[serde(transparent)]
+pub(crate) struct LicenseId(usize);
+
+#[derive(Clone, Hash, PartialEq, Eq, serde::Serialize)]
+pub(crate) struct License {
+ pub(crate) spdx: String,
+ pub(crate) copyright: Vec<String>,
+}
+
+impl License {
+ fn simplify(&mut self) {
+ self.remove_copyright_prefixes();
+ self.copyright.sort();
+ self.copyright.dedup();
+ }
+
+ fn remove_copyright_prefixes(&mut self) {
+ for copyright in &mut self.copyright {
+ let mut stripped = copyright.trim();
+ let mut previous_stripped;
+ loop {
+ previous_stripped = stripped;
+ for pattern in COPYRIGHT_PREFIXES {
+ stripped = stripped.trim_start_matches(pattern).trim_start();
+ }
+ if stripped == previous_stripped {
+ break;
+ }
+ }
+ *copyright = stripped.into();
+ }
+ }
+}
diff --git a/src/tools/collect-license-metadata/src/main.rs b/src/tools/collect-license-metadata/src/main.rs
new file mode 100644
index 000000000..ca2a6f4b8
--- /dev/null
+++ b/src/tools/collect-license-metadata/src/main.rs
@@ -0,0 +1,30 @@
+mod licenses;
+mod path_tree;
+mod reuse;
+
+use crate::licenses::LicensesInterner;
+use anyhow::Error;
+use std::path::PathBuf;
+
+fn main() -> Result<(), Error> {
+ let reuse_exe: PathBuf = std::env::var_os("REUSE_EXE").expect("Missing REUSE_EXE").into();
+ let dest: PathBuf = std::env::var_os("DEST").expect("Missing DEST").into();
+
+ let mut interner = LicensesInterner::new();
+ let paths = crate::reuse::collect(&reuse_exe, &mut interner)?;
+
+ let mut tree = crate::path_tree::build(paths);
+ tree.simplify();
+
+ if let Some(parent) = dest.parent() {
+ std::fs::create_dir_all(parent)?;
+ }
+ std::fs::write(
+ &dest,
+ &serde_json::to_vec_pretty(&serde_json::json!({
+ "files": crate::path_tree::expand_interned_licenses(tree, &interner),
+ }))?,
+ )?;
+
+ Ok(())
+}
diff --git a/src/tools/collect-license-metadata/src/path_tree.rs b/src/tools/collect-license-metadata/src/path_tree.rs
new file mode 100644
index 000000000..133ff6837
--- /dev/null
+++ b/src/tools/collect-license-metadata/src/path_tree.rs
@@ -0,0 +1,294 @@
+//! Tools like REUSE output per-file licensing information, but we need to condense it in the
+//! minimum amount of data that still represents the same licensing metadata. This module is
+//! responsible for that, by turning the list of paths into a tree and executing simplification
+//! passes over the tree to remove redundant information.
+
+use crate::licenses::{License, LicenseId, LicensesInterner};
+use std::collections::BTreeMap;
+use std::path::{Path, PathBuf};
+
+#[derive(serde::Serialize)]
+#[serde(rename_all = "kebab-case", tag = "type")]
+pub(crate) enum Node<L> {
+ Root { childs: Vec<Node<L>> },
+ Directory { name: PathBuf, childs: Vec<Node<L>>, license: Option<L> },
+ File { name: PathBuf, license: L },
+ FileGroup { names: Vec<PathBuf>, license: L },
+ Empty,
+}
+
+impl Node<LicenseId> {
+ pub(crate) fn simplify(&mut self) {
+ self.merge_directories();
+ self.collapse_in_licensed_directories();
+ self.merge_directory_licenses();
+ self.merge_file_groups();
+ self.remove_empty();
+ }
+
+ /// Initially, the build() function constructs a list of separate paths from the file
+ /// system root down to each file, like so:
+ ///
+ /// ```text
+ /// ┌─► ./ ──► compiler/ ──► rustc/ ──► src/ ──► main.rs
+ /// │
+ /// <root> ─┼─► ./ ──► compiler/ ──► rustc/ ──► Cargo.toml
+ /// │
+ /// └─► ./ ──► library/ ───► std/ ──► Cargo.toml
+ /// ```
+ ///
+ /// This pass is responsible for turning that into a proper directory tree:
+ ///
+ /// ```text
+ /// ┌─► compiler/ ──► rustc/ ──┬─► src/ ──► main.rs
+ /// │ │
+ /// <root> ──► ./ ──┤ └─► Cargo.toml
+ /// │
+ /// └─► library/ ───► std/ ──► Cargo.toml
+ /// ```
+ fn merge_directories(&mut self) {
+ match self {
+ Node::Root { childs } | Node::Directory { childs, license: None, .. } => {
+ let mut directories = BTreeMap::new();
+ let mut files = Vec::new();
+
+ for child in childs.drain(..) {
+ match child {
+ Node::Directory { name, mut childs, license: None } => {
+ directories.entry(name).or_insert_with(Vec::new).append(&mut childs);
+ }
+ file @ Node::File { .. } => {
+ files.push(file);
+ }
+ Node::Empty => {}
+ Node::Root { .. } => {
+ panic!("can't have a root inside another element");
+ }
+ Node::FileGroup { .. } => {
+ panic!("FileGroup should not be present at this stage");
+ }
+ Node::Directory { license: Some(_), .. } => {
+ panic!("license should not be set at this stage");
+ }
+ }
+ }
+
+ childs.extend(directories.into_iter().map(|(name, childs)| Node::Directory {
+ name,
+ childs,
+ license: None,
+ }));
+ childs.append(&mut files);
+
+ for child in &mut *childs {
+ child.merge_directories();
+ }
+ }
+ Node::Empty => {}
+ Node::File { .. } => {}
+ Node::FileGroup { .. } => {
+ panic!("FileGroup should not be present at this stage");
+ }
+ Node::Directory { license: Some(_), .. } => {
+ panic!("license should not be set at this stage");
+ }
+ }
+ }
+
+ /// In our codebase, most files in a directory have the same license as the other files in that
+ /// same directory, so it's redundant to store licensing metadata for all the files. Instead,
+ /// we can add a license for a whole directory, and only record the exceptions to a directory
+ /// licensing metadata.
+ ///
+ /// We cannot instead record only the difference to Rust's standard licensing, as the majority
+ /// of the files in our repository are *not* licensed under Rust's standard licensing due to
+ /// our inclusion of LLVM.
+ fn collapse_in_licensed_directories(&mut self) {
+ match self {
+ Node::Directory { childs, license, .. } => {
+ for child in &mut *childs {
+ child.collapse_in_licensed_directories();
+ }
+
+ let mut licenses_count = BTreeMap::new();
+ for child in &*childs {
+ let Some(license) = child.license() else { continue };
+ *licenses_count.entry(license).or_insert(0) += 1;
+ }
+
+ let most_popular_license = licenses_count
+ .into_iter()
+ .max_by_key(|(_, count)| *count)
+ .map(|(license, _)| license);
+
+ if let Some(most_popular_license) = most_popular_license {
+ childs.retain(|child| child.license() != Some(most_popular_license));
+ *license = Some(most_popular_license);
+ }
+ }
+ Node::Root { childs } => {
+ for child in &mut *childs {
+ child.collapse_in_licensed_directories();
+ }
+ }
+ Node::File { .. } => {}
+ Node::FileGroup { .. } => {}
+ Node::Empty => {}
+ }
+ }
+
+ /// Reduce the depth of the tree by merging subdirectories with the same license as their
+ /// parent directory into their parent, and adjusting the paths of the childs accordingly.
+ fn merge_directory_licenses(&mut self) {
+ match self {
+ Node::Root { childs } => {
+ for child in &mut *childs {
+ child.merge_directory_licenses();
+ }
+ }
+ Node::Directory { childs, license, .. } => {
+ let mut to_add = Vec::new();
+ for child in &mut *childs {
+ child.merge_directory_licenses();
+
+ let Node::Directory {
+ name: child_name,
+ childs: child_childs,
+ license: child_license,
+ } = child else { continue };
+
+ if child_license != license {
+ continue;
+ }
+ for mut child_child in child_childs.drain(..) {
+ match &mut child_child {
+ Node::Root { .. } => {
+ panic!("can't have a root inside another element");
+ }
+ Node::FileGroup { .. } => {
+ panic!("FileGroup should not be present at this stage");
+ }
+ Node::Directory { name: child_child_name, .. } => {
+ *child_child_name = child_name.join(&child_child_name);
+ }
+ Node::File { name: child_child_name, .. } => {
+ *child_child_name = child_name.join(&child_child_name);
+ }
+ Node::Empty => {}
+ }
+ to_add.push(child_child);
+ }
+
+ *child = Node::Empty;
+ }
+ childs.append(&mut to_add);
+ }
+ Node::Empty => {}
+ Node::File { .. } => {}
+ Node::FileGroup { .. } => {}
+ }
+ }
+
+ /// This pass groups multiple files in a directory with the same license into a single
+ /// "FileGroup", so that the license of all those files can be reported as a group.
+ ///
+ /// Crucially this pass runs after collapse_in_licensed_directories, so the most common license
+ /// will already be marked as the directory's license and won't be turned into a group.
+ fn merge_file_groups(&mut self) {
+ match self {
+ Node::Root { childs } | Node::Directory { childs, .. } => {
+ let mut grouped = BTreeMap::new();
+
+ for child in &mut *childs {
+ child.merge_file_groups();
+ if let Node::File { name, license } = child {
+ grouped.entry(*license).or_insert_with(Vec::new).push(name.clone());
+ *child = Node::Empty;
+ }
+ }
+
+ for (license, mut names) in grouped.into_iter() {
+ if names.len() == 1 {
+ childs.push(Node::File { license, name: names.pop().unwrap() });
+ } else {
+ childs.push(Node::FileGroup { license, names });
+ }
+ }
+ }
+ Node::File { .. } => {}
+ Node::FileGroup { .. } => panic!("FileGroup should not be present at this stage"),
+ Node::Empty => {}
+ }
+ }
+
+ /// Some nodes were replaced with Node::Empty to mark them for deletion. As the last step, make
+ /// sure to remove them from the tree.
+ fn remove_empty(&mut self) {
+ match self {
+ Node::Root { childs } | Node::Directory { childs, .. } => {
+ for child in &mut *childs {
+ child.remove_empty();
+ }
+ childs.retain(|child| !matches!(child, Node::Empty));
+ }
+ Node::FileGroup { .. } => {}
+ Node::File { .. } => {}
+ Node::Empty => {}
+ }
+ }
+
+ fn license(&self) -> Option<LicenseId> {
+ match self {
+ Node::Directory { childs, license: Some(license), .. } if childs.is_empty() => {
+ Some(*license)
+ }
+ Node::File { license, .. } => Some(*license),
+ _ => None,
+ }
+ }
+}
+
+pub(crate) fn build(mut input: Vec<(PathBuf, LicenseId)>) -> Node<LicenseId> {
+ let mut childs = Vec::new();
+
+ // Ensure reproducibility of all future steps.
+ input.sort();
+
+ for (path, license) in input {
+ let mut node = Node::File { name: path.file_name().unwrap().into(), license };
+ for component in path.parent().unwrap_or_else(|| Path::new(".")).components().rev() {
+ node = Node::Directory {
+ name: component.as_os_str().into(),
+ childs: vec![node],
+ license: None,
+ };
+ }
+
+ childs.push(node);
+ }
+
+ Node::Root { childs }
+}
+
+/// Convert a `Node<LicenseId>` into a `Node<&License>`, expanding all interned license IDs with a
+/// reference to the actual license metadata.
+pub(crate) fn expand_interned_licenses(
+ node: Node<LicenseId>,
+ interner: &LicensesInterner,
+) -> Node<&License> {
+ match node {
+ Node::Root { childs } => Node::Root {
+ childs: childs.into_iter().map(|child| strip_interning(child, interner)).collect(),
+ },
+ Node::Directory { name, childs, license } => Node::Directory {
+ childs: childs.into_iter().map(|child| strip_interning(child, interner)).collect(),
+ license: license.map(|license| interner.resolve(license)),
+ name,
+ },
+ Node::File { name, license } => Node::File { name, license: interner.resolve(license) },
+ Node::FileGroup { names, license } => {
+ Node::FileGroup { names, license: interner.resolve(license) }
+ }
+ Node::Empty => Node::Empty,
+ }
+}
diff --git a/src/tools/collect-license-metadata/src/reuse.rs b/src/tools/collect-license-metadata/src/reuse.rs
new file mode 100644
index 000000000..d6b3772ba
--- /dev/null
+++ b/src/tools/collect-license-metadata/src/reuse.rs
@@ -0,0 +1,49 @@
+use crate::licenses::{License, LicenseId, LicensesInterner};
+use anyhow::Error;
+use std::path::{Path, PathBuf};
+use std::process::{Command, Stdio};
+use std::time::Instant;
+
+pub(crate) fn collect(
+ reuse_exe: &Path,
+ interner: &mut LicensesInterner,
+) -> Result<Vec<(PathBuf, LicenseId)>, Error> {
+ eprintln!("gathering license information from REUSE");
+ let start = Instant::now();
+ let raw = &obtain_spdx_document(reuse_exe)?;
+ eprintln!("finished gathering the license information from REUSE in {:.2?}", start.elapsed());
+
+ let document = spdx_rs::parsers::spdx_from_tag_value(&raw)?;
+
+ let mut result = Vec::new();
+ for file in document.file_information {
+ let license = interner.intern(License {
+ spdx: file.concluded_license.to_string(),
+ copyright: file.copyright_text.split('\n').map(|s| s.into()).collect(),
+ });
+
+ result.push((file.file_name.into(), license));
+ }
+
+ Ok(result)
+}
+
+fn obtain_spdx_document(reuse_exe: &Path) -> Result<String, Error> {
+ let output = Command::new(reuse_exe)
+ .args(&["spdx", "--add-license-concluded", "--creator-person=bors"])
+ .stdout(Stdio::piped())
+ .spawn()?
+ .wait_with_output()?;
+
+ if !output.status.success() {
+ eprintln!();
+ eprintln!("Note that Rust requires some REUSE features that might not be present in the");
+ eprintln!("release you're using. Make sure your REUSE release includes these PRs:");
+ eprintln!();
+ eprintln!(" - https://github.com/fsfe/reuse-tool/pull/623");
+ eprintln!();
+ anyhow::bail!("collecting licensing information with REUSE failed");
+ }
+
+ Ok(String::from_utf8(output.stdout)?)
+}
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 41f97e432..1911f0f9c 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -8,6 +8,7 @@ colored = "2"
diff = "0.1.10"
unified-diff = "0.2.1"
getopts = "0.2"
+miropt-test-tools = { path = "../miropt-test-tools" }
tracing = "0.1"
tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
regex = "1.0"
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 0260f6848..07b80b8ba 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -2,11 +2,12 @@ pub use self::Mode::*;
use std::ffi::OsString;
use std::fmt;
+use std::iter;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::str::FromStr;
-use crate::util::PathBufExt;
+use crate::util::{add_dylib_path, PathBufExt};
use lazycell::LazyCell;
use test::ColorConfig;
@@ -229,6 +230,9 @@ pub struct Config {
/// The directory where programs should be built
pub build_base: PathBuf,
+ /// The directory containing the compiler sysroot
+ pub sysroot_base: PathBuf,
+
/// The name of the stage being built (stage1, etc)
pub stage_id: String,
@@ -385,8 +389,7 @@ impl Config {
}
fn target_cfg(&self) -> &TargetCfg {
- self.target_cfg
- .borrow_with(|| TargetCfg::new(&self.rustc_path, &self.target, &self.target_rustcflags))
+ self.target_cfg.borrow_with(|| TargetCfg::new(self))
}
pub fn matches_arch(&self, arch: &str) -> bool {
@@ -457,21 +460,23 @@ pub enum Endian {
}
impl TargetCfg {
- fn new(rustc_path: &Path, target: &str, target_rustcflags: &Vec<String>) -> TargetCfg {
- let output = match Command::new(rustc_path)
+ fn new(config: &Config) -> TargetCfg {
+ let mut command = Command::new(&config.rustc_path);
+ add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
+ let output = match command
.arg("--print=cfg")
.arg("--target")
- .arg(target)
- .args(target_rustcflags)
+ .arg(&config.target)
+ .args(&config.target_rustcflags)
.output()
{
Ok(output) => output,
- Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", rustc_path),
+ Err(e) => panic!("error: failed to get cfg info from {:?}: {e}", config.rustc_path),
};
if !output.status.success() {
panic!(
"error: failed to get cfg info from {:?}\n--- stdout\n{}\n--- stderr\n{}",
- rustc_path,
+ config.rustc_path,
String::from_utf8(output.stdout).unwrap(),
String::from_utf8(output.stderr).unwrap(),
);
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 0d9a629e1..64d97e914 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -260,9 +260,9 @@ impl TestProps {
props.load_from(testfile, cfg, config);
match (props.pass_mode, props.fail_mode) {
- (None, None) => props.fail_mode = Some(FailMode::Check),
- (Some(_), None) | (None, Some(_)) => {}
+ (None, None) if config.mode == Mode::Ui => props.fail_mode = Some(FailMode::Check),
(Some(_), Some(_)) => panic!("cannot use a *-fail and *-pass mode together"),
+ _ => {}
}
props
@@ -522,8 +522,8 @@ impl TestProps {
}
pub fn pass_mode(&self, config: &Config) -> Option<PassMode> {
- if !self.ignore_pass && self.fail_mode.is_none() && config.mode == Mode::Ui {
- if let (mode @ Some(_), Some(_)) = (config.force_pass_mode, self.pass_mode) {
+ if !self.ignore_pass && self.fail_mode.is_none() {
+ if let mode @ Some(_) = config.force_pass_mode {
return mode;
}
}
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index bcd222b5a..e42b8c524 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -46,6 +46,7 @@ fn config() -> Config {
"--jsondocck-path=",
"--src-base=",
"--build-base=",
+ "--sysroot-base=",
"--stage-id=stage2",
"--cc=c",
"--cxx=c++",
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 19cf54780..91c701a5d 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -69,6 +69,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
.optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR")
.reqopt("", "src-base", "directory to scan for test files", "PATH")
.reqopt("", "build-base", "directory to deposit test outputs", "PATH")
+ .reqopt("", "sysroot-base", "directory containing the compiler sysroot", "PATH")
.reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET")
.reqopt(
"",
@@ -234,6 +235,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
llvm_bin_dir: matches.opt_str("llvm-bin-dir").map(PathBuf::from),
src_base,
build_base: opt_path(matches, "build-base"),
+ sysroot_base: opt_path(matches, "sysroot-base"),
stage_id: matches.opt_str("stage-id").unwrap(),
mode,
suite: matches.opt_str("suite").unwrap(),
@@ -512,6 +514,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
options: test::Options::new(),
time_options: None,
force_run_in_process: false,
+ fail_fast: std::env::var_os("RUSTC_TEST_FAIL_FAST").is_some(),
}
}
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 8af5f1da6..1542b1c17 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -13,7 +13,7 @@ use crate::errors::{self, Error, ErrorKind};
use crate::header::TestProps;
use crate::json;
use crate::read2::read2_abbreviated;
-use crate::util::{logv, PathBufExt};
+use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt};
use crate::ColorConfig;
use regex::{Captures, Regex};
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
@@ -26,6 +26,7 @@ use std::fs::{self, create_dir_all, File, OpenOptions};
use std::hash::{Hash, Hasher};
use std::io::prelude::*;
use std::io::{self, BufReader};
+use std::iter;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, ExitStatus, Output, Stdio};
use std::str;
@@ -72,19 +73,6 @@ fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R {
f()
}
-/// The name of the environment variable that holds dynamic library locations.
-pub fn dylib_env_var() -> &'static str {
- if cfg!(windows) {
- "PATH"
- } else if cfg!(target_os = "macos") {
- "DYLD_LIBRARY_PATH"
- } else if cfg!(target_os = "haiku") {
- "LIBRARY_PATH"
- } else {
- "LD_LIBRARY_PATH"
- }
-}
-
/// The platform-specific library name
pub fn get_lib_name(lib: &str, dylib: bool) -> String {
// In some casess (e.g. MUSL), we build a static
@@ -220,11 +208,13 @@ enum WillExecute {
Disabled,
}
-/// Should `--emit metadata` be used?
+/// What value should be passed to `--emit`?
#[derive(Copy, Clone)]
-enum EmitMetadata {
- Yes,
- No,
+enum Emit {
+ None,
+ Metadata,
+ LlvmIr,
+ Asm,
}
impl<'test> TestCx<'test> {
@@ -424,7 +414,7 @@ impl<'test> TestCx<'test> {
}
let should_run = self.run_if_enabled();
- let mut proc_res = self.compile_test(should_run, EmitMetadata::No);
+ let mut proc_res = self.compile_test(should_run, Emit::None);
if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
@@ -670,7 +660,7 @@ impl<'test> TestCx<'test> {
// compile test file (it should have 'compile-flags:-g' in the header)
let should_run = self.run_if_enabled();
- let compile_result = self.compile_test(should_run, EmitMetadata::No);
+ let compile_result = self.compile_test(should_run, Emit::None);
if !compile_result.status.success() {
self.fatal_proc_rec("compilation failed!", &compile_result);
}
@@ -721,7 +711,7 @@ impl<'test> TestCx<'test> {
script_str.push_str("\n");
}
- script_str.push_str("\nqq\n"); // Quit the debugger (including remote debugger, if any)
+ script_str.push_str("qq\n"); // Quit the debugger (including remote debugger, if any)
// Write the script into a file
debug!("script_str = {}", script_str);
@@ -790,7 +780,7 @@ impl<'test> TestCx<'test> {
// compile test file (it should have 'compile-flags:-g' in the header)
let should_run = self.run_if_enabled();
- let compiler_run_result = self.compile_test(should_run, EmitMetadata::No);
+ let compiler_run_result = self.compile_test(should_run, Emit::None);
if !compiler_run_result.status.success() {
self.fatal_proc_rec("compilation failed!", &compiler_run_result);
}
@@ -1022,7 +1012,7 @@ impl<'test> TestCx<'test> {
fn run_debuginfo_lldb_test_no_opt(&self) {
// compile test file (it should have 'compile-flags:-g' in the header)
let should_run = self.run_if_enabled();
- let compile_result = self.compile_test(should_run, EmitMetadata::No);
+ let compile_result = self.compile_test(should_run, Emit::None);
if !compile_result.status.success() {
self.fatal_proc_rec("compilation failed!", &compile_result);
}
@@ -1438,21 +1428,21 @@ impl<'test> TestCx<'test> {
}
}
- fn should_emit_metadata(&self, pm: Option<PassMode>) -> EmitMetadata {
+ fn should_emit_metadata(&self, pm: Option<PassMode>) -> Emit {
match (pm, self.props.fail_mode, self.config.mode) {
- (Some(PassMode::Check), ..) | (_, Some(FailMode::Check), Ui) => EmitMetadata::Yes,
- _ => EmitMetadata::No,
+ (Some(PassMode::Check), ..) | (_, Some(FailMode::Check), Ui) => Emit::Metadata,
+ _ => Emit::None,
}
}
- fn compile_test(&self, will_execute: WillExecute, emit_metadata: EmitMetadata) -> ProcRes {
- self.compile_test_general(will_execute, emit_metadata, self.props.local_pass_mode())
+ fn compile_test(&self, will_execute: WillExecute, emit: Emit) -> ProcRes {
+ self.compile_test_general(will_execute, emit, self.props.local_pass_mode())
}
fn compile_test_general(
&self,
will_execute: WillExecute,
- emit_metadata: EmitMetadata,
+ emit: Emit,
local_pm: Option<PassMode>,
) -> ProcRes {
// Only use `make_exe_name` when the test ends up being executed.
@@ -1484,10 +1474,13 @@ impl<'test> TestCx<'test> {
_ => AllowUnused::No,
};
- let mut rustc =
- self.make_compile_args(&self.testpaths.file, output_file, emit_metadata, allow_unused);
-
- rustc.arg("-L").arg(&self.aux_output_dir_name());
+ let rustc = self.make_compile_args(
+ &self.testpaths.file,
+ output_file,
+ emit,
+ allow_unused,
+ LinkToAux::Yes,
+ );
self.compose_and_run_compiler(rustc, None)
}
@@ -1714,8 +1707,13 @@ impl<'test> TestCx<'test> {
// Create the directory for the stdout/stderr files.
create_dir_all(aux_cx.output_base_dir()).unwrap();
let input_file = &aux_testpaths.file;
- let mut aux_rustc =
- aux_cx.make_compile_args(input_file, aux_output, EmitMetadata::No, AllowUnused::No);
+ let mut aux_rustc = aux_cx.make_compile_args(
+ input_file,
+ aux_output,
+ Emit::None,
+ AllowUnused::No,
+ LinkToAux::No,
+ );
for key in &aux_props.unset_rustc_env {
aux_rustc.env_remove(key);
@@ -1811,16 +1809,7 @@ impl<'test> TestCx<'test> {
// Need to be sure to put both the lib_path and the aux path in the dylib
// search path for the child.
- let mut path =
- env::split_paths(&env::var_os(dylib_env_var()).unwrap_or_default()).collect::<Vec<_>>();
- if let Some(p) = aux_path {
- path.insert(0, PathBuf::from(p))
- }
- path.insert(0, PathBuf::from(lib_path));
-
- // Add the new dylib search path var
- let newpath = env::join_paths(&path).unwrap();
- command.env(dylib_env_var(), newpath);
+ 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));
@@ -1852,8 +1841,9 @@ impl<'test> TestCx<'test> {
&self,
input_file: &Path,
output_file: TargetLocation,
- emit_metadata: EmitMetadata,
+ emit: Emit,
allow_unused: AllowUnused,
+ link_to_aux: LinkToAux,
) -> Command {
let is_aux = input_file.components().map(|c| c.as_os_str()).any(|c| c == "auxiliary");
let is_rustdoc = self.is_rustdoc() && !is_aux;
@@ -1968,8 +1958,18 @@ impl<'test> TestCx<'test> {
}
}
- if let (false, EmitMetadata::Yes) = (is_rustdoc, emit_metadata) {
- rustc.args(&["--emit", "metadata"]);
+ match emit {
+ Emit::None => {}
+ Emit::Metadata if is_rustdoc => {}
+ Emit::Metadata => {
+ rustc.args(&["--emit", "metadata"]);
+ }
+ Emit::LlvmIr => {
+ rustc.args(&["--emit", "llvm-ir"]);
+ }
+ Emit::Asm => {
+ rustc.args(&["--emit", "asm"]);
+ }
}
if !is_rustdoc {
@@ -2035,6 +2035,10 @@ impl<'test> TestCx<'test> {
rustc.arg("-Ctarget-feature=-crt-static");
}
+ if let LinkToAux::Yes = link_to_aux {
+ rustc.arg("-L").arg(self.aux_output_dir_name());
+ }
+
rustc.args(&self.props.compile_flags);
rustc
@@ -2226,13 +2230,15 @@ impl<'test> TestCx<'test> {
// codegen tests (using FileCheck)
fn compile_test_and_save_ir(&self) -> ProcRes {
- let aux_dir = self.aux_output_dir_name();
-
let output_file = TargetLocation::ThisDirectory(self.output_base_dir());
let input_file = &self.testpaths.file;
- let mut rustc =
- self.make_compile_args(input_file, output_file, EmitMetadata::No, AllowUnused::No);
- rustc.arg("-L").arg(aux_dir).arg("--emit=llvm-ir");
+ let rustc = self.make_compile_args(
+ input_file,
+ output_file,
+ Emit::LlvmIr,
+ AllowUnused::No,
+ LinkToAux::Yes,
+ );
self.compose_and_run_compiler(rustc, None)
}
@@ -2244,14 +2250,11 @@ impl<'test> TestCx<'test> {
let output_file = TargetLocation::ThisFile(output_path.clone());
let input_file = &self.testpaths.file;
- let mut rustc =
- self.make_compile_args(input_file, output_file, EmitMetadata::No, AllowUnused::No);
-
- rustc.arg("-L").arg(self.aux_output_dir_name());
+ let mut emit = Emit::None;
match self.props.assembly_output.as_ref().map(AsRef::as_ref) {
Some("emit-asm") => {
- rustc.arg("--emit=asm");
+ emit = Emit::Asm;
}
Some("ptx-linker") => {
@@ -2262,6 +2265,9 @@ impl<'test> TestCx<'test> {
None => self.fatal("missing 'assembly-output' header"),
}
+ let rustc =
+ self.make_compile_args(input_file, output_file, emit, AllowUnused::No, LinkToAux::Yes);
+
(self.compose_and_run_compiler(rustc, None), output_path)
}
@@ -2386,10 +2392,10 @@ impl<'test> TestCx<'test> {
let mut rustc = new_rustdoc.make_compile_args(
&new_rustdoc.testpaths.file,
output_file,
- EmitMetadata::No,
+ Emit::None,
AllowUnused::Yes,
+ LinkToAux::Yes,
);
- rustc.arg("-L").arg(&new_rustdoc.aux_output_dir_name());
new_rustdoc.build_all_auxiliary(&mut rustc);
let proc_res = new_rustdoc.document(&compare_dir);
@@ -2662,7 +2668,7 @@ impl<'test> TestCx<'test> {
fn run_codegen_units_test(&self) {
assert!(self.revision.is_none(), "revisions not relevant here");
- let proc_res = self.compile_test(WillExecute::No, EmitMetadata::No);
+ let proc_res = self.compile_test(WillExecute::No, Emit::None);
if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
@@ -2981,6 +2987,10 @@ impl<'test> TestCx<'test> {
cmd.env("LLVM_BIN_DIR", llvm_bin_dir);
}
+ if let Some(ref remote_test_client) = self.config.remote_test_client {
+ cmd.env("REMOTE_TEST_CLIENT", remote_test_client);
+ }
+
// We don't want RUSTFLAGS set from the outside to interfere with
// compiler flags set in the test cases:
cmd.env_remove("RUSTFLAGS");
@@ -3175,7 +3185,7 @@ impl<'test> TestCx<'test> {
if let Some(FailMode::Build) = self.props.fail_mode {
// Make sure a build-fail test cannot fail due to failing analysis (e.g. typeck).
let pm = Some(PassMode::Check);
- let proc_res = self.compile_test_general(WillExecute::No, EmitMetadata::Yes, pm);
+ let proc_res = self.compile_test_general(WillExecute::No, Emit::Metadata, pm);
self.check_if_test_should_compile(&proc_res, pm);
}
@@ -3333,13 +3343,13 @@ impl<'test> TestCx<'test> {
if self.props.run_rustfix && self.config.compare_mode.is_none() {
// And finally, compile the fixed code and make sure it both
// succeeds and has no diagnostics.
- let mut rustc = self.make_compile_args(
+ let rustc = self.make_compile_args(
&self.testpaths.file.with_extension(UI_FIXED),
TargetLocation::ThisFile(self.make_exe_name()),
emit_metadata,
AllowUnused::No,
+ LinkToAux::Yes,
);
- rustc.arg("-L").arg(&self.aux_output_dir_name());
let res = self.compose_and_run_compiler(rustc, None);
if !res.status.success() {
self.fatal_proc_rec("failed to compile fixed code", &res);
@@ -3399,103 +3409,49 @@ impl<'test> TestCx<'test> {
}
}
- for l in test_file_contents.lines() {
- if l.starts_with("// EMIT_MIR ") {
- let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
- let mut test_names = test_name.split(' ');
- // sometimes we specify two files so that we get a diff between the two files
- let test_name = test_names.next().unwrap();
- let mut expected_file;
- let from_file;
- let to_file;
-
- if test_name.ends_with(".diff") {
- let trimmed = test_name.trim_end_matches(".diff");
- let test_against = format!("{}.after.mir", trimmed);
- from_file = format!("{}.before.mir", trimmed);
- expected_file = format!("{}{}.diff", trimmed, bit_width);
- assert!(
- test_names.next().is_none(),
- "two mir pass names specified for MIR diff"
- );
- to_file = Some(test_against);
- } else if let Some(first_pass) = test_names.next() {
- let second_pass = test_names.next().unwrap();
- assert!(
- test_names.next().is_none(),
- "three mir pass names specified for MIR diff"
- );
- expected_file =
- format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass);
- let second_file = format!("{}.{}.mir", test_name, second_pass);
- from_file = format!("{}.{}.mir", test_name, first_pass);
- to_file = Some(second_file);
- } else {
- let ext_re = Regex::new(r#"(\.(mir|dot|html))$"#).unwrap();
- let cap = ext_re
- .captures_iter(test_name)
- .next()
- .expect("test_name has an invalid extension");
- let extension = cap.get(1).unwrap().as_str();
- expected_file = format!(
- "{}{}{}",
- test_name.trim_end_matches(extension),
- bit_width,
- extension,
- );
- from_file = test_name.to_string();
- assert!(
- test_names.next().is_none(),
- "two mir pass names specified for MIR dump"
+ let files = miropt_test_tools::files_for_miropt_test(
+ &self.testpaths.file,
+ self.config.get_pointer_width(),
+ );
+
+ for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file } in files {
+ let dumped_string = if let Some(after) = to_file {
+ self.diff_mir_files(from_file.into(), after.into())
+ } else {
+ let mut output_file = PathBuf::new();
+ output_file.push(self.get_mir_dump_dir());
+ output_file.push(&from_file);
+ debug!(
+ "comparing the contents of: {} with {}",
+ output_file.display(),
+ expected_file.display()
+ );
+ if !output_file.exists() {
+ panic!(
+ "Output file `{}` from test does not exist, available files are in `{}`",
+ output_file.display(),
+ output_file.parent().unwrap().display()
);
- to_file = None;
- };
- if !expected_file.starts_with(&test_crate) {
- expected_file = format!("{}.{}", test_crate, expected_file);
}
- let expected_file = test_dir.join(expected_file);
+ self.check_mir_test_timestamp(&from_file, &output_file);
+ let dumped_string = fs::read_to_string(&output_file).unwrap();
+ self.normalize_output(&dumped_string, &[])
+ };
- let dumped_string = if let Some(after) = to_file {
- self.diff_mir_files(from_file.into(), after.into())
- } else {
- let mut output_file = PathBuf::new();
- output_file.push(self.get_mir_dump_dir());
- output_file.push(&from_file);
- debug!(
- "comparing the contents of: {} with {}",
- output_file.display(),
+ if self.config.bless {
+ let _ = std::fs::remove_file(&expected_file);
+ std::fs::write(expected_file, dumped_string.as_bytes()).unwrap();
+ } else {
+ if !expected_file.exists() {
+ panic!("Output file `{}` from test does not exist", expected_file.display());
+ }
+ let expected_string = fs::read_to_string(&expected_file).unwrap();
+ if dumped_string != expected_string {
+ print!("{}", write_diff(&expected_string, &dumped_string, 3));
+ panic!(
+ "Actual MIR output differs from expected MIR output {}",
expected_file.display()
);
- if !output_file.exists() {
- panic!(
- "Output file `{}` from test does not exist, available files are in `{}`",
- output_file.display(),
- output_file.parent().unwrap().display()
- );
- }
- self.check_mir_test_timestamp(&from_file, &output_file);
- let dumped_string = fs::read_to_string(&output_file).unwrap();
- self.normalize_output(&dumped_string, &[])
- };
-
- if self.config.bless {
- let _ = std::fs::remove_file(&expected_file);
- std::fs::write(expected_file, dumped_string.as_bytes()).unwrap();
- } else {
- if !expected_file.exists() {
- panic!(
- "Output file `{}` from test does not exist",
- expected_file.display()
- );
- }
- let expected_string = fs::read_to_string(&expected_file).unwrap();
- if dumped_string != expected_string {
- print!("{}", write_diff(&expected_string, &dumped_string, 3));
- panic!(
- "Actual MIR output differs from expected MIR output {}",
- expected_file.display()
- );
- }
}
}
}
@@ -3577,22 +3533,27 @@ impl<'test> TestCx<'test> {
let parent_dir = self.testpaths.file.parent().unwrap();
normalize_path(parent_dir, "$DIR");
- // Paths into the libstd/libcore
- let base_dir = self.config.src_base.parent().unwrap().parent().unwrap().parent().unwrap();
- let src_dir = base_dir.join("library");
- normalize_path(&src_dir, "$SRC_DIR");
-
- // `ui-fulldeps` tests can show paths to the compiler source when testing macros from
- // `rustc_macros`
- // eg. /home/user/rust/compiler
- let compiler_src_dir = base_dir.join("compiler");
- normalize_path(&compiler_src_dir, "$COMPILER_DIR");
-
- if let Some(virtual_rust_source_base_dir) =
- option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from)
- {
- normalize_path(&virtual_rust_source_base_dir.join("library"), "$SRC_DIR");
- normalize_path(&virtual_rust_source_base_dir.join("compiler"), "$COMPILER_DIR");
+ let source_bases = &[
+ // Source base on the current filesystem (calculated as parent of `src/test/$suite`):
+ Some(self.config.src_base.parent().unwrap().parent().unwrap().parent().unwrap().into()),
+ // Source base on the sysroot (from the src components downloaded by `download-rustc`):
+ Some(self.config.sysroot_base.join("lib").join("rustlib").join("src").join("rust")),
+ // Virtual `/rustc/$sha` remapped paths (if `remap-debuginfo` is enabled):
+ option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from),
+ // Virtual `/rustc/$sha` coming from download-rustc:
+ std::env::var_os("FAKE_DOWNLOAD_RUSTC_PREFIX").map(PathBuf::from),
+ // Tests using -Zsimulate-remapped-rust-src-base should use this fake path
+ Some("/rustc/FAKE_PREFIX".into()),
+ ];
+ for base_dir in source_bases {
+ if let Some(base_dir) = base_dir {
+ // Paths into the libstd/libcore
+ normalize_path(&base_dir.join("library"), "$SRC_DIR");
+ // `ui-fulldeps` tests can show paths to the compiler source when testing macros from
+ // `rustc_macros`
+ // eg. /home/user/rust/compiler
+ normalize_path(&base_dir.join("compiler"), "$COMPILER_DIR");
+ }
}
// Paths into the build directory
@@ -3927,3 +3888,8 @@ enum AllowUnused {
Yes,
No,
}
+
+enum LinkToAux {
+ Yes,
+ No,
+}
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index e5ff0906b..ec36f1e4f 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -2,6 +2,7 @@ use crate::common::Config;
use std::env;
use std::ffi::OsStr;
use std::path::PathBuf;
+use std::process::Command;
use tracing::*;
@@ -111,3 +112,25 @@ impl PathBufExt for PathBuf {
}
}
}
+
+/// The name of the environment variable that holds dynamic library locations.
+pub fn dylib_env_var() -> &'static str {
+ if cfg!(windows) {
+ "PATH"
+ } else if cfg!(target_os = "macos") {
+ "DYLD_LIBRARY_PATH"
+ } else if cfg!(target_os = "haiku") {
+ "LIBRARY_PATH"
+ } else {
+ "LD_LIBRARY_PATH"
+ }
+}
+
+/// Adds a list of lookup paths to `cmd`'s dynamic library lookup path.
+/// If the dylib_path_var is already set for this cmd, the old value will be overwritten!
+pub fn add_dylib_path(cmd: &mut Command, paths: impl Iterator<Item = impl Into<PathBuf>>) {
+ let path_env = env::var_os(dylib_env_var());
+ let old_paths = path_env.as_ref().map(env::split_paths);
+ let new_paths = paths.map(Into::into).chain(old_paths.into_iter().flatten());
+ cmd.env(dylib_env_var(), env::join_paths(new_paths).unwrap());
+}
diff --git a/src/tools/generate-copyright/Cargo.toml b/src/tools/generate-copyright/Cargo.toml
new file mode 100644
index 000000000..899ef0f8a
--- /dev/null
+++ b/src/tools/generate-copyright/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "generate-copyright"
+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.65"
+serde = { version = "1.0.147", features = ["derive"] }
+serde_json = "1.0.85"
diff --git a/src/tools/generate-copyright/src/main.rs b/src/tools/generate-copyright/src/main.rs
new file mode 100644
index 000000000..d172c9e15
--- /dev/null
+++ b/src/tools/generate-copyright/src/main.rs
@@ -0,0 +1,94 @@
+use anyhow::Error;
+use std::io::Write;
+use std::path::PathBuf;
+
+fn main() -> Result<(), Error> {
+ let dest = env_path("DEST")?;
+ let license_metadata = env_path("LICENSE_METADATA")?;
+
+ let metadata: Metadata = serde_json::from_slice(&std::fs::read(&license_metadata)?)?;
+
+ let mut buffer = Vec::new();
+ render_recursive(&metadata.files, &mut buffer, 0)?;
+
+ std::fs::write(&dest, &buffer)?;
+
+ Ok(())
+}
+
+fn render_recursive(node: &Node, buffer: &mut Vec<u8>, depth: usize) -> Result<(), Error> {
+ let prefix = std::iter::repeat("> ").take(depth + 1).collect::<String>();
+
+ match node {
+ Node::Root { childs } => {
+ for child in childs {
+ render_recursive(child, buffer, depth)?;
+ }
+ }
+ Node::Directory { name, childs, license } => {
+ render_license(&prefix, std::iter::once(name), license, buffer)?;
+ if !childs.is_empty() {
+ writeln!(buffer, "{prefix}")?;
+ writeln!(buffer, "{prefix}*Exceptions:*")?;
+ for child in childs {
+ writeln!(buffer, "{prefix}")?;
+ render_recursive(child, buffer, depth + 1)?;
+ }
+ }
+ }
+ Node::FileGroup { names, license } => {
+ render_license(&prefix, names.iter(), license, buffer)?;
+ }
+ Node::File { name, license } => {
+ render_license(&prefix, std::iter::once(name), license, buffer)?;
+ }
+ }
+
+ Ok(())
+}
+
+fn render_license<'a>(
+ prefix: &str,
+ names: impl Iterator<Item = &'a String>,
+ license: &License,
+ buffer: &mut Vec<u8>,
+) -> Result<(), Error> {
+ for name in names {
+ writeln!(buffer, "{prefix}**`{name}`** ")?;
+ }
+ writeln!(buffer, "{prefix}License: `{}` ", license.spdx)?;
+ for (i, copyright) in license.copyright.iter().enumerate() {
+ let suffix = if i == license.copyright.len() - 1 { "" } else { " " };
+ writeln!(buffer, "{prefix}Copyright: {copyright}{suffix}")?;
+ }
+
+ Ok(())
+}
+
+#[derive(serde::Deserialize)]
+struct Metadata {
+ files: Node,
+}
+
+#[derive(serde::Deserialize)]
+#[serde(rename_all = "kebab-case", tag = "type")]
+pub(crate) enum Node {
+ Root { childs: Vec<Node> },
+ Directory { name: String, childs: Vec<Node>, license: License },
+ File { name: String, license: License },
+ FileGroup { names: Vec<String>, license: License },
+}
+
+#[derive(serde::Deserialize)]
+struct License {
+ spdx: String,
+ copyright: Vec<String>,
+}
+
+fn env_path(var: &str) -> Result<PathBuf, Error> {
+ if let Some(var) = std::env::var_os(var) {
+ Ok(var.into())
+ } else {
+ anyhow::bail!("missing environment variable {var}")
+ }
+}
diff --git a/src/tools/jsondoclint/src/item_kind.rs b/src/tools/jsondoclint/src/item_kind.rs
index 6d986e575..b395c6e7d 100644
--- a/src/tools/jsondoclint/src/item_kind.rs
+++ b/src/tools/jsondoclint/src/item_kind.rs
@@ -1,7 +1,7 @@
use rustdoc_json_types::{Item, ItemEnum, ItemKind, ItemSummary};
/// A univeral way to represent an [`ItemEnum`] or [`ItemKind`]
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
pub(crate) enum Kind {
Module,
ExternCrate,
@@ -17,7 +17,6 @@ pub(crate) enum Kind {
Constant,
Trait,
TraitAlias,
- Method,
Impl,
Static,
ForeignType,
@@ -63,18 +62,33 @@ impl Kind {
// Only in traits
AssocConst => false,
AssocType => false,
- Method => false,
StructField => false, // Only in structs or variants
Variant => false, // Only in enums
}
}
+ pub fn can_appear_in_import(self) -> bool {
+ match self {
+ Kind::Variant => true,
+ Kind::Import => false,
+ other => other.can_appear_in_mod(),
+ }
+ }
+
+ pub fn can_appear_in_glob_import(self) -> bool {
+ match self {
+ Kind::Module => true,
+ Kind::Enum => true,
+ _ => false,
+ }
+ }
+
pub fn can_appear_in_trait(self) -> bool {
match self {
Kind::AssocConst => true,
Kind::AssocType => true,
- Kind::Method => true,
+ Kind::Function => true,
Kind::Module => false,
Kind::ExternCrate => false,
@@ -84,7 +98,6 @@ impl Kind {
Kind::Union => false,
Kind::Enum => false,
Kind::Variant => false,
- Kind::Function => false,
Kind::Typedef => false,
Kind::OpaqueTy => false,
Kind::Constant => false,
@@ -114,11 +127,11 @@ impl Kind {
pub fn is_variant(self) -> bool {
matches!(self, Kind::Variant)
}
- pub fn is_trait(self) -> bool {
- matches!(self, Kind::Trait)
+ pub fn is_trait_or_alias(self) -> bool {
+ matches!(self, Kind::Trait | Kind::TraitAlias)
}
- pub fn is_struct_enum_union(self) -> bool {
- matches!(self, Kind::Struct | Kind::Enum | Kind::Union)
+ pub fn is_type(self) -> bool {
+ matches!(self, Kind::Struct | Kind::Enum | Kind::Union | Kind::Typedef)
}
pub fn from_item(i: &Item) -> Self {
@@ -134,7 +147,6 @@ impl Kind {
ItemEnum::Function(_) => Function,
ItemEnum::Trait(_) => Trait,
ItemEnum::TraitAlias(_) => TraitAlias,
- ItemEnum::Method(_) => Method,
ItemEnum::Impl(_) => Impl,
ItemEnum::Typedef(_) => Typedef,
ItemEnum::OpaqueTy(_) => OpaqueTy,
@@ -164,7 +176,6 @@ impl Kind {
ItemKind::Import => Import,
ItemKind::Keyword => Keyword,
ItemKind::Macro => Macro,
- ItemKind::Method => Method,
ItemKind::Module => Module,
ItemKind::OpaqueTy => OpaqueTy,
ItemKind::Primitive => Primitive,
diff --git a/src/tools/jsondoclint/src/json_find.rs b/src/tools/jsondoclint/src/json_find.rs
index 95ea88666..70e7440f7 100644
--- a/src/tools/jsondoclint/src/json_find.rs
+++ b/src/tools/jsondoclint/src/json_find.rs
@@ -2,7 +2,7 @@ use std::fmt::Write;
use serde_json::Value;
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SelectorPart {
Field(String),
Index(usize),
@@ -72,3 +72,6 @@ fn find_selector_recursive(
}
}
}
+
+#[cfg(test)]
+mod tests;
diff --git a/src/tools/jsondoclint/src/json_find/tests.rs b/src/tools/jsondoclint/src/json_find/tests.rs
new file mode 100644
index 000000000..2a5335307
--- /dev/null
+++ b/src/tools/jsondoclint/src/json_find/tests.rs
@@ -0,0 +1,27 @@
+use super::*;
+
+#[test]
+fn basic_find() {
+ use SelectorPart::*;
+
+ let j = serde_json::json!({
+ "index": {
+ "4": {
+ "inner": {
+ "items": ["1", "2", "3"]
+ }
+ }
+ }
+ });
+
+ let sel = find_selector(&j, &serde_json::json!("1"));
+ let exp: Vec<Vec<SelectorPart>> = vec![vec![
+ Field("index".to_owned()),
+ Field("4".to_owned()),
+ Field("inner".to_owned()),
+ Field("items".to_owned()),
+ Index(0),
+ ]];
+
+ assert_eq!(exp, sel);
+}
diff --git a/src/tools/jsondoclint/src/main.rs b/src/tools/jsondoclint/src/main.rs
index 70d7a82a5..fc54c421b 100644
--- a/src/tools/jsondoclint/src/main.rs
+++ b/src/tools/jsondoclint/src/main.rs
@@ -9,13 +9,13 @@ pub(crate) mod item_kind;
mod json_find;
mod validator;
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq)]
struct Error {
kind: ErrorKind,
id: Id,
}
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq)]
enum ErrorKind {
NotFound,
Custom(String),
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index 94af4c5e9..e15f5fe3c 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -3,9 +3,9 @@ use std::hash::Hash;
use rustdoc_json_types::{
Constant, Crate, DynTrait, Enum, FnDecl, Function, FunctionPointer, GenericArg, GenericArgs,
- GenericBound, GenericParamDef, Generics, Id, Impl, Import, ItemEnum, Method, Module, OpaqueTy,
- Path, Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, Type,
- TypeBinding, TypeBindingKind, Typedef, Union, Variant, WherePredicate,
+ GenericBound, GenericParamDef, Generics, Id, Impl, Import, ItemEnum, Module, OpaqueTy, Path,
+ Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, Type, TypeBinding,
+ TypeBindingKind, Typedef, Union, Variant, WherePredicate,
};
use crate::{item_kind::Kind, Error, ErrorKind};
@@ -32,7 +32,10 @@ pub struct Validator<'a> {
enum PathKind {
Trait,
- StructEnumUnion,
+ /// Structs, Enums, Unions and Typedefs.
+ ///
+ /// This doesn't include trait's because traits are not types.
+ Type,
}
impl<'a> Validator<'a> {
@@ -57,6 +60,8 @@ impl<'a> Validator<'a> {
fn check_item(&mut self, id: &'a Id) {
if let Some(item) = &self.krate.index.get(id) {
+ item.links.values().for_each(|id| self.add_any_id(id));
+
match &item.inner {
ItemEnum::Import(x) => self.check_import(x),
ItemEnum::Union(x) => self.check_union(x),
@@ -67,7 +72,6 @@ impl<'a> Validator<'a> {
ItemEnum::Function(x) => self.check_function(x),
ItemEnum::Trait(x) => self.check_trait(x),
ItemEnum::TraitAlias(x) => self.check_trait_alias(x),
- ItemEnum::Method(x) => self.check_method(x),
ItemEnum::Impl(x) => self.check_impl(x),
ItemEnum::Typedef(x) => self.check_typedef(x),
ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
@@ -101,9 +105,9 @@ impl<'a> Validator<'a> {
fn check_import(&mut self, x: &'a Import) {
if x.glob {
- self.add_mod_id(x.id.as_ref().unwrap());
+ self.add_glob_import_item_id(x.id.as_ref().unwrap());
} else if let Some(id) = &x.id {
- self.add_mod_item_id(id);
+ self.add_import_item_id(id);
}
}
@@ -176,11 +180,6 @@ impl<'a> Validator<'a> {
x.params.iter().for_each(|i| self.check_generic_bound(i));
}
- fn check_method(&mut self, x: &'a Method) {
- self.check_fn_decl(&x.decl);
- self.check_generics(&x.generics);
- }
-
fn check_impl(&mut self, x: &'a Impl) {
self.check_generics(&x.generics);
if let Some(path) = &x.trait_ {
@@ -230,7 +229,7 @@ impl<'a> Validator<'a> {
fn check_type(&mut self, x: &'a Type) {
match x {
- Type::ResolvedPath(path) => self.check_path(path, PathKind::StructEnumUnion),
+ Type::ResolvedPath(path) => self.check_path(path, PathKind::Type),
Type::DynTrait(dyn_trait) => self.check_dyn_trait(dyn_trait),
Type::Generic(_) => {}
Type::Primitive(_) => {}
@@ -269,8 +268,8 @@ impl<'a> Validator<'a> {
fn check_path(&mut self, x: &'a Path, kind: PathKind) {
match kind {
- PathKind::Trait => self.add_trait_id(&x.id),
- PathKind::StructEnumUnion => self.add_struct_enum_union_id(&x.id),
+ PathKind::Trait => self.add_trait_or_alias_id(&x.id),
+ PathKind::Type => self.add_type_id(&x.id),
}
if let Some(args) = &x.args {
self.check_generic_args(&**args);
@@ -379,6 +378,10 @@ impl<'a> Validator<'a> {
}
}
+ fn add_any_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, |_| true, "any kind of item");
+ }
+
fn add_field_id(&mut self, id: &'a Id) {
self.add_id_checked(id, Kind::is_struct_field, "StructField");
}
@@ -394,12 +397,12 @@ impl<'a> Validator<'a> {
self.add_id_checked(id, Kind::is_variant, "Variant");
}
- fn add_trait_id(&mut self, id: &'a Id) {
- self.add_id_checked(id, Kind::is_trait, "Trait");
+ fn add_trait_or_alias_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::is_trait_or_alias, "Trait (or TraitAlias)");
}
- fn add_struct_enum_union_id(&mut self, id: &'a Id) {
- self.add_id_checked(id, Kind::is_struct_enum_union, "Struct or Enum or Union");
+ fn add_type_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::is_type, "Type (Struct, Enum, Union or Typedef)");
}
/// Add an Id that appeared in a trait
@@ -407,6 +410,15 @@ impl<'a> Validator<'a> {
self.add_id_checked(id, Kind::can_appear_in_trait, "Trait inner item");
}
+ /// Add an Id that can be `use`d
+ fn add_import_item_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::can_appear_in_import, "Import inner item");
+ }
+
+ fn add_glob_import_item_id(&mut self, id: &'a Id) {
+ self.add_id_checked(id, Kind::can_appear_in_glob_import, "Glob import inner item");
+ }
+
/// Add an Id that appeared in a mod
fn add_mod_item_id(&mut self, id: &'a Id) {
self.add_id_checked(id, Kind::can_appear_in_mod, "Module inner item")
@@ -440,3 +452,6 @@ fn set_remove<T: Hash + Eq + Clone>(set: &mut HashSet<T>) -> Option<T> {
None
}
}
+
+#[cfg(test)]
+mod tests;
diff --git a/src/tools/jsondoclint/src/validator/tests.rs b/src/tools/jsondoclint/src/validator/tests.rs
new file mode 100644
index 000000000..c4aeee9c5
--- /dev/null
+++ b/src/tools/jsondoclint/src/validator/tests.rs
@@ -0,0 +1,50 @@
+use std::collections::HashMap;
+
+use rustdoc_json_types::{Crate, Item, Visibility};
+
+use super::*;
+
+#[track_caller]
+fn check(krate: &Crate, errs: &[Error]) {
+ let mut validator = Validator::new(krate);
+ validator.check_crate();
+
+ assert_eq!(errs, &validator.errs[..]);
+}
+
+fn id(s: &str) -> Id {
+ Id(s.to_owned())
+}
+
+#[test]
+fn errors_on_missing_links() {
+ let k = Crate {
+ root: id("0"),
+ crate_version: None,
+ includes_private: false,
+ index: HashMap::from_iter([(
+ id("0"),
+ Item {
+ name: Some("root".to_owned()),
+ id: id(""),
+ crate_id: 0,
+ span: None,
+ visibility: Visibility::Public,
+ docs: None,
+ links: HashMap::from_iter([("Not Found".to_owned(), id("1"))]),
+ attrs: vec![],
+ deprecation: None,
+ inner: ItemEnum::Module(Module {
+ is_crate: true,
+ items: vec![],
+ is_stripped: false,
+ }),
+ },
+ )]),
+ paths: HashMap::new(),
+ external_crates: HashMap::new(),
+ format_version: rustdoc_json_types::FORMAT_VERSION,
+ };
+
+ check(&k, &[Error { kind: ErrorKind::NotFound, id: id("1") }]);
+}
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index 7842611bd..4170c32f1 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -55,30 +55,6 @@ const LINKCHECK_EXCEPTIONS: &[(&str, &[&str])] = &[
#[rustfmt::skip]
const INTRA_DOC_LINK_EXCEPTIONS: &[(&str, &[&str])] = &[
- // This will never have links that are not in other pages.
- // To avoid repeating the exceptions twice, an empty list means all broken links are allowed.
- ("reference/print.html", &[]),
- // All the reference 'links' are actually ENBF highlighted as code
- ("reference/comments.html", &[
- "/</code> <code>!",
- "*</code> <code>!",
- ]),
- ("reference/identifiers.html", &[
- "a</code>-<code>z</code> <code>A</code>-<code>Z",
- "a</code>-<code>z</code> <code>A</code>-<code>Z</code> <code>0</code>-<code>9</code> <code>_",
- "a</code>-<code>z</code> <code>A</code>-<code>Z</code>] [<code>a</code>-<code>z</code> <code>A</code>-<code>Z</code> <code>0</code>-<code>9</code> <code>_",
- ]),
- ("reference/tokens.html", &[
- "0</code>-<code>1",
- "0</code>-<code>7",
- "0</code>-<code>9",
- "0</code>-<code>9",
- "0</code>-<code>9</code> <code>a</code>-<code>f</code> <code>A</code>-<code>F",
- ]),
- ("reference/notation.html", &[
- "b</code> <code>B",
- "a</code>-<code>z",
- ]),
// This is being used in the sense of 'inclusive range', not a markdown link
("core/ops/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
("std/ops/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
@@ -365,6 +341,33 @@ impl Checker {
}
});
+ self.check_intra_doc_links(file, &pretty_path, &source, report);
+
+ // we don't need the source anymore,
+ // so drop to reduce memory-usage
+ match self.cache.get_mut(&pretty_path).unwrap() {
+ FileEntry::HtmlFile { source, .. } => *source = Rc::new(String::new()),
+ _ => unreachable!("must be html file"),
+ }
+ }
+
+ fn check_intra_doc_links(
+ &mut self,
+ file: &Path,
+ pretty_path: &str,
+ source: &str,
+ report: &mut Report,
+ ) {
+ let relative = file.strip_prefix(&self.root).expect("should always be relative to root");
+ // Don't check the reference. It has several legitimate things that
+ // look like [<code>…</code>]. The reference has its own broken link
+ // checker in its CI which handles this using pulldown_cmark.
+ //
+ // This checks both the end of the root (when checking just the
+ // reference directory) or the beginning (when checking all docs).
+ if self.root.ends_with("reference") || relative.starts_with("reference") {
+ return;
+ }
// Search for intra-doc links that rustdoc didn't warn about
// FIXME(#77199, 77200) Rustdoc should just warn about these directly.
// NOTE: only looks at one line at a time; in practice this should find most links
@@ -379,12 +382,6 @@ impl Checker {
}
}
}
- // we don't need the source anymore,
- // so drop to reduce memory-usage
- match self.cache.get_mut(&pretty_path).unwrap() {
- FileEntry::HtmlFile { source, .. } => *source = Rc::new(String::new()),
- _ => unreachable!("must be html file"),
- }
}
/// Load a file from disk, or from the cache if available.
diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs
index 857feb773..3842a649c 100644
--- a/src/tools/lint-docs/src/lib.rs
+++ b/src/tools/lint-docs/src/lib.rs
@@ -37,10 +37,8 @@ impl Lint {
}
fn is_ignored(&self) -> bool {
- self.doc
- .iter()
- .filter(|line| line.starts_with("```rust"))
- .all(|line| line.contains(",ignore"))
+ let blocks: Vec<_> = self.doc.iter().filter(|line| line.starts_with("```rust")).collect();
+ !blocks.is_empty() && blocks.iter().all(|line| line.contains(",ignore"))
}
/// Checks the doc style of the lint.
diff --git a/src/tools/miropt-test-tools/Cargo.toml b/src/tools/miropt-test-tools/Cargo.toml
new file mode 100644
index 000000000..8589a44cf
--- /dev/null
+++ b/src/tools/miropt-test-tools/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "miropt-test-tools"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+regex = "1.0"
diff --git a/src/tools/miropt-test-tools/src/lib.rs b/src/tools/miropt-test-tools/src/lib.rs
new file mode 100644
index 000000000..cfba7d583
--- /dev/null
+++ b/src/tools/miropt-test-tools/src/lib.rs
@@ -0,0 +1,70 @@
+use std::fs;
+
+pub struct MiroptTestFiles {
+ pub expected_file: std::path::PathBuf,
+ pub from_file: String,
+ pub to_file: Option<String>,
+}
+
+pub fn files_for_miropt_test(testfile: &std::path::Path, bit_width: u32) -> Vec<MiroptTestFiles> {
+ let mut out = Vec::new();
+ let test_file_contents = fs::read_to_string(&testfile).unwrap();
+
+ let test_dir = testfile.parent().unwrap();
+ let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace('-', "_");
+
+ let bit_width = if test_file_contents.lines().any(|l| l == "// EMIT_MIR_FOR_EACH_BIT_WIDTH") {
+ format!(".{}bit", bit_width)
+ } else {
+ String::new()
+ };
+
+ for l in test_file_contents.lines() {
+ if l.starts_with("// EMIT_MIR ") {
+ let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
+ let mut test_names = test_name.split(' ');
+ // sometimes we specify two files so that we get a diff between the two files
+ let test_name = test_names.next().unwrap();
+ let mut expected_file;
+ let from_file;
+ let to_file;
+
+ if test_name.ends_with(".diff") {
+ let trimmed = test_name.trim_end_matches(".diff");
+ let test_against = format!("{}.after.mir", trimmed);
+ from_file = format!("{}.before.mir", trimmed);
+ expected_file = format!("{}{}.diff", trimmed, bit_width);
+ assert!(test_names.next().is_none(), "two mir pass names specified for MIR diff");
+ to_file = Some(test_against);
+ } else if let Some(first_pass) = test_names.next() {
+ let second_pass = test_names.next().unwrap();
+ assert!(test_names.next().is_none(), "three mir pass names specified for MIR diff");
+ expected_file =
+ format!("{}{}.{}-{}.diff", test_name, bit_width, first_pass, second_pass);
+ let second_file = format!("{}.{}.mir", test_name, second_pass);
+ from_file = format!("{}.{}.mir", test_name, first_pass);
+ to_file = Some(second_file);
+ } else {
+ let ext_re = regex::Regex::new(r#"(\.(mir|dot|html))$"#).unwrap();
+ let cap = ext_re
+ .captures_iter(test_name)
+ .next()
+ .expect("test_name has an invalid extension");
+ let extension = cap.get(1).unwrap().as_str();
+ expected_file =
+ format!("{}{}{}", test_name.trim_end_matches(extension), bit_width, extension,);
+ from_file = test_name.to_string();
+ assert!(test_names.next().is_none(), "two mir pass names specified for MIR dump");
+ to_file = None;
+ };
+ if !expected_file.starts_with(&test_crate) {
+ expected_file = format!("{}.{}", test_crate, expected_file);
+ }
+ let expected_file = test_dir.join(expected_file);
+
+ out.push(MiroptTestFiles { expected_file, from_file, to_file });
+ }
+ }
+
+ out
+}
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 0ddea2f72..41c5d3667 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -222,6 +222,16 @@ dependencies = [
]
[[package]]
+name = "command-group"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7a8a86f409b4a59df3a3e4bee2de0b83f1755fdd2a25e3a9684c396fc4bed2c"
+dependencies = [
+ "nix",
+ "winapi",
+]
+
+[[package]]
name = "countme"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -300,7 +310,7 @@ dependencies = [
"hashbrown",
"lock_api",
"once_cell",
- "parking_lot_core 0.9.3",
+ "parking_lot_core 0.9.4",
]
[[package]]
@@ -359,14 +369,14 @@ dependencies = [
[[package]]
name = "filetime"
-version = "0.2.17"
+version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c"
+checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
- "windows-sys 0.36.1",
+ "windows-sys 0.42.0",
]
[[package]]
@@ -390,6 +400,7 @@ name = "flycheck"
version = "0.0.0"
dependencies = [
"cargo_metadata",
+ "command-group",
"crossbeam-channel",
"jod-thread",
"paths",
@@ -872,9 +883,9 @@ dependencies = [
[[package]]
name = "lsp-types"
-version = "0.93.1"
+version = "0.93.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3bcfee315dde785ba887edb540b08765fd7df75a7d948844be6bf5712246734"
+checksum = "9be6e9c7e2d18f651974370d7aff703f9513e0df6e464fd795660edc77e6ca51"
dependencies = [
"bitflags",
"serde",
@@ -963,11 +974,24 @@ dependencies = [
[[package]]
name = "miow"
-version = "0.4.0"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7377f7792b3afb6a3cba68daa54ca23c032137010460d667fda53a8d66be00e"
+checksum = "52ffbca2f655e33c08be35d87278e5b18b89550a37dbd598c20db92f6a471123"
dependencies = [
- "windows-sys 0.28.0",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "nix"
+version = "0.22.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf"
+dependencies = [
+ "bitflags",
+ "cc",
+ "cfg-if",
+ "libc",
+ "memoffset",
]
[[package]]
@@ -1037,7 +1061,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
- "parking_lot_core 0.9.3",
+ "parking_lot_core 0.9.4",
]
[[package]]
@@ -1056,15 +1080,15 @@ dependencies = [
[[package]]
name = "parking_lot_core"
-version = "0.9.3"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
+checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
- "windows-sys 0.36.1",
+ "windows-sys 0.42.0",
]
[[package]]
@@ -1981,19 +2005,6 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
-version = "0.28.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6"
-dependencies = [
- "windows_aarch64_msvc 0.28.0",
- "windows_i686_gnu 0.28.0",
- "windows_i686_msvc 0.28.0",
- "windows_x86_64_gnu 0.28.0",
- "windows_x86_64_msvc 0.28.0",
-]
-
-[[package]]
-name = "windows-sys"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
@@ -2006,10 +2017,25 @@ dependencies = [
]
[[package]]
-name = "windows_aarch64_msvc"
-version = "0.28.0"
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc 0.42.0",
+ "windows_i686_gnu 0.42.0",
+ "windows_i686_msvc 0.42.0",
+ "windows_x86_64_gnu 0.42.0",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc 0.42.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2"
+checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
[[package]]
name = "windows_aarch64_msvc"
@@ -2018,10 +2044,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
-name = "windows_i686_gnu"
-version = "0.28.0"
+name = "windows_aarch64_msvc"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a"
+checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
[[package]]
name = "windows_i686_gnu"
@@ -2030,10 +2056,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
-name = "windows_i686_msvc"
-version = "0.28.0"
+name = "windows_i686_gnu"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64"
+checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
[[package]]
name = "windows_i686_msvc"
@@ -2042,10 +2068,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
-name = "windows_x86_64_gnu"
-version = "0.28.0"
+name = "windows_i686_msvc"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954"
+checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
[[package]]
name = "windows_x86_64_gnu"
@@ -2054,10 +2080,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
-name = "windows_x86_64_msvc"
-version = "0.28.0"
+name = "windows_x86_64_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f"
+checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
[[package]]
name = "windows_x86_64_msvc"
@@ -2066,6 +2098,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+
+[[package]]
name = "write-json"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml
index f02a51ab6..a484ecec6 100644
--- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/cfg/Cargo.toml b/src/tools/rust-analyzer/crates/cfg/Cargo.toml
index ee1ad677a..2857420c2 100644
--- a/src/tools/rust-analyzer/crates/cfg/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/cfg/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/flycheck/Cargo.toml b/src/tools/rust-analyzer/crates/flycheck/Cargo.toml
index 2ad32d248..514d567fc 100644
--- a/src/tools/rust-analyzer/crates/flycheck/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/flycheck/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
@@ -17,6 +17,7 @@ rustc-hash = "1.1.0"
serde = { version = "1.0.137", features = ["derive"] }
serde_json = "1.0.86"
jod-thread = "0.1.2"
+command-group = "1.0.8"
toolchain = { path = "../toolchain", version = "0.0.0" }
stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
index 73c3a48b4..8f93dad06 100644
--- a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
@@ -10,11 +10,12 @@ use std::{
time::Duration,
};
+use command_group::{CommandGroup, GroupChild};
use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
use paths::AbsPathBuf;
use rustc_hash::FxHashMap;
use serde::Deserialize;
-use stdx::{process::streaming_output, JodChild};
+use stdx::process::streaming_output;
pub use cargo_metadata::diagnostic::{
Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan,
@@ -39,7 +40,7 @@ pub enum InvocationLocation {
pub enum FlycheckConfig {
CargoCommand {
command: String,
- target_triple: Option<String>,
+ target_triples: Vec<String>,
all_targets: bool,
no_default_features: bool,
all_features: bool,
@@ -285,7 +286,7 @@ impl FlycheckActor {
let (mut cmd, args) = match &self.config {
FlycheckConfig::CargoCommand {
command,
- target_triple,
+ target_triples,
no_default_features,
all_targets,
all_features,
@@ -295,9 +296,11 @@ impl FlycheckActor {
} => {
let mut cmd = Command::new(toolchain::cargo());
cmd.arg(command);
- cmd.args(&["--workspace", "--message-format=json"]);
+ cmd.current_dir(&self.root);
+ cmd.args(&["--workspace", "--message-format=json", "--manifest-path"])
+ .arg(self.root.join("Cargo.toml").as_os_str());
- if let Some(target) = target_triple {
+ for target in target_triples {
cmd.args(&["--target", target.as_str()]);
}
if *all_targets {
@@ -357,10 +360,12 @@ impl FlycheckActor {
}
}
+struct JodChild(GroupChild);
+
/// A handle to a cargo process used for fly-checking.
struct CargoHandle {
/// The handle to the actual cargo process. As we cannot cancel directly from with
- /// a read syscall dropping and therefor terminating the process is our best option.
+ /// a read syscall dropping and therefore terminating the process is our best option.
child: JodChild,
thread: jod_thread::JoinHandle<io::Result<(bool, String)>>,
receiver: Receiver<CargoMessage>,
@@ -369,10 +374,10 @@ struct CargoHandle {
impl CargoHandle {
fn spawn(mut command: Command) -> std::io::Result<CargoHandle> {
command.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null());
- let mut child = JodChild::spawn(command)?;
+ let mut child = command.group_spawn().map(JodChild)?;
- let stdout = child.stdout.take().unwrap();
- let stderr = child.stderr.take().unwrap();
+ let stdout = child.0.inner().stdout.take().unwrap();
+ let stderr = child.0.inner().stderr.take().unwrap();
let (sender, receiver) = unbounded();
let actor = CargoActor::new(sender, stdout, stderr);
@@ -384,13 +389,13 @@ impl CargoHandle {
}
fn cancel(mut self) {
- let _ = self.child.kill();
- let _ = self.child.wait();
+ let _ = self.child.0.kill();
+ let _ = self.child.0.wait();
}
fn join(mut self) -> io::Result<()> {
- let _ = self.child.kill();
- let exit_status = self.child.wait()?;
+ let _ = self.child.0.kill();
+ let exit_status = self.child.0.wait()?;
let (read_at_least_one_message, error) = self.thread.join()?;
if read_at_least_one_message || exit_status.success() {
Ok(())
diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
index 4ad8e7597..22f98ea7c 100644
--- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
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 2dc69b00a..9c7696908 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -236,11 +236,19 @@ impl TraitData {
.by_key("rustc_skip_array_during_method_dispatch")
.exists();
- let mut collector =
- AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr));
- collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items);
- let (items, attribute_calls, diagnostics) = collector.finish();
-
+ let (items, attribute_calls, diagnostics) = match &tr_def.items {
+ Some(items) => {
+ let mut collector = AssocItemCollector::new(
+ db,
+ module_id,
+ tree_id.file_id(),
+ ItemContainerId::TraitId(tr),
+ );
+ collector.collect(&item_tree, tree_id.tree_id(), items);
+ collector.finish()
+ }
+ None => Default::default(),
+ };
(
Arc::new(TraitData {
name,
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 570344596..0aa531eff 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
@@ -666,7 +666,8 @@ pub struct Trait {
pub generic_params: Interned<GenericParams>,
pub is_auto: bool,
pub is_unsafe: bool,
- pub items: Box<[AssocItem]>,
+ /// This is [`None`] if this Trait is a trait alias.
+ pub items: Option<Box<[AssocItem]>>,
pub ast_id: FileAstId<ast::Trait>,
}
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 077a1b619..b25274bcc 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
@@ -451,15 +451,7 @@ impl<'a> Ctx<'a> {
.collect()
});
let ast_id = self.source_ast_id_map.ast_id(trait_def);
- let res = Trait {
- name,
- visibility,
- generic_params,
- is_auto,
- is_unsafe,
- items: items.unwrap_or_default(),
- ast_id,
- };
+ let res = Trait { name, visibility, generic_params, is_auto, is_unsafe, items, ast_id };
Some(id(self.data().traits.alloc(res)))
}
@@ -662,8 +654,12 @@ fn desugar_future_path(orig: TypeRef) -> Path {
let mut generic_args: Vec<_> =
std::iter::repeat(None).take(path.segments().len() - 1).collect();
let mut last = GenericArgs::empty();
- let binding =
- AssociatedTypeBinding { name: name![Output], type_ref: Some(orig), bounds: Vec::new() };
+ let binding = AssociatedTypeBinding {
+ name: name![Output],
+ args: None,
+ type_ref: Some(orig),
+ bounds: Vec::new(),
+ };
last.bindings.push(binding);
generic_args.push(Some(Interned::new(last)));
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 da1643152..48c40df22 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
@@ -375,12 +375,21 @@ impl<'a> Printer<'a> {
}
w!(self, "trait {}", name);
self.print_generic_params(generic_params);
- self.print_where_clause_and_opening_brace(generic_params);
- self.indented(|this| {
- for item in &**items {
- this.print_mod_item((*item).into());
+ match items {
+ Some(items) => {
+ self.print_where_clause_and_opening_brace(generic_params);
+ self.indented(|this| {
+ for item in &**items {
+ this.print_mod_item((*item).into());
+ }
+ });
}
- });
+ None => {
+ w!(self, " = ");
+ // FIXME: Print the aliased traits
+ self.print_where_clause_and_opening_brace(generic_params);
+ }
+ }
wln!(self, "}}");
}
ModItem::Impl(it) => {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs
index bc162d0fa..fc90c6e9f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs
@@ -94,11 +94,11 @@ macro_rules! m {
($($s:stmt)*) => (stringify!($($s |)*);)
}
stringify!(;
-|;
-|92|;
-|let x = 92|;
+| ;
+|92| ;
+|let x = 92| ;
|loop {}
-|;
+| ;
|);
"#]],
);
@@ -118,7 +118,7 @@ m!(.. .. ..);
macro_rules! m {
($($p:pat)*) => (stringify!($($p |)*);)
}
-stringify!(.. .. ..|);
+stringify!(.. .. .. |);
"#]],
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
index 029821e5e..118c14ed8 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
@@ -82,14 +82,14 @@ fn attribute_macro_syntax_completion_2() {
#[proc_macros::identity_when_valid]
fn foo() { bar.; blub }
"#,
- expect![[r##"
+ expect![[r#"
#[proc_macros::identity_when_valid]
fn foo() { bar.; blub }
fn foo() {
- bar.;
+ bar. ;
blub
-}"##]],
+}"#]],
);
}
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 9ffc21881..b0dd01f9d 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
@@ -212,6 +212,7 @@ impl Import {
#[derive(Debug, Eq, PartialEq)]
struct ImportDirective {
+ /// The module this import directive is in.
module_id: LocalModuleId,
import: Import,
status: PartialResolvedImport,
@@ -963,8 +964,10 @@ impl DefCollector<'_> {
fn update(
&mut self,
+ // The module for which `resolutions` have been resolve
module_id: LocalModuleId,
resolutions: &[(Option<Name>, PerNs)],
+ // Visibility this import will have
vis: Visibility,
import_type: ImportType,
) {
@@ -974,6 +977,7 @@ impl DefCollector<'_> {
fn update_recursive(
&mut self,
+ // The module for which `resolutions` have been resolve
module_id: LocalModuleId,
resolutions: &[(Option<Name>, PerNs)],
// All resolutions are imported with this visibility; the visibilities in
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 8dfda6df6..20d39ec6c 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
@@ -73,7 +73,10 @@ impl DefMap {
pub(crate) fn resolve_visibility(
&self,
db: &dyn DefDatabase,
+ // module to import to
original_module: LocalModuleId,
+ // pub(path)
+ // ^^^^ this
visibility: &RawVisibility,
) -> Option<Visibility> {
let mut vis = match visibility {
@@ -115,6 +118,7 @@ impl DefMap {
&self,
db: &dyn DefDatabase,
mode: ResolveMode,
+ // module to import to
mut original_module: LocalModuleId,
path: &ModPath,
shadow: BuiltinShadowMode,
@@ -361,6 +365,9 @@ impl DefMap {
);
}
};
+
+ curr_per_ns = curr_per_ns
+ .filter_visibility(|vis| vis.is_visible_from_def_map(db, self, original_module));
}
ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None, Some(self.krate))
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 70dd2eb3a..0d90047c2 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
@@ -58,9 +58,9 @@ extern {
"#,
expect![[r#"
crate
- E: t
+ E: _
S: t v
- V: t v
+ V: _
foo: t
crate::foo
@@ -307,7 +307,7 @@ pub struct FromLib;
Bar: t v
crate::foo
- Bar: t v
+ Bar: _
FromLib: t 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 b2a6a592c..88a3c7639 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
@@ -119,7 +119,7 @@ use foo::*;
use foo::bar::*;
//- /foo/mod.rs
-mod bar;
+pub mod bar;
fn Foo() {};
pub struct Foo {};
@@ -132,6 +132,7 @@ pub(crate) struct PubCrateStruct;
crate
Foo: t
PubCrateStruct: t v
+ bar: t
foo: t
crate::foo
@@ -336,3 +337,33 @@ mod d {
"#]],
);
}
+
+#[test]
+fn glob_name_collision_check_visibility() {
+ check(
+ r#"
+mod event {
+ mod serenity {
+ pub fn Event() {}
+ }
+ use serenity::*;
+
+ pub struct Event {}
+}
+
+use event::Event;
+ "#,
+ expect![[r#"
+ crate
+ Event: t
+ event: t
+
+ crate::event
+ Event: t v
+ serenity: t
+
+ crate::event::serenity
+ Event: 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 ba3bf8b5a..c575bf7ca 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
@@ -580,7 +580,7 @@ fn module_resolution_decl_inside_inline_module_in_crate_root() {
//- /main.rs
mod foo {
#[path = "baz.rs"]
- mod bar;
+ pub mod bar;
}
use self::foo::bar::Baz;
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 2f13a9fbf..592223f7d 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/path.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/path.rs
@@ -68,6 +68,9 @@ pub struct GenericArgs {
pub struct AssociatedTypeBinding {
/// The name of the associated type.
pub name: Name,
+ /// The generic arguments to the associated type. e.g. For `Trait<Assoc<'a, T> = &'a T>`, this
+ /// would be `['a, T]`.
+ pub args: Option<Interned<GenericArgs>>,
/// The type bound to this associated type (in `Item = T`, this would be the
/// `T`). This can be `None` if there are bounds instead.
pub type_ref: Option<TypeRef>,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs
index 0428f1a39..cfa3a6baa 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs
@@ -163,6 +163,10 @@ pub(super) fn lower_generic_args(
ast::GenericArg::AssocTypeArg(assoc_type_arg) => {
if let Some(name_ref) = assoc_type_arg.name_ref() {
let name = name_ref.as_name();
+ let args = assoc_type_arg
+ .generic_arg_list()
+ .and_then(|args| lower_generic_args(lower_ctx, args))
+ .map(Interned::new);
let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
l.bounds()
@@ -171,7 +175,7 @@ pub(super) fn lower_generic_args(
} else {
Vec::new()
};
- bindings.push(AssociatedTypeBinding { name, type_ref, bounds });
+ bindings.push(AssociatedTypeBinding { name, args, type_ref, bounds });
}
}
ast::GenericArg::LifetimeArg(lifetime_arg) => {
@@ -214,6 +218,7 @@ fn lower_generic_args_from_fn_path(
let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty());
bindings.push(AssociatedTypeBinding {
name: name![Output],
+ args: None,
type_ref: Some(type_ref),
bounds: Vec::new(),
});
@@ -222,6 +227,7 @@ fn lower_generic_args_from_fn_path(
let type_ref = TypeRef::Tuple(Vec::new());
bindings.push(AssociatedTypeBinding {
name: name![Output],
+ args: None,
type_ref: Some(type_ref),
bounds: Vec::new(),
});
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 6636c8a23..933970d10 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/pretty.rs
@@ -143,9 +143,12 @@ pub(crate) fn print_type_ref(type_ref: &TypeRef, buf: &mut dyn Write) -> fmt::Re
print_type_ref(elem, buf)?;
write!(buf, "]")?;
}
- TypeRef::Fn(args_and_ret, varargs) => {
+ TypeRef::Fn(args_and_ret, varargs, is_unsafe) => {
let ((_, return_type), args) =
args_and_ret.split_last().expect("TypeRef::Fn is missing return type");
+ if *is_unsafe {
+ write!(buf, "unsafe ")?;
+ }
write!(buf, "fn(")?;
for (i, (_, typeref)) in args.iter().enumerate() {
if i != 0 {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs
index 5b4c71be7..f8bb78ddc 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/type_ref.rs
@@ -119,7 +119,7 @@ pub enum TypeRef {
Array(Box<TypeRef>, ConstScalarOrPath),
Slice(Box<TypeRef>),
/// A fn pointer. Last element of the vector is the return type.
- Fn(Vec<(Option<Name>, TypeRef)>, bool /*varargs*/),
+ Fn(Vec<(Option<Name>, TypeRef)>, bool /*varargs*/, bool /*is_unsafe*/),
ImplTrait(Vec<Interned<TypeBound>>),
DynTrait(Vec<Interned<TypeBound>>),
Macro(AstId<ast::MacroCall>),
@@ -229,7 +229,7 @@ impl TypeRef {
Vec::new()
};
params.push((None, ret_ty));
- TypeRef::Fn(params, is_varargs)
+ TypeRef::Fn(params, is_varargs, inner.unsafe_token().is_some())
}
// for types are close enough for our purposes to the inner type for now...
ast::Type::ForType(inner) => TypeRef::from_ast_opt(ctx, inner.ty()),
@@ -263,7 +263,7 @@ impl TypeRef {
fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) {
f(type_ref);
match type_ref {
- TypeRef::Fn(params, _) => {
+ TypeRef::Fn(params, _, _) => {
params.iter().for_each(|(_, param_type)| go(param_type, f))
}
TypeRef::Tuple(types) => types.iter().for_each(|t| go(t, f)),
diff --git a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml
index 3359c99b3..77eb1fd45 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
index 893e6fe4b..a4abe7562 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/fixup.rs
@@ -4,6 +4,7 @@ use std::mem;
use mbe::{SyntheticToken, SyntheticTokenId, TokenMap};
use rustc_hash::FxHashMap;
+use smallvec::SmallVec;
use syntax::{
ast::{self, AstNode, HasLoopBody},
match_ast, SyntaxElement, SyntaxKind, SyntaxNode, TextRange,
@@ -292,25 +293,34 @@ pub(crate) fn reverse_fixups(
token_map: &TokenMap,
undo_info: &SyntaxFixupUndoInfo,
) {
- tt.token_trees.retain(|tt| match tt {
- tt::TokenTree::Leaf(leaf) => {
- token_map.synthetic_token_id(leaf.id()).is_none()
- || token_map.synthetic_token_id(leaf.id()) != Some(EMPTY_ID)
- }
- tt::TokenTree::Subtree(st) => st.delimiter.map_or(true, |d| {
- token_map.synthetic_token_id(d.id).is_none()
- || token_map.synthetic_token_id(d.id) != Some(EMPTY_ID)
- }),
- });
- tt.token_trees.iter_mut().for_each(|tt| match tt {
- tt::TokenTree::Subtree(tt) => reverse_fixups(tt, token_map, undo_info),
- tt::TokenTree::Leaf(leaf) => {
- if let Some(id) = token_map.synthetic_token_id(leaf.id()) {
- let original = &undo_info.original[id.0 as usize];
- *tt = tt::TokenTree::Subtree(original.clone());
+ let tts = std::mem::take(&mut tt.token_trees);
+ tt.token_trees = tts
+ .into_iter()
+ .filter(|tt| match tt {
+ tt::TokenTree::Leaf(leaf) => token_map.synthetic_token_id(leaf.id()) != Some(EMPTY_ID),
+ tt::TokenTree::Subtree(st) => {
+ st.delimiter.map_or(true, |d| token_map.synthetic_token_id(d.id) != Some(EMPTY_ID))
}
- }
- });
+ })
+ .flat_map(|tt| match tt {
+ tt::TokenTree::Subtree(mut tt) => {
+ reverse_fixups(&mut tt, token_map, undo_info);
+ SmallVec::from_const([tt.into()])
+ }
+ tt::TokenTree::Leaf(leaf) => {
+ if let Some(id) = token_map.synthetic_token_id(leaf.id()) {
+ let original = undo_info.original[id.0 as usize].clone();
+ if original.delimiter.is_none() {
+ original.token_trees.into()
+ } else {
+ SmallVec::from_const([original.into()])
+ }
+ } else {
+ SmallVec::from_const([leaf.into()])
+ }
+ }
+ })
+ .collect();
}
#[cfg(test)]
@@ -319,6 +329,31 @@ mod tests {
use super::reverse_fixups;
+ // The following three functions are only meant to check partial structural equivalence of
+ // `TokenTree`s, see the last assertion in `check()`.
+ fn check_leaf_eq(a: &tt::Leaf, b: &tt::Leaf) -> bool {
+ match (a, b) {
+ (tt::Leaf::Literal(a), tt::Leaf::Literal(b)) => a.text == b.text,
+ (tt::Leaf::Punct(a), tt::Leaf::Punct(b)) => a.char == b.char,
+ (tt::Leaf::Ident(a), tt::Leaf::Ident(b)) => a.text == b.text,
+ _ => false,
+ }
+ }
+
+ fn check_subtree_eq(a: &tt::Subtree, b: &tt::Subtree) -> bool {
+ a.delimiter.map(|it| it.kind) == b.delimiter.map(|it| it.kind)
+ && a.token_trees.len() == b.token_trees.len()
+ && a.token_trees.iter().zip(&b.token_trees).all(|(a, b)| check_tt_eq(a, b))
+ }
+
+ fn check_tt_eq(a: &tt::TokenTree, b: &tt::TokenTree) -> bool {
+ match (a, b) {
+ (tt::TokenTree::Leaf(a), tt::TokenTree::Leaf(b)) => check_leaf_eq(a, b),
+ (tt::TokenTree::Subtree(a), tt::TokenTree::Subtree(b)) => check_subtree_eq(a, b),
+ _ => false,
+ }
+ }
+
#[track_caller]
fn check(ra_fixture: &str, mut expect: Expect) {
let parsed = syntax::SourceFile::parse(ra_fixture);
@@ -331,17 +366,15 @@ mod tests {
fixups.append,
);
- let mut actual = tt.to_string();
- actual.push('\n');
+ let actual = format!("{}\n", tt);
expect.indent(false);
expect.assert_eq(&actual);
// the fixed-up tree should be syntactically valid
let (parse, _) = mbe::token_tree_to_syntax_node(&tt, ::mbe::TopEntryPoint::MacroItems);
- assert_eq!(
- parse.errors(),
- &[],
+ assert!(
+ parse.errors().is_empty(),
"parse has syntax errors. parse tree:\n{:#?}",
parse.syntax_node()
);
@@ -349,9 +382,12 @@ mod tests {
reverse_fixups(&mut tt, &tmap, &fixups.undo_info);
// the fixed-up + reversed version should be equivalent to the original input
- // (but token IDs don't matter)
+ // modulo token IDs and `Punct`s' spacing.
let (original_as_tt, _) = mbe::syntax_node_to_token_tree(&parsed.syntax_node());
- assert_eq!(tt.to_string(), original_as_tt.to_string());
+ assert!(
+ check_subtree_eq(&tt, &original_as_tt),
+ "different token tree: {tt:?}, {original_as_tt:?}"
+ );
}
#[test]
@@ -468,7 +504,7 @@ fn foo() {
}
"#,
expect![[r#"
-fn foo () {a .__ra_fixup}
+fn foo () {a . __ra_fixup}
"#]],
)
}
@@ -482,7 +518,7 @@ fn foo() {
}
"#,
expect![[r#"
-fn foo () {a .__ra_fixup ;}
+fn foo () {a . __ra_fixup ;}
"#]],
)
}
@@ -497,7 +533,7 @@ fn foo() {
}
"#,
expect![[r#"
-fn foo () {a .__ra_fixup ; bar () ;}
+fn foo () {a . __ra_fixup ; bar () ;}
"#]],
)
}
@@ -525,7 +561,7 @@ fn foo() {
}
"#,
expect![[r#"
-fn foo () {let x = a .__ra_fixup ;}
+fn foo () {let x = a . __ra_fixup ;}
"#]],
)
}
@@ -541,7 +577,7 @@ fn foo() {
}
"#,
expect![[r#"
-fn foo () {a .b ; bar () ;}
+fn foo () {a . b ; bar () ;}
"#]],
)
}
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 a5b499fe8..7352b003a 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
@@ -814,7 +814,7 @@ impl<'a> InFile<&'a SyntaxNode> {
pub fn original_syntax_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> {
// This kind of upmapping can only be achieved in attribute expanded files,
- // as we don't have node inputs otherwise and therefor can't find an `N` node in the input
+ // as we don't have node inputs otherwise and therefore can't find an `N` node in the input
if !self.file_id.is_macro() {
return Some(self.map(Clone::clone));
} else if !self.file_id.is_attr_macro(db) {
@@ -926,7 +926,7 @@ impl<N: AstNode> InFile<N> {
pub fn original_ast_node(self, db: &dyn db::AstDatabase) -> Option<InFile<N>> {
// This kind of upmapping can only be achieved in attribute expanded files,
- // as we don't have node inputs otherwise and therefor can't find an `N` node in the input
+ // as we don't have node inputs otherwise and therefore can't find an `N` node in the input
if !self.file_id.is_macro() {
return Some(self);
} else if !self.file_id.is_attr_macro(db) {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
index ed13275ba..a1d6835bf 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
index e2099d7e5..996b42f5b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
@@ -11,9 +11,9 @@ use syntax::SmolStr;
use crate::{
db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
- from_placeholder_idx, to_chalk_trait_id, AdtId, AliasEq, AliasTy, Binders, CallableDefId,
- CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy, QuantifiedWhereClause,
- Substitution, TraitRef, Ty, TyBuilder, TyKind, WhereClause,
+ from_placeholder_idx, to_chalk_trait_id, utils::generics, AdtId, AliasEq, AliasTy, Binders,
+ CallableDefId, CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy,
+ QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, WhereClause,
};
pub trait TyExt {
@@ -338,10 +338,13 @@ pub trait ProjectionTyExt {
impl ProjectionTyExt for ProjectionTy {
fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
- TraitRef {
- trait_id: to_chalk_trait_id(self.trait_(db)),
- substitution: self.substitution.clone(),
- }
+ // FIXME: something like `Split` trait from chalk-solve might be nice.
+ let generics = generics(db.upcast(), from_assoc_type_id(self.associated_ty_id).into());
+ let substitution = Substitution::from_iter(
+ Interner,
+ self.substitution.iter(Interner).skip(generics.len_self()),
+ );
+ TraitRef { trait_id: to_chalk_trait_id(self.trait_(db)), substitution }
}
fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
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 0221f922f..a22a4b170 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -289,16 +289,18 @@ impl HirDisplay for ProjectionTy {
return write!(f, "{}", TYPE_HINT_TRUNCATION);
}
- let trait_ = f.db.trait_data(self.trait_(f.db));
+ let trait_ref = self.trait_ref(f.db);
write!(f, "<")?;
- self.self_type_parameter(f.db).hir_fmt(f)?;
- write!(f, " as {}", trait_.name)?;
- if self.substitution.len(Interner) > 1 {
+ fmt_trait_ref(&trait_ref, f, true)?;
+ write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
+ let proj_params_count =
+ self.substitution.len(Interner) - trait_ref.substitution.len(Interner);
+ let proj_params = &self.substitution.as_slice(Interner)[..proj_params_count];
+ if !proj_params.is_empty() {
write!(f, "<")?;
- f.write_joined(&self.substitution.as_slice(Interner)[1..], ", ")?;
+ f.write_joined(proj_params, ", ")?;
write!(f, ">")?;
}
- write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
Ok(())
}
}
@@ -641,9 +643,12 @@ impl HirDisplay for Ty {
// Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
if f.display_target.is_test() {
write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
+ // Note that the generic args for the associated type come before those for the
+ // trait (including the self type).
+ // FIXME: reconsider the generic args order upon formatting?
if parameters.len(Interner) > 0 {
write!(f, "<")?;
- f.write_joined(&*parameters.as_slice(Interner), ", ")?;
+ f.write_joined(parameters.as_slice(Interner), ", ")?;
write!(f, ">")?;
}
} else {
@@ -972,9 +977,20 @@ fn write_bounds_like_dyn_trait(
angle_open = true;
}
if let AliasTy::Projection(proj) = alias {
- let type_alias =
- f.db.type_alias_data(from_assoc_type_id(proj.associated_ty_id));
- write!(f, "{} = ", type_alias.name)?;
+ let assoc_ty_id = from_assoc_type_id(proj.associated_ty_id);
+ let type_alias = f.db.type_alias_data(assoc_ty_id);
+ write!(f, "{}", type_alias.name)?;
+
+ let proj_arg_count = generics(f.db.upcast(), assoc_ty_id.into()).len_self();
+ if proj_arg_count > 0 {
+ write!(f, "<")?;
+ f.write_joined(
+ &proj.substitution.as_slice(Interner)[..proj_arg_count],
+ ", ",
+ )?;
+ write!(f, ">")?;
+ }
+ write!(f, " = ")?;
}
ty.hir_fmt(f)?;
}
@@ -1171,8 +1187,11 @@ impl HirDisplay for TypeRef {
inner.hir_fmt(f)?;
write!(f, "]")?;
}
- TypeRef::Fn(parameters, is_varargs) => {
+ &TypeRef::Fn(ref parameters, is_varargs, is_unsafe) => {
// FIXME: Function pointer qualifiers.
+ if is_unsafe {
+ write!(f, "unsafe ")?;
+ }
write!(f, "fn(")?;
if let Some(((_, return_type), function_parameters)) = parameters.split_last() {
for index in 0..function_parameters.len() {
@@ -1187,7 +1206,7 @@ impl HirDisplay for TypeRef {
write!(f, ", ")?;
}
}
- if *is_varargs {
+ if is_varargs {
write!(f, "{}...", if parameters.len() == 1 { "" } else { ", " })?;
}
write!(f, ")")?;
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 0efff651c..0b3c23f57 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -1020,7 +1020,7 @@ impl Expectation {
/// The primary use case is where the expected type is a fat pointer,
/// like `&[isize]`. For example, consider the following statement:
///
- /// let x: &[isize] = &[1, 2, 3];
+ /// let x: &[isize] = &[1, 2, 3];
///
/// In this case, the expected type for the `&[1, 2, 3]` expression is
/// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
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 f56108b26..b1f4de826 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
@@ -85,6 +85,7 @@ impl<'a> InferenceContext<'a> {
let ty = match &self.body[tgt_expr] {
Expr::Missing => self.err_ty(),
&Expr::If { condition, then_branch, else_branch } => {
+ let expected = &expected.adjust_for_branches(&mut self.table);
self.infer_expr(
condition,
&Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
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 7a4754cdc..ebe9d6fb5 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
@@ -157,7 +157,7 @@ impl<'a> InferenceContext<'a> {
remaining_segments_for_ty,
true,
);
- if let TyKind::Error = ty.kind(Interner) {
+ if ty.is_unknown() {
return None;
}
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 b00e3216b..12f45f00f 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
@@ -340,8 +340,8 @@ impl<'a> InferenceTable<'a> {
self.resolve_with_fallback(t, &|_, _, d, _| d)
}
- /// Unify two types and register new trait goals that arise from that.
- pub(crate) fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
+ /// Unify two relatable values (e.g. `Ty`) and register new trait goals that arise from that.
+ pub(crate) fn unify<T: ?Sized + Zip<Interner>>(&mut self, ty1: &T, ty2: &T) -> bool {
let result = match self.try_unify(ty1, ty2) {
Ok(r) => r,
Err(_) => return false,
@@ -350,9 +350,13 @@ impl<'a> InferenceTable<'a> {
true
}
- /// Unify two types and return new trait goals arising from it, so the
+ /// Unify two relatable values (e.g. `Ty`) and return new trait goals arising from it, so the
/// caller needs to deal with them.
- pub(crate) fn try_unify<T: Zip<Interner>>(&mut self, t1: &T, t2: &T) -> InferResult<()> {
+ pub(crate) fn try_unify<T: ?Sized + Zip<Interner>>(
+ &mut self,
+ t1: &T,
+ t2: &T,
+ ) -> InferResult<()> {
match self.var_unification_table.relate(
Interner,
&self.db,
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 c4b700cbc..39514fc44 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -38,10 +38,12 @@ use std::sync::Arc;
use chalk_ir::{
fold::{Shift, TypeFoldable},
interner::HasInterner,
- NoSolution,
+ NoSolution, UniverseIndex,
};
use hir_def::{expr::ExprId, type_ref::Rawness, TypeOrConstParamId};
+use hir_expand::name;
use itertools::Either;
+use traits::FnTrait;
use utils::Generics;
use crate::{consteval::unknown_const, db::HirDatabase, utils::generics};
@@ -51,7 +53,7 @@ pub use builder::{ParamKind, TyBuilder};
pub use chalk_ext::*;
pub use infer::{
could_coerce, could_unify, Adjust, Adjustment, AutoBorrow, BindingMode, InferenceDiagnostic,
- InferenceResult,
+ InferenceResult, OverloadedDeref, PointerCast,
};
pub use interner::Interner;
pub use lower::{
@@ -81,7 +83,20 @@ pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
pub type VariableKind = chalk_ir::VariableKind<Interner>;
pub type VariableKinds = chalk_ir::VariableKinds<Interner>;
pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
+/// Represents generic parameters and an item bound by them. When the item has parent, the binders
+/// also contain the generic parameters for its parent. See chalk's documentation for details.
+///
+/// One thing to keep in mind when working with `Binders` (and `Substitution`s, which represent
+/// generic arguments) in rust-analyzer is that the ordering within *is* significant - the generic
+/// parameters/arguments for an item MUST come before those for its parent. This is to facilitate
+/// the integration with chalk-solve, which mildly puts constraints as such. See #13335 for its
+/// motivation in detail.
pub type Binders<T> = chalk_ir::Binders<T>;
+/// Interned list of generic arguments for an item. When an item has parent, the `Substitution` for
+/// it contains generic arguments for both its parent and itself. See chalk's documentation for
+/// details.
+///
+/// See `Binders` for the constraint on the ordering.
pub type Substitution = chalk_ir::Substitution<Interner>;
pub type GenericArg = chalk_ir::GenericArg<Interner>;
pub type GenericArgData = chalk_ir::GenericArgData<Interner>;
@@ -124,14 +139,6 @@ pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>;
pub type Guidance = chalk_solve::Guidance<Interner>;
pub type WhereClause = chalk_ir::WhereClause<Interner>;
-// FIXME: get rid of this
-pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution {
- Substitution::from_iter(
- Interner,
- s.as_slice(Interner)[..std::cmp::min(s.len(Interner), n)].iter().cloned(),
- )
-}
-
/// Return an index of a parameter in the generic type parameter list by it's id.
pub fn param_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<usize> {
generics(db.upcast(), id.parent).param_idx(id)
@@ -203,6 +210,7 @@ pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>(
pub struct CallableSig {
params_and_return: Arc<[Ty]>,
is_varargs: bool,
+ safety: Safety,
}
has_interner!(CallableSig);
@@ -211,9 +219,14 @@ has_interner!(CallableSig);
pub type PolyFnSig = Binders<CallableSig>;
impl CallableSig {
- pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig {
+ pub fn from_params_and_return(
+ mut params: Vec<Ty>,
+ ret: Ty,
+ is_varargs: bool,
+ safety: Safety,
+ ) -> CallableSig {
params.push(ret);
- CallableSig { params_and_return: params.into(), is_varargs }
+ CallableSig { params_and_return: params.into(), is_varargs, safety }
}
pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
@@ -230,13 +243,14 @@ impl CallableSig {
.map(|arg| arg.assert_ty_ref(Interner).clone())
.collect(),
is_varargs: fn_ptr.sig.variadic,
+ safety: fn_ptr.sig.safety,
}
}
pub fn to_fn_ptr(&self) -> FnPointer {
FnPointer {
num_binders: 0,
- sig: FnSig { abi: (), safety: Safety::Safe, variadic: self.is_varargs },
+ sig: FnSig { abi: (), safety: self.safety, variadic: self.is_varargs },
substitution: FnSubst(Substitution::from_iter(
Interner,
self.params_and_return.iter().cloned(),
@@ -261,7 +275,11 @@ impl TypeFoldable<Interner> for CallableSig {
) -> Result<Self, E> {
let vec = self.params_and_return.to_vec();
let folded = vec.try_fold_with(folder, outer_binder)?;
- Ok(CallableSig { params_and_return: folded.into(), is_varargs: self.is_varargs })
+ Ok(CallableSig {
+ params_and_return: folded.into(),
+ is_varargs: self.is_varargs,
+ safety: self.safety,
+ })
}
}
@@ -382,7 +400,6 @@ pub(crate) fn fold_tys_and_consts<T: HasInterner<Interner = Interner> + TypeFold
pub fn replace_errors_with_variables<T>(t: &T) -> Canonical<T>
where
T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + Clone,
- T: HasInterner<Interner = Interner>,
{
use chalk_ir::{
fold::{FallibleTypeFolder, TypeSuperFoldable},
@@ -504,3 +521,64 @@ where
});
Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(Interner, kinds) }
}
+
+pub fn callable_sig_from_fnonce(
+ self_ty: &Ty,
+ env: Arc<TraitEnvironment>,
+ db: &dyn HirDatabase,
+) -> Option<CallableSig> {
+ let krate = env.krate;
+ let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
+ let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
+
+ let b = TyBuilder::trait_ref(db, fn_once_trait);
+ if b.remaining() != 2 {
+ return None;
+ }
+ let fn_once = b.push(self_ty.clone()).fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
+ let kinds = fn_once
+ .substitution
+ .iter(Interner)
+ .skip(1)
+ .map(|x| {
+ let vk = match x.data(Interner) {
+ chalk_ir::GenericArgData::Ty(_) => {
+ chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
+ }
+ chalk_ir::GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime,
+ chalk_ir::GenericArgData::Const(c) => {
+ chalk_ir::VariableKind::Const(c.data(Interner).ty.clone())
+ }
+ };
+ chalk_ir::WithKind::new(vk, UniverseIndex::ROOT)
+ })
+ .collect::<Vec<_>>();
+
+ // FIXME: chalk refuses to solve `<Self as FnOnce<^0.0>>::Output == ^0.1`, so we first solve
+ // `<Self as FnOnce<^0.0>>` and then replace `^0.0` with the concrete argument tuple.
+ let trait_env = env.env.clone();
+ let obligation = InEnvironment { goal: fn_once.cast(Interner), environment: trait_env };
+ let canonical =
+ Canonical { binders: CanonicalVarKinds::from_iter(Interner, kinds), value: obligation };
+ let subst = match db.trait_solve(krate, canonical) {
+ Some(Solution::Unique(vars)) => vars.value.subst,
+ _ => return None,
+ };
+ let args = subst.at(Interner, 0).ty(Interner)?;
+ let params = match args.kind(Interner) {
+ chalk_ir::TyKind::Tuple(_, subst) => {
+ subst.iter(Interner).filter_map(|arg| arg.ty(Interner).cloned()).collect::<Vec<_>>()
+ }
+ _ => return None,
+ };
+
+ let fn_once =
+ TyBuilder::trait_ref(db, fn_once_trait).push(self_ty.clone()).push(args.clone()).build();
+ let projection =
+ TyBuilder::assoc_type_projection(db, output_assoc_type, Some(fn_once.substitution.clone()))
+ .build();
+
+ let ret_ty = db.normalize_projection(projection, env);
+
+ Some(CallableSig::from_params_and_return(params, ret_ty.clone(), false, Safety::Safe))
+}
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 223d705b1..baf9842d5 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -227,13 +227,17 @@ impl<'a> TyLoweringContext<'a> {
.intern(Interner)
}
TypeRef::Placeholder => TyKind::Error.intern(Interner),
- TypeRef::Fn(params, is_varargs) => {
+ &TypeRef::Fn(ref params, variadic, is_unsafe) => {
let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
});
TyKind::Function(FnPointer {
num_binders: 0, // FIXME lower `for<'a> fn()` correctly
- sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
+ sig: FnSig {
+ abi: (),
+ safety: if is_unsafe { Safety::Unsafe } else { Safety::Safe },
+ variadic,
+ },
substitution: FnSubst(substs),
})
.intern(Interner)
@@ -447,12 +451,31 @@ impl<'a> TyLoweringContext<'a> {
.db
.trait_data(trait_ref.hir_trait_id())
.associated_type_by_name(segment.name);
+
match found {
Some(associated_ty) => {
- // FIXME handle type parameters on the segment
+ // FIXME: `substs_from_path_segment()` pushes `TyKind::Error` for every parent
+ // generic params. It's inefficient to splice the `Substitution`s, so we may want
+ // that method to optionally take parent `Substitution` as we already know them at
+ // this point (`trait_ref.substitution`).
+ let substitution = self.substs_from_path_segment(
+ segment,
+ Some(associated_ty.into()),
+ false,
+ None,
+ );
+ let len_self =
+ generics(self.db.upcast(), associated_ty.into()).len_self();
+ let substitution = Substitution::from_iter(
+ Interner,
+ substitution
+ .iter(Interner)
+ .take(len_self)
+ .chain(trait_ref.substitution.iter(Interner)),
+ );
TyKind::Alias(AliasTy::Projection(ProjectionTy {
associated_ty_id: to_assoc_type_id(associated_ty),
- substitution: trait_ref.substitution,
+ substitution,
}))
.intern(Interner)
}
@@ -590,36 +613,48 @@ impl<'a> TyLoweringContext<'a> {
res,
Some(segment.name.clone()),
move |name, t, associated_ty| {
- if name == segment.name {
- let substs = match self.type_param_mode {
- ParamLoweringMode::Placeholder => {
- // if we're lowering to placeholders, we have to put
- // them in now
- let generics = generics(
- self.db.upcast(),
- self.resolver
- .generic_def()
- .expect("there should be generics if there's a generic param"),
- );
- let s = generics.placeholder_subst(self.db);
- s.apply(t.substitution.clone(), Interner)
- }
- ParamLoweringMode::Variable => t.substitution.clone(),
- };
- // We need to shift in the bound vars, since
- // associated_type_shorthand_candidates does not do that
- let substs = substs.shifted_in_from(Interner, self.in_binders);
- // FIXME handle type parameters on the segment
- Some(
- TyKind::Alias(AliasTy::Projection(ProjectionTy {
- associated_ty_id: to_assoc_type_id(associated_ty),
- substitution: substs,
- }))
- .intern(Interner),
- )
- } else {
- None
+ if name != segment.name {
+ return None;
}
+
+ // FIXME: `substs_from_path_segment()` pushes `TyKind::Error` for every parent
+ // generic params. It's inefficient to splice the `Substitution`s, so we may want
+ // that method to optionally take parent `Substitution` as we already know them at
+ // this point (`t.substitution`).
+ let substs = self.substs_from_path_segment(
+ segment.clone(),
+ Some(associated_ty.into()),
+ false,
+ None,
+ );
+
+ let len_self = generics(self.db.upcast(), associated_ty.into()).len_self();
+
+ let substs = Substitution::from_iter(
+ Interner,
+ substs.iter(Interner).take(len_self).chain(t.substitution.iter(Interner)),
+ );
+
+ let substs = match self.type_param_mode {
+ ParamLoweringMode::Placeholder => {
+ // if we're lowering to placeholders, we have to put
+ // them in now
+ let generics = generics(self.db.upcast(), def);
+ let s = generics.placeholder_subst(self.db);
+ s.apply(substs, Interner)
+ }
+ ParamLoweringMode::Variable => substs,
+ };
+ // We need to shift in the bound vars, since
+ // associated_type_shorthand_candidates does not do that
+ let substs = substs.shifted_in_from(Interner, self.in_binders);
+ Some(
+ TyKind::Alias(AliasTy::Projection(ProjectionTy {
+ associated_ty_id: to_assoc_type_id(associated_ty),
+ substitution: substs,
+ }))
+ .intern(Interner),
+ )
},
);
@@ -777,7 +812,15 @@ impl<'a> TyLoweringContext<'a> {
// handle defaults. In expression or pattern path segments without
// explicitly specified type arguments, missing type arguments are inferred
// (i.e. defaults aren't used).
- if !infer_args || had_explicit_args {
+ // Generic parameters for associated types are not supposed to have defaults, so we just
+ // ignore them.
+ let is_assoc_ty = if let GenericDefId::TypeAliasId(id) = def {
+ let container = id.lookup(self.db.upcast()).container;
+ matches!(container, ItemContainerId::TraitId(_))
+ } else {
+ false
+ };
+ if !is_assoc_ty && (!infer_args || had_explicit_args) {
let defaults = self.db.generic_defaults(def);
assert_eq!(total_len, defaults.len());
let parent_from = item_len - substs.len();
@@ -966,9 +1009,28 @@ impl<'a> TyLoweringContext<'a> {
None => return SmallVec::new(),
Some(t) => t,
};
+ // FIXME: `substs_from_path_segment()` pushes `TyKind::Error` for every parent
+ // generic params. It's inefficient to splice the `Substitution`s, so we may want
+ // that method to optionally take parent `Substitution` as we already know them at
+ // this point (`super_trait_ref.substitution`).
+ let substitution = self.substs_from_path_segment(
+ // FIXME: This is hack. We shouldn't really build `PathSegment` directly.
+ PathSegment { name: &binding.name, args_and_bindings: binding.args.as_deref() },
+ Some(associated_ty.into()),
+ false, // this is not relevant
+ Some(super_trait_ref.self_type_parameter(Interner)),
+ );
+ let self_params = generics(self.db.upcast(), associated_ty.into()).len_self();
+ let substitution = Substitution::from_iter(
+ Interner,
+ substitution
+ .iter(Interner)
+ .take(self_params)
+ .chain(super_trait_ref.substitution.iter(Interner)),
+ );
let projection_ty = ProjectionTy {
associated_ty_id: to_assoc_type_id(associated_ty),
- substitution: super_trait_ref.substitution,
+ substitution,
};
let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity(
binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
@@ -1515,7 +1577,12 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
.with_type_param_mode(ParamLoweringMode::Variable);
let ret = ctx_ret.lower_ty(&data.ret_type);
let generics = generics(db.upcast(), def.into());
- let sig = CallableSig::from_params_and_return(params, ret, data.is_varargs());
+ let sig = CallableSig::from_params_and_return(
+ params,
+ ret,
+ data.is_varargs(),
+ if data.has_unsafe_kw() { Safety::Unsafe } else { Safety::Safe },
+ );
make_binders(db, &generics, sig)
}
@@ -1559,7 +1626,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
- Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
+ Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe))
}
/// Build the type of a tuple struct constructor.
@@ -1586,7 +1653,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
TyLoweringContext::new(db, &resolver).with_type_param_mode(ParamLoweringMode::Variable);
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
- Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
+ Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe))
}
/// Build the type of a tuple enum variant constructor.
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
index 3a1a3f4fd..8bcfa2728 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs
@@ -22,10 +22,10 @@ use crate::{
from_foreign_def_id,
infer::{unify::InferenceTable, Adjust, Adjustment, AutoBorrow, OverloadedDeref, PointerCast},
primitive::{FloatTy, IntTy, UintTy},
- static_lifetime,
+ static_lifetime, to_chalk_trait_id,
utils::all_super_traits,
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner,
- Scalar, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
+ Scalar, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
};
/// This is used as a key for indexing impls.
@@ -541,7 +541,7 @@ pub struct ReceiverAdjustments {
impl ReceiverAdjustments {
pub(crate) fn apply(&self, table: &mut InferenceTable<'_>, ty: Ty) -> (Ty, Vec<Adjustment>) {
- let mut ty = ty;
+ let mut ty = table.resolve_ty_shallow(&ty);
let mut adjust = Vec::new();
for _ in 0..self.autoderefs {
match autoderef::autoderef_step(table, ty.clone()) {
@@ -624,52 +624,76 @@ pub(crate) fn iterate_method_candidates<T>(
slot
}
+/// Looks up the impl method that actually runs for the trait method `func`.
+///
+/// Returns `func` if it's not a method defined in a trait or the lookup failed.
pub fn lookup_impl_method(
- self_ty: &Ty,
db: &dyn HirDatabase,
env: Arc<TraitEnvironment>,
- trait_: TraitId,
+ func: FunctionId,
+ fn_subst: Substitution,
+) -> FunctionId {
+ let trait_id = match func.lookup(db.upcast()).container {
+ ItemContainerId::TraitId(id) => id,
+ _ => return func,
+ };
+ let trait_params = db.generic_params(trait_id.into()).type_or_consts.len();
+ let fn_params = fn_subst.len(Interner) - trait_params;
+ let trait_ref = TraitRef {
+ trait_id: to_chalk_trait_id(trait_id),
+ substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).skip(fn_params)),
+ };
+
+ let name = &db.function_data(func).name;
+ lookup_impl_method_for_trait_ref(trait_ref, db, env, name).unwrap_or(func)
+}
+
+fn lookup_impl_method_for_trait_ref(
+ trait_ref: TraitRef,
+ db: &dyn HirDatabase,
+ env: Arc<TraitEnvironment>,
name: &Name,
) -> Option<FunctionId> {
- let self_ty_fp = TyFingerprint::for_trait_impl(self_ty)?;
- let trait_impls = db.trait_impls_in_deps(env.krate);
- let impls = trait_impls.for_trait_and_self_ty(trait_, self_ty_fp);
- let mut table = InferenceTable::new(db, env.clone());
- find_matching_impl(impls, &mut table, &self_ty).and_then(|data| {
- data.items.iter().find_map(|it| match it {
- AssocItemId::FunctionId(f) => (db.function_data(*f).name == *name).then(|| *f),
- _ => None,
- })
+ let self_ty = trait_ref.self_type_parameter(Interner);
+ let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty)?;
+ let impls = db.trait_impls_in_deps(env.krate);
+ let impls = impls.for_trait_and_self_ty(trait_ref.hir_trait_id(), self_ty_fp);
+
+ let table = InferenceTable::new(db, env);
+
+ let impl_data = find_matching_impl(impls, table, trait_ref)?;
+ impl_data.items.iter().find_map(|it| match it {
+ AssocItemId::FunctionId(f) => (db.function_data(*f).name == *name).then(|| *f),
+ _ => None,
})
}
fn find_matching_impl(
mut impls: impl Iterator<Item = ImplId>,
- table: &mut InferenceTable<'_>,
- self_ty: &Ty,
+ mut table: InferenceTable<'_>,
+ actual_trait_ref: TraitRef,
) -> Option<Arc<ImplData>> {
let db = table.db;
loop {
let impl_ = impls.next()?;
let r = table.run_in_snapshot(|table| {
let impl_data = db.impl_data(impl_);
- let substs =
+ let impl_substs =
TyBuilder::subst_for_def(db, impl_, None).fill_with_inference_vars(table).build();
- let impl_ty = db.impl_self_ty(impl_).substitute(Interner, &substs);
-
- table
- .unify(self_ty, &impl_ty)
- .then(|| {
- let wh_goals =
- crate::chalk_db::convert_where_clauses(db, impl_.into(), &substs)
- .into_iter()
- .map(|b| b.cast(Interner));
+ let trait_ref = db
+ .impl_trait(impl_)
+ .expect("non-trait method in find_matching_impl")
+ .substitute(Interner, &impl_substs);
- let goal = crate::Goal::all(Interner, wh_goals);
+ if !table.unify(&trait_ref, &actual_trait_ref) {
+ return None;
+ }
- table.try_obligation(goal).map(|_| impl_data)
- })
- .flatten()
+ let wcs = crate::chalk_db::convert_where_clauses(db, impl_.into(), &impl_substs)
+ .into_iter()
+ .map(|b| b.cast(Interner));
+ let goal = crate::Goal::all(Interner, wcs);
+ table.try_obligation(goal).map(|_| impl_data)
});
if r.is_some() {
break r;
@@ -1214,7 +1238,7 @@ fn is_valid_fn_candidate(
let expected_receiver =
sig.map(|s| s.params()[0].clone()).substitute(Interner, &fn_subst);
- check_that!(table.unify(&receiver_ty, &expected_receiver));
+ check_that!(table.unify(receiver_ty, &expected_receiver));
}
if let ItemContainerId::ImplId(impl_id) = container {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
index d301595bc..7e3aecc2a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/coercion.rs
@@ -123,6 +123,23 @@ fn test() {
}
#[test]
+fn if_else_adjust_for_branches_discard_type_var() {
+ check_no_mismatches(
+ r#"
+fn test() {
+ let f = || {
+ if true {
+ &""
+ } else {
+ ""
+ }
+ };
+}
+"#,
+ );
+}
+
+#[test]
fn match_first_coerce() {
check_no_mismatches(
r#"
@@ -183,6 +200,22 @@ fn test() {
}
#[test]
+fn match_adjust_for_branches_discard_type_var() {
+ check_no_mismatches(
+ r#"
+fn test() {
+ let f = || {
+ match 0i32 {
+ 0i32 => &"",
+ _ => "",
+ }
+ };
+}
+"#,
+ );
+}
+
+#[test]
fn return_coerce_unknown() {
check_types(
r"
@@ -357,7 +390,7 @@ fn test() {
let f: fn(u32) -> isize = foo;
// ^^^ adjustments: Pointer(ReifyFnPointer)
let f: unsafe fn(u32) -> isize = foo;
- // ^^^ adjustments: Pointer(ReifyFnPointer)
+ // ^^^ adjustments: Pointer(ReifyFnPointer), Pointer(UnsafeFnPointer)
}",
);
}
@@ -388,7 +421,10 @@ fn coerce_closure_to_fn_ptr() {
check_no_mismatches(
r"
fn test() {
- let f: fn(u32) -> isize = |x| { 1 };
+ let f: fn(u32) -> u32 = |x| x;
+ // ^^^^^ adjustments: Pointer(ClosureFnPointer(Safe))
+ let f: unsafe fn(u32) -> u32 = |x| x;
+ // ^^^^^ adjustments: Pointer(ClosureFnPointer(Unsafe))
}",
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
index 8a8ff08cf..425432479 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/display_source_code.rs
@@ -196,3 +196,34 @@ fn test(
"#,
);
}
+
+#[test]
+fn projection_type_correct_arguments_order() {
+ check_types_source_code(
+ r#"
+trait Foo<T> {
+ type Assoc<U>;
+}
+fn f<T: Foo<i32>>(a: T::Assoc<usize>) {
+ a;
+ //^ <T as Foo<i32>>::Assoc<usize>
+}
+"#,
+ );
+}
+
+#[test]
+fn generic_associated_type_binding_in_impl_trait() {
+ check_types_source_code(
+ r#"
+//- minicore: sized
+trait Foo<T> {
+ type Assoc<U>;
+}
+fn f(a: impl Foo<i8, Assoc<i16> = i32>) {
+ a;
+ //^ impl Foo<i8, Assoc<i16> = i32>
+}
+ "#,
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
index ac8edb841..5d76d185f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/method_resolution.rs
@@ -164,16 +164,16 @@ fn infer_associated_method_with_modules() {
check_infer(
r#"
mod a {
- struct A;
+ pub struct A;
impl A { pub fn thing() -> A { A {} }}
}
mod b {
- struct B;
+ pub struct B;
impl B { pub fn thing() -> u32 { 99 }}
- mod c {
- struct C;
+ pub mod c {
+ pub struct C;
impl C { pub fn thing() -> C { C {} }}
}
}
@@ -186,22 +186,22 @@ fn infer_associated_method_with_modules() {
}
"#,
expect![[r#"
- 55..63 '{ A {} }': A
- 57..61 'A {}': A
- 125..131 '{ 99 }': u32
- 127..129 '99': u32
- 201..209 '{ C {} }': C
- 203..207 'C {}': C
- 240..324 '{ ...g(); }': ()
- 250..251 'x': A
- 254..265 'a::A::thing': fn thing() -> A
- 254..267 'a::A::thing()': A
- 277..278 'y': u32
- 281..292 'b::B::thing': fn thing() -> u32
- 281..294 'b::B::thing()': u32
- 304..305 'z': C
- 308..319 'c::C::thing': fn thing() -> C
- 308..321 'c::C::thing()': C
+ 59..67 '{ A {} }': A
+ 61..65 'A {}': A
+ 133..139 '{ 99 }': u32
+ 135..137 '99': u32
+ 217..225 '{ C {} }': C
+ 219..223 'C {}': C
+ 256..340 '{ ...g(); }': ()
+ 266..267 'x': A
+ 270..281 'a::A::thing': fn thing() -> A
+ 270..283 'a::A::thing()': A
+ 293..294 'y': u32
+ 297..308 'b::B::thing': fn thing() -> u32
+ 297..310 'b::B::thing()': u32
+ 320..321 'z': C
+ 324..335 'c::C::thing': fn thing() -> C
+ 324..337 'c::C::thing()': C
"#]],
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
index a155adcec..4e4639745 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs
@@ -1707,3 +1707,19 @@ impl<T, const N: usize> Trait for [T; N] {
"#,
);
}
+
+#[test]
+fn unsize_array_with_inference_variable() {
+ check_types(
+ r#"
+//- minicore: try, slice
+use core::ops::ControlFlow;
+fn foo() -> ControlFlow<(), [usize; 1]> { loop {} }
+fn bar() -> ControlFlow<(), ()> {
+ let a = foo()?.len();
+ //^ usize
+ ControlFlow::Continue(())
+}
+"#,
+ );
+}
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 080e2ac1b..d7431443b 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
@@ -214,7 +214,7 @@ fn infer_paths() {
fn a() -> u32 { 1 }
mod b {
- fn c() -> u32 { 1 }
+ pub fn c() -> u32 { 1 }
}
fn test() {
@@ -225,13 +225,13 @@ fn test() {
expect![[r#"
14..19 '{ 1 }': u32
16..17 '1': u32
- 47..52 '{ 1 }': u32
- 49..50 '1': u32
- 66..90 '{ ...c(); }': ()
- 72..73 'a': fn a() -> u32
- 72..75 'a()': u32
- 81..85 'b::c': fn c() -> u32
- 81..87 'b::c()': u32
+ 51..56 '{ 1 }': u32
+ 53..54 '1': u32
+ 70..94 '{ ...c(); }': ()
+ 76..77 'a': fn a() -> u32
+ 76..79 'a()': u32
+ 85..89 'b::c': fn c() -> u32
+ 85..91 'b::c()': u32
"#]],
);
}
@@ -1856,7 +1856,7 @@ fn not_shadowing_module_by_primitive() {
check_types(
r#"
//- /str.rs
-fn foo() -> u32 {0}
+pub fn foo() -> u32 {0}
//- /main.rs
mod str;
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 555b6972f..3d7194b6f 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
@@ -1706,7 +1706,7 @@ fn where_clause_trait_in_scope_for_method_resolution() {
check_types(
r#"
mod foo {
- trait Trait {
+ pub trait Trait {
fn foo(&self) -> u32 { 0 }
}
}
@@ -1723,7 +1723,7 @@ fn super_trait_method_resolution() {
check_infer(
r#"
mod foo {
- trait SuperTrait {
+ pub trait SuperTrait {
fn foo(&self) -> u32 {}
}
}
@@ -1735,15 +1735,15 @@ fn test<T: Trait1, U: Trait2>(x: T, y: U) {
y.foo();
}"#,
expect![[r#"
- 49..53 'self': &Self
- 62..64 '{}': u32
- 181..182 'x': T
- 187..188 'y': U
- 193..222 '{ ...o(); }': ()
- 199..200 'x': T
- 199..206 'x.foo()': u32
- 212..213 'y': U
- 212..219 'y.foo()': u32
+ 53..57 'self': &Self
+ 66..68 '{}': u32
+ 185..186 'x': T
+ 191..192 'y': U
+ 197..226 '{ ...o(); }': ()
+ 203..204 'x': T
+ 203..210 'x.foo()': u32
+ 216..217 'y': U
+ 216..223 'y.foo()': u32
"#]],
);
}
@@ -1754,7 +1754,7 @@ fn super_trait_impl_trait_method_resolution() {
r#"
//- minicore: sized
mod foo {
- trait SuperTrait {
+ pub trait SuperTrait {
fn foo(&self) -> u32 {}
}
}
@@ -1764,12 +1764,12 @@ fn test(x: &impl Trait1) {
x.foo();
}"#,
expect![[r#"
- 49..53 'self': &Self
- 62..64 '{}': u32
- 115..116 'x': &impl Trait1
- 132..148 '{ ...o(); }': ()
- 138..139 'x': &impl Trait1
- 138..145 'x.foo()': u32
+ 53..57 'self': &Self
+ 66..68 '{}': u32
+ 119..120 'x': &impl Trait1
+ 136..152 '{ ...o(); }': ()
+ 142..143 'x': &impl Trait1
+ 142..149 'x.foo()': u32
"#]],
);
}
@@ -3963,3 +3963,124 @@ fn g(t: &(dyn T + Send)) {
"#,
);
}
+
+#[test]
+fn gats_in_path() {
+ check_types(
+ r#"
+//- minicore: deref
+use core::ops::Deref;
+trait PointerFamily {
+ type Pointer<T>: Deref<Target = T>;
+}
+
+fn f<P: PointerFamily>(p: P::Pointer<i32>) {
+ let a = *p;
+ //^ i32
+}
+fn g<P: PointerFamily>(p: <P as PointerFamily>::Pointer<i32>) {
+ let a = *p;
+ //^ i32
+}
+ "#,
+ );
+}
+
+#[test]
+fn gats_with_impl_trait() {
+ // FIXME: the last function (`fn i()`) is not valid Rust as of this writing because you cannot
+ // specify the same associated type multiple times even if their arguments are different (c.f.
+ // `fn h()`, which is valid). Reconsider how to treat these invalid types.
+ check_types(
+ r#"
+//- minicore: deref
+use core::ops::Deref;
+
+trait Trait {
+ type Assoc<T>: Deref<Target = T>;
+ fn get<U>(&self) -> Self::Assoc<U>;
+}
+
+fn f<T>(v: impl Trait) {
+ let a = v.get::<i32>().deref();
+ //^ &i32
+ let a = v.get::<T>().deref();
+ //^ &T
+}
+fn g<'a, T: 'a>(v: impl Trait<Assoc<T> = &'a T>) {
+ let a = v.get::<T>();
+ //^ &T
+ let a = v.get::<()>();
+ //^ Trait::Assoc<(), impl Trait<Assoc<T> = &T>>
+}
+fn h<'a>(v: impl Trait<Assoc<i32> = &'a i32> + Trait<Assoc<i64> = &'a i64>) {
+ let a = v.get::<i32>();
+ //^ &i32
+ let a = v.get::<i64>();
+ //^ &i64
+}
+fn i<'a>(v: impl Trait<Assoc<i32> = &'a i32, Assoc<i64> = &'a i64>) {
+ let a = v.get::<i32>();
+ //^ &i32
+ let a = v.get::<i64>();
+ //^ &i64
+}
+ "#,
+ );
+}
+
+#[test]
+fn gats_with_dyn() {
+ // This test is here to keep track of how we infer things despite traits with GATs being not
+ // object-safe currently.
+ // FIXME: reconsider how to treat these invalid types.
+ check_infer_with_mismatches(
+ r#"
+//- minicore: deref
+use core::ops::Deref;
+
+trait Trait {
+ type Assoc<T>: Deref<Target = T>;
+ fn get<U>(&self) -> Self::Assoc<U>;
+}
+
+fn f<'a>(v: &dyn Trait<Assoc<i32> = &'a i32>) {
+ v.get::<i32>().deref();
+}
+ "#,
+ expect![[r#"
+ 90..94 'self': &Self
+ 127..128 'v': &(dyn Trait<Assoc<i32> = &i32>)
+ 164..195 '{ ...f(); }': ()
+ 170..171 'v': &(dyn Trait<Assoc<i32> = &i32>)
+ 170..184 'v.get::<i32>()': &i32
+ 170..192 'v.get:...eref()': &i32
+ "#]],
+ );
+}
+
+#[test]
+fn gats_in_associated_type_binding() {
+ check_types(
+ r#"
+trait Trait {
+ type Assoc<T>;
+ fn get<U>(&self) -> Self::Assoc<U>;
+}
+
+fn f<T>(t: T)
+where
+ T: Trait<Assoc<i32> = u32>,
+ T: Trait<Assoc<isize> = usize>,
+{
+ let a = t.get::<i32>();
+ //^ u32
+ let a = t.get::<isize>();
+ //^ usize
+ let a = t.get::<()>();
+ //^ Trait::Assoc<(), T>
+}
+
+ "#,
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs
index 547850b02..92711a24f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/tls.rs
@@ -5,7 +5,7 @@ use itertools::Itertools;
use crate::{
chalk_db, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, mapping::from_chalk,
- CallableDefId, Interner,
+ CallableDefId, Interner, ProjectionTyExt,
};
use hir_def::{AdtId, ItemContainerId, Lookup, TypeAliasId};
@@ -63,17 +63,31 @@ impl DebugContext<'_> {
ItemContainerId::TraitId(t) => t,
_ => panic!("associated type not in trait"),
};
- let trait_data = self.0.trait_data(trait_);
- let params = projection_ty.substitution.as_slice(Interner);
- write!(fmt, "<{:?} as {}", &params[0], trait_data.name,)?;
- if params.len() > 1 {
+ let trait_name = &self.0.trait_data(trait_).name;
+ let trait_ref = projection_ty.trait_ref(self.0);
+ let trait_params = trait_ref.substitution.as_slice(Interner);
+ let self_ty = trait_ref.self_type_parameter(Interner);
+ write!(fmt, "<{:?} as {}", self_ty, trait_name)?;
+ if trait_params.len() > 1 {
+ write!(
+ fmt,
+ "<{}>",
+ trait_params[1..].iter().format_with(", ", |x, f| f(&format_args!("{:?}", x))),
+ )?;
+ }
+ write!(fmt, ">::{}", type_alias_data.name)?;
+
+ let proj_params_count = projection_ty.substitution.len(Interner) - trait_params.len();
+ let proj_params = &projection_ty.substitution.as_slice(Interner)[..proj_params_count];
+ if !proj_params.is_empty() {
write!(
fmt,
"<{}>",
- &params[1..].iter().format_with(", ", |x, f| f(&format_args!("{:?}", x))),
+ proj_params.iter().format_with(", ", |x, f| f(&format_args!("{:?}", x))),
)?;
}
- write!(fmt, ">::{}", type_alias_data.name)
+
+ Ok(())
}
pub(crate) fn debug_fn_def_id(
diff --git a/src/tools/rust-analyzer/crates/hir/Cargo.toml b/src/tools/rust-analyzer/crates/hir/Cargo.toml
index e1418de3c..f780e3f53 100644
--- a/src/tools/rust-analyzer/crates/hir/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index f5324208c..cbbcaebb4 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -117,7 +117,7 @@ pub use {
name::{known, Name},
ExpandResult, HirFileId, InFile, MacroFile, Origin,
},
- hir_ty::display::HirDisplay,
+ hir_ty::{display::HirDisplay, PointerCast, Safety},
};
// These are negative re-exports: pub using these names is forbidden, they
@@ -2995,7 +2995,16 @@ impl Type {
let callee = match self.ty.kind(Interner) {
TyKind::Closure(id, _) => Callee::Closure(*id),
TyKind::Function(_) => Callee::FnPtr,
- _ => Callee::Def(self.ty.callable_def(db)?),
+ TyKind::FnDef(..) => Callee::Def(self.ty.callable_def(db)?),
+ _ => {
+ let sig = hir_ty::callable_sig_from_fnonce(&self.ty, self.env.clone(), db)?;
+ return Some(Callable {
+ ty: self.clone(),
+ sig,
+ callee: Callee::Other,
+ is_bound_method: false,
+ });
+ }
};
let sig = self.ty.callable_sig(db)?;
@@ -3464,6 +3473,7 @@ enum Callee {
Def(CallableDefId),
Closure(ClosureId),
FnPtr,
+ Other,
}
pub enum CallableKind {
@@ -3472,6 +3482,8 @@ pub enum CallableKind {
TupleEnumVariant(Variant),
Closure,
FnPtr,
+ /// Some other type that implements `FnOnce`.
+ Other,
}
impl Callable {
@@ -3483,6 +3495,7 @@ impl Callable {
Def(CallableDefId::EnumVariantId(it)) => CallableKind::TupleEnumVariant(it.into()),
Closure(_) => CallableKind::Closure,
FnPtr => CallableKind::FnPtr,
+ Other => CallableKind::Other,
}
}
pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<ast::SelfParam> {
@@ -3637,6 +3650,28 @@ impl From<ItemInNs> for ScopeDef {
}
}
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub enum Adjust {
+ /// Go from ! to any type.
+ NeverToAny,
+ /// Dereference once, producing a place.
+ Deref(Option<OverloadedDeref>),
+ /// Take the address and produce either a `&` or `*` pointer.
+ Borrow(AutoBorrow),
+ Pointer(PointerCast),
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub enum AutoBorrow {
+ /// Converts from T to &T.
+ Ref(Mutability),
+ /// Converts from T to *T.
+ RawPtr(Mutability),
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub struct OverloadedDeref(pub Mutability);
+
pub trait HasVisibility {
fn visibility(&self, db: &dyn HirDatabase) -> Visibility;
fn is_visible_from(&self, db: &dyn HirDatabase, module: Module) -> bool {
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index 119ec3210..2e1f88ba0 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -29,9 +29,10 @@ use crate::{
db::HirDatabase,
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
source_analyzer::{resolve_hir_path, SourceAnalyzer},
- Access, BindingMode, BuiltinAttr, Callable, ConstParam, Crate, DeriveHelper, Field, Function,
- HasSource, HirFileId, Impl, InFile, Label, LifetimeParam, Local, Macro, Module, ModuleDef,
- Name, Path, ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
+ Access, Adjust, AutoBorrow, BindingMode, BuiltinAttr, Callable, ConstParam, Crate,
+ DeriveHelper, Field, Function, HasSource, HirFileId, Impl, InFile, Label, LifetimeParam, Local,
+ Macro, Module, ModuleDef, Name, OverloadedDeref, Path, ScopeDef, ToolModule, Trait, Type,
+ TypeAlias, TypeParam, VariantDef,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -333,9 +334,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
self.imp.resolve_trait(trait_)
}
- // FIXME: Figure out a nice interface to inspect adjustments
- pub fn is_implicit_reborrow(&self, expr: &ast::Expr) -> Option<Mutability> {
- self.imp.is_implicit_reborrow(expr)
+ pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjust>> {
+ self.imp.expr_adjustments(expr)
}
pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> {
@@ -1067,8 +1067,29 @@ impl<'db> SemanticsImpl<'db> {
}
}
- fn is_implicit_reborrow(&self, expr: &ast::Expr) -> Option<Mutability> {
- self.analyze(expr.syntax())?.is_implicit_reborrow(self.db, expr)
+ fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjust>> {
+ let mutability = |m| match m {
+ hir_ty::Mutability::Not => Mutability::Shared,
+ hir_ty::Mutability::Mut => Mutability::Mut,
+ };
+ self.analyze(expr.syntax())?.expr_adjustments(self.db, expr).map(|it| {
+ it.iter()
+ .map(|adjust| match adjust.kind {
+ hir_ty::Adjust::NeverToAny => Adjust::NeverToAny,
+ hir_ty::Adjust::Deref(Some(hir_ty::OverloadedDeref(m))) => {
+ Adjust::Deref(Some(OverloadedDeref(mutability(m))))
+ }
+ hir_ty::Adjust::Deref(None) => Adjust::Deref(None),
+ hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::RawPtr(m)) => {
+ Adjust::Borrow(AutoBorrow::RawPtr(mutability(m)))
+ }
+ hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::Ref(m)) => {
+ Adjust::Borrow(AutoBorrow::Ref(mutability(m)))
+ }
+ hir_ty::Adjust::Pointer(pc) => Adjust::Pointer(pc),
+ })
+ .collect()
+ })
}
fn type_of_expr(&self, expr: &ast::Expr) -> Option<TypeInfo> {
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 07bae2b38..91ea1c24d 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -38,8 +38,7 @@ use hir_ty::{
UnsafeExpr,
},
method_resolution::{self, lang_names_for_bin_op},
- Adjust, Adjustment, AutoBorrow, InferenceResult, Interner, Substitution, Ty, TyExt, TyKind,
- TyLoweringContext,
+ Adjustment, InferenceResult, Interner, Substitution, Ty, TyExt, TyKind, TyLoweringContext,
};
use itertools::Itertools;
use smallvec::SmallVec;
@@ -156,21 +155,14 @@ impl SourceAnalyzer {
Some(res)
}
- pub(crate) fn is_implicit_reborrow(
+ pub(crate) fn expr_adjustments(
&self,
db: &dyn HirDatabase,
expr: &ast::Expr,
- ) -> Option<Mutability> {
+ ) -> Option<&[Adjustment]> {
let expr_id = self.expr_id(db, expr)?;
let infer = self.infer.as_ref()?;
- let adjustments = infer.expr_adjustments.get(&expr_id)?;
- adjustments.windows(2).find_map(|slice| match slice {
- &[Adjustment {kind: Adjust::Deref(None), ..}, Adjustment {kind: Adjust::Borrow(AutoBorrow::Ref(m)), ..}] => Some(match m {
- hir_ty::Mutability::Mut => Mutability::Mut,
- hir_ty::Mutability::Not => Mutability::Shared,
- }),
- _ => None,
- })
+ infer.expr_adjustments.get(&expr_id).map(|v| &**v)
}
pub(crate) fn type_of_expr(
@@ -270,7 +262,7 @@ impl SourceAnalyzer {
let expr_id = self.expr_id(db, &call.clone().into())?;
let (f_in_trait, substs) = self.infer.as_ref()?.method_resolution(expr_id)?;
- Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, &substs))
+ Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs))
}
pub(crate) fn resolve_await_to_poll(
@@ -311,7 +303,7 @@ impl SourceAnalyzer {
// HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself
// doesn't have any generic parameters, so we skip building another subst for `poll()`.
let substs = hir_ty::TyBuilder::subst_for_def(db, future_trait, None).push(ty).build();
- Some(self.resolve_impl_method_or_trait_def(db, poll_fn, &substs))
+ Some(self.resolve_impl_method_or_trait_def(db, poll_fn, substs))
}
pub(crate) fn resolve_prefix_expr(
@@ -331,7 +323,7 @@ impl SourceAnalyzer {
// don't have any generic parameters, so we skip building another subst for the methods.
let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None).push(ty.clone()).build();
- Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+ Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
}
pub(crate) fn resolve_index_expr(
@@ -351,7 +343,7 @@ impl SourceAnalyzer {
.push(base_ty.clone())
.push(index_ty.clone())
.build();
- Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+ Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
}
pub(crate) fn resolve_bin_expr(
@@ -372,7 +364,7 @@ impl SourceAnalyzer {
.push(rhs.clone())
.build();
- Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+ Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
}
pub(crate) fn resolve_try_expr(
@@ -392,7 +384,7 @@ impl SourceAnalyzer {
// doesn't have any generic parameters, so we skip building another subst for `branch()`.
let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None).push(ty.clone()).build();
- Some(self.resolve_impl_method_or_trait_def(db, op_fn, &substs))
+ Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs))
}
pub(crate) fn resolve_field(
@@ -487,9 +479,9 @@ impl SourceAnalyzer {
let mut prefer_value_ns = false;
let resolved = (|| {
+ let infer = self.infer.as_deref()?;
if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
let expr_id = self.expr_id(db, &path_expr.into())?;
- let infer = self.infer.as_ref()?;
if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
let assoc = match assoc {
AssocItemId::FunctionId(f_in_trait) => {
@@ -497,9 +489,12 @@ impl SourceAnalyzer {
None => assoc,
Some(func_ty) => {
if let TyKind::FnDef(_fn_def, subs) = func_ty.kind(Interner) {
- self.resolve_impl_method(db, f_in_trait, subs)
- .map(AssocItemId::FunctionId)
- .unwrap_or(assoc)
+ self.resolve_impl_method_or_trait_def(
+ db,
+ f_in_trait,
+ subs.clone(),
+ )
+ .into()
} else {
assoc
}
@@ -520,18 +515,18 @@ impl SourceAnalyzer {
prefer_value_ns = true;
} else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
let pat_id = self.pat_id(&path_pat.into())?;
- if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
+ if let Some(assoc) = infer.assoc_resolutions_for_pat(pat_id) {
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
}
if let Some(VariantId::EnumVariantId(variant)) =
- self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
+ infer.variant_resolution_for_pat(pat_id)
{
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
}
} else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
let expr_id = self.expr_id(db, &rec_lit.into())?;
if let Some(VariantId::EnumVariantId(variant)) =
- self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
+ infer.variant_resolution_for_expr(expr_id)
{
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
}
@@ -541,8 +536,7 @@ impl SourceAnalyzer {
|| parent().and_then(ast::TupleStructPat::cast).map(ast::Pat::from);
if let Some(pat) = record_pat.or_else(tuple_struct_pat) {
let pat_id = self.pat_id(&pat)?;
- let variant_res_for_pat =
- self.infer.as_ref()?.variant_resolution_for_pat(pat_id);
+ let variant_res_for_pat = infer.variant_resolution_for_pat(pat_id);
if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat {
return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
}
@@ -780,37 +774,22 @@ impl SourceAnalyzer {
false
}
- fn resolve_impl_method(
+ fn resolve_impl_method_or_trait_def(
&self,
db: &dyn HirDatabase,
func: FunctionId,
- substs: &Substitution,
- ) -> Option<FunctionId> {
- let impled_trait = match func.lookup(db.upcast()).container {
- ItemContainerId::TraitId(trait_id) => trait_id,
- _ => return None,
- };
- if substs.is_empty(Interner) {
- return None;
- }
- let self_ty = substs.at(Interner, 0).ty(Interner)?;
+ substs: Substitution,
+ ) -> FunctionId {
let krate = self.resolver.krate();
- let trait_env = self.resolver.body_owner()?.as_generic_def_id().map_or_else(
+ let owner = match self.resolver.body_owner() {
+ Some(it) => it,
+ None => return func,
+ };
+ let env = owner.as_generic_def_id().map_or_else(
|| Arc::new(hir_ty::TraitEnvironment::empty(krate)),
|d| db.trait_environment(d),
);
-
- let fun_data = db.function_data(func);
- method_resolution::lookup_impl_method(self_ty, db, trait_env, impled_trait, &fun_data.name)
- }
-
- fn resolve_impl_method_or_trait_def(
- &self,
- db: &dyn HirDatabase,
- func: FunctionId,
- substs: &Substitution,
- ) -> FunctionId {
- self.resolve_impl_method(db, func, substs).unwrap_or(func)
+ method_resolution::lookup_impl_method(db, env, func, substs)
}
fn lang_trait_fn(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml b/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml
index 57a41f3d9..e781c0a01 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
index 60d1588a4..b273ebc85 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_config.rs
@@ -14,4 +14,5 @@ pub struct AssistConfig {
pub allowed: Option<Vec<AssistKind>>,
pub insert_use: InsertUseConfig,
pub prefer_no_std: bool,
+ pub assist_emit_must_use: bool,
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_type.rs
index bfa9759ec..b5f99726f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_type.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_explicit_type.rs
@@ -69,14 +69,14 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
let inferred_type = ty.display_source_code(ctx.db(), module.into()).ok()?;
acc.add(
AssistId("add_explicit_type", AssistKind::RefactorRewrite),
- format!("Insert explicit type `{}`", inferred_type),
+ format!("Insert explicit type `{inferred_type}`"),
pat_range,
|builder| match ascribed_ty {
Some(ascribed_ty) => {
builder.replace(ascribed_ty.syntax().text_range(), inferred_type);
}
None => {
- builder.insert(pat_range.end(), format!(": {}", inferred_type));
+ builder.insert(pat_range.end(), format!(": {inferred_type}"));
}
},
)
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 62cf5ab4f..2b3793659 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
@@ -196,6 +196,7 @@ trait Foo {
type Output;
const CONST: usize = 42;
+ const CONST_2: i32;
fn foo(&self);
fn bar(&self);
@@ -213,6 +214,7 @@ trait Foo {
type Output;
const CONST: usize = 42;
+ const CONST_2: i32;
fn foo(&self);
fn bar(&self);
@@ -226,7 +228,7 @@ impl Foo for S {
$0type Output;
- const CONST: usize = 42;
+ const CONST_2: i32;
fn foo(&self) {
todo!()
@@ -379,14 +381,14 @@ impl Foo for S {
r#"
mod foo {
pub struct Bar;
- trait Foo { fn foo(&self, bar: Bar); }
+ pub trait Foo { fn foo(&self, bar: Bar); }
}
struct S;
impl foo::Foo for S { $0 }"#,
r#"
mod foo {
pub struct Bar;
- trait Foo { fn foo(&self, bar: Bar); }
+ pub trait Foo { fn foo(&self, bar: Bar); }
}
struct S;
impl foo::Foo for S {
@@ -439,14 +441,14 @@ impl bar::Foo for S {
r#"
mod foo {
pub struct Bar<T>;
- trait Foo { fn foo(&self, bar: Bar<u32>); }
+ pub trait Foo { fn foo(&self, bar: Bar<u32>); }
}
struct S;
impl foo::Foo for S { $0 }"#,
r#"
mod foo {
pub struct Bar<T>;
- trait Foo { fn foo(&self, bar: Bar<u32>); }
+ pub trait Foo { fn foo(&self, bar: Bar<u32>); }
}
struct S;
impl foo::Foo for S {
@@ -464,14 +466,14 @@ impl foo::Foo for S {
r#"
mod foo {
pub struct Bar<T>;
- trait Foo<T> { fn foo(&self, bar: Bar<T>); }
+ pub trait Foo<T> { fn foo(&self, bar: Bar<T>); }
}
struct S;
impl foo::Foo<u32> for S { $0 }"#,
r#"
mod foo {
pub struct Bar<T>;
- trait Foo<T> { fn foo(&self, bar: Bar<T>); }
+ pub trait Foo<T> { fn foo(&self, bar: Bar<T>); }
}
struct S;
impl foo::Foo<u32> for S {
@@ -489,7 +491,7 @@ impl foo::Foo<u32> for S {
add_missing_impl_members,
r#"
mod foo {
- trait Foo<T> { fn foo(&self, bar: T); }
+ pub trait Foo<T> { fn foo(&self, bar: T); }
pub struct Param;
}
struct Param;
@@ -497,7 +499,7 @@ struct S;
impl foo::Foo<Param> for S { $0 }"#,
r#"
mod foo {
- trait Foo<T> { fn foo(&self, bar: T); }
+ pub trait Foo<T> { fn foo(&self, bar: T); }
pub struct Param;
}
struct Param;
@@ -518,7 +520,7 @@ impl foo::Foo<Param> for S {
mod foo {
pub struct Bar<T>;
impl Bar<T> { type Assoc = u32; }
- trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
+ pub trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
}
struct S;
impl foo::Foo for S { $0 }"#,
@@ -526,7 +528,7 @@ impl foo::Foo for S { $0 }"#,
mod foo {
pub struct Bar<T>;
impl Bar<T> { type Assoc = u32; }
- trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
+ pub trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
}
struct S;
impl foo::Foo for S {
@@ -545,7 +547,7 @@ impl foo::Foo for S {
mod foo {
pub struct Bar<T>;
pub struct Baz;
- trait Foo { fn foo(&self, bar: Bar<Baz>); }
+ pub trait Foo { fn foo(&self, bar: Bar<Baz>); }
}
struct S;
impl foo::Foo for S { $0 }"#,
@@ -553,7 +555,7 @@ impl foo::Foo for S { $0 }"#,
mod foo {
pub struct Bar<T>;
pub struct Baz;
- trait Foo { fn foo(&self, bar: Bar<Baz>); }
+ pub trait Foo { fn foo(&self, bar: Bar<Baz>); }
}
struct S;
impl foo::Foo for S {
@@ -571,14 +573,14 @@ impl foo::Foo for S {
r#"
mod foo {
pub trait Fn<Args> { type Output; }
- trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
+ pub trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
}
struct S;
impl foo::Foo for S { $0 }"#,
r#"
mod foo {
pub trait Fn<Args> { type Output; }
- trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
+ pub trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
}
struct S;
impl foo::Foo for S {
@@ -658,6 +660,7 @@ trait Foo {
type Output;
const CONST: usize = 42;
+ const CONST_2: i32;
fn valid(some: u32) -> bool { false }
fn foo(some: u32) -> bool;
@@ -669,13 +672,16 @@ trait Foo {
type Output;
const CONST: usize = 42;
+ const CONST_2: i32;
fn valid(some: u32) -> bool { false }
fn foo(some: u32) -> bool;
}
struct S;
impl Foo for S {
- $0fn valid(some: u32) -> bool { false }
+ $0const CONST: usize = 42;
+
+ fn valid(some: u32) -> bool { false }
}"#,
)
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs
index f858d7a15..89040a856 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_return_type.rs
@@ -35,16 +35,16 @@ pub(crate) fn add_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
match builder_edit_pos {
InsertOrReplace::Insert(insert_pos, needs_whitespace) => {
let preceeding_whitespace = if needs_whitespace { " " } else { "" };
- builder.insert(insert_pos, &format!("{}-> {} ", preceeding_whitespace, ty))
+ builder.insert(insert_pos, &format!("{preceeding_whitespace}-> {ty} "))
}
InsertOrReplace::Replace(text_range) => {
- builder.replace(text_range, &format!("-> {}", ty))
+ builder.replace(text_range, &format!("-> {ty}"))
}
}
if let FnType::Closure { wrap_expr: true } = fn_type {
cov_mark::hit!(wrap_closure_non_block_expr);
// `|x| x` becomes `|x| -> T x` which is invalid, so wrap it in a block
- builder.replace(tail_expr.syntax().text_range(), &format!("{{{}}}", tail_expr));
+ builder.replace(tail_expr.syntax().text_range(), &format!("{{{tail_expr}}}"));
}
},
)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs
index c0bf238db..acf82e4b2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_turbo_fish.rs
@@ -93,12 +93,13 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
builder.trigger_signature_help();
match ctx.config.snippet_cap {
Some(cap) => {
- let snip = format!("::<{}>", get_snippet_fish_head(number_of_arguments));
+ let fish_head = get_snippet_fish_head(number_of_arguments);
+ let snip = format!("::<{fish_head}>");
builder.insert_snippet(cap, ident.text_range().end(), snip)
}
None => {
let fish_head = std::iter::repeat("_").take(number_of_arguments).format(", ");
- let snip = format!("::<{}>", fish_head);
+ let snip = format!("::<{fish_head}>");
builder.insert(ident.text_range().end(), snip);
}
}
@@ -109,7 +110,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
/// This will create a snippet string with tabstops marked
fn get_snippet_fish_head(number_of_arguments: usize) -> String {
let mut fish_head = (1..number_of_arguments)
- .format_with("", |i, f| f(&format_args!("${{{}:_}}, ", i)))
+ .format_with("", |i, f| f(&format_args!("${{{i}:_}}, ")))
.to_string();
// tabstop 0 is a special case and always the last one
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 2853d1d1b..57cfa17cc 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
@@ -123,20 +123,20 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
let lhs_range = lhs.syntax().text_range();
let not_lhs = invert_boolean_expression(lhs);
- edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text()));
+ 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.syntax().text()));
+ 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.syntax().text());
+ edit.replace(term_range, not_term.to_string());
}
}
},
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
index 678dc877d..a689270bc 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/auto_import.rs
@@ -127,10 +127,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
.sort_by_key(|import| Reverse(relevance_score(ctx, import, current_module.as_ref())));
for import in proposed_imports {
+ let import_path = import.import_path;
+
acc.add_group(
&group_label,
AssistId("auto_import", AssistKind::QuickFix),
- format!("Import `{}`", import.import_path),
+ format!("Import `{import_path}`"),
range,
|builder| {
let scope = match scope.clone() {
@@ -138,7 +140,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
};
- insert_use(&scope, mod_path_to_ast(&import.import_path), &ctx.config.insert_use);
+ insert_use(&scope, mod_path_to_ast(&import_path), &ctx.config.insert_use);
},
);
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs
index f171dd81a..312cb65ab 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_block.rs
@@ -54,16 +54,17 @@ fn block_to_line(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
let indent_spaces = indentation.to_string();
let output = lines
- .map(|l| l.trim_start_matches(&indent_spaces))
- .map(|l| {
+ .map(|line| {
+ let line = line.trim_start_matches(&indent_spaces);
+
// Don't introduce trailing whitespace
- if l.is_empty() {
+ if line.is_empty() {
line_prefix.to_string()
} else {
- format!("{} {}", line_prefix, l.trim_start_matches(&indent_spaces))
+ format!("{line_prefix} {line}")
}
})
- .join(&format!("\n{}", indent_spaces));
+ .join(&format!("\n{indent_spaces}"));
edit.replace(target, output)
},
@@ -96,7 +97,7 @@ fn line_to_block(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
let block_prefix =
CommentKind { shape: CommentShape::Block, ..comment.kind() }.prefix();
- let output = format!("{}\n{}\n{}*/", block_prefix, block_comment_body, indentation);
+ let output = format!("{block_prefix}\n{block_comment_body}\n{indentation}*/");
edit.replace(target, output)
},
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs
index 9060696cd..ff2195f7e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_integer_literal.rs
@@ -32,19 +32,19 @@ pub(crate) fn convert_integer_literal(acc: &mut Assists, ctx: &AssistContext<'_>
}
let mut converted = match target_radix {
- Radix::Binary => format!("0b{:b}", value),
- Radix::Octal => format!("0o{:o}", value),
+ Radix::Binary => format!("0b{value:b}"),
+ Radix::Octal => format!("0o{value:o}"),
Radix::Decimal => value.to_string(),
- Radix::Hexadecimal => format!("0x{:X}", value),
+ Radix::Hexadecimal => format!("0x{value:X}"),
};
- let label = format!("Convert {} to {}{}", literal, converted, suffix.unwrap_or_default());
-
// Appends the type suffix back into the new literal if it exists.
if let Some(suffix) = suffix {
converted.push_str(suffix);
}
+ let label = format!("Convert {literal} to {converted}");
+
acc.add_group(
&group_id,
AssistId("convert_integer_literal", AssistKind::RefactorInline),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
index 95d11abe8..872b52c98 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_into_to_from.rs
@@ -86,9 +86,9 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) -
impl_.syntax().text_range(),
|builder| {
builder.replace(src_type.syntax().text_range(), dest_type.to_string());
- builder.replace(ast_trait.syntax().text_range(), format!("From<{}>", src_type));
+ builder.replace(ast_trait.syntax().text_range(), format!("From<{src_type}>"));
builder.replace(into_fn_return.syntax().text_range(), "-> Self");
- builder.replace(into_fn_params.syntax().text_range(), format!("(val: {})", src_type));
+ builder.replace(into_fn_params.syntax().text_range(), format!("(val: {src_type})"));
builder.replace(into_fn_name.syntax().text_range(), "from");
for s in selfs {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs
index 2cf370c09..80eecf4a0 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs
@@ -119,19 +119,19 @@ pub(crate) fn convert_for_loop_with_for_each(
{
// We have either "for x in &col" and col implements a method called iter
// or "for x in &mut col" and col implements a method called iter_mut
- format_to!(buf, "{}.{}()", expr_behind_ref, method);
+ format_to!(buf, "{expr_behind_ref}.{method}()");
} else if let ast::Expr::RangeExpr(..) = iterable {
// range expressions need to be parenthesized for the syntax to be correct
- format_to!(buf, "({})", iterable);
+ format_to!(buf, "({iterable})");
} else if impls_core_iter(&ctx.sema, &iterable) {
- format_to!(buf, "{}", iterable);
+ format_to!(buf, "{iterable}");
} else if let ast::Expr::RefExpr(_) = iterable {
- format_to!(buf, "({}).into_iter()", iterable);
+ format_to!(buf, "({iterable}).into_iter()");
} else {
- format_to!(buf, "{}.into_iter()", iterable);
+ format_to!(buf, "{iterable}.into_iter()");
}
- format_to!(buf, ".for_each(|{}| {});", pat, body);
+ format_to!(buf, ".for_each(|{pat}| {body});");
builder.replace(for_loop.syntax().text_range(), buf)
},
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
index 00095de25..c82a3b530 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
@@ -80,7 +80,7 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
.map(
|(ident, ismut)| {
if *ismut && addmut {
- format!("mut {}", ident)
+ format!("mut {ident}")
} else {
ident.to_string()
}
@@ -93,7 +93,7 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
} else if binders.len() == 1 {
vars
} else {
- format!("({})", vars)
+ format!("({vars})")
}
}
@@ -153,7 +153,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
let only_expr = let_else_block.statements().next().is_none();
let branch2 = match &let_else_block.tail_expr() {
- Some(tail) if only_expr => format!("{},", tail.syntax().text()),
+ Some(tail) if only_expr => format!("{tail},"),
_ => let_else_block.syntax().text().to_string(),
};
let replace = if binders.is_empty() {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs
new file mode 100644
index 000000000..5bf04a3ad
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_match_to_let_else.rs
@@ -0,0 +1,413 @@
+use ide_db::defs::{Definition, NameRefClass};
+use syntax::{
+ ast::{self, HasName},
+ ted, AstNode, SyntaxNode,
+};
+
+use crate::{
+ assist_context::{AssistContext, Assists},
+ AssistId, AssistKind,
+};
+
+// Assist: convert_match_to_let_else
+//
+// Converts let statement with match initializer to let-else statement.
+//
+// ```
+// # //- minicore: option
+// fn foo(opt: Option<()>) {
+// let val = $0match opt {
+// Some(it) => it,
+// None => return,
+// };
+// }
+// ```
+// ->
+// ```
+// fn foo(opt: Option<()>) {
+// let Some(val) = opt else { return };
+// }
+// ```
+pub(crate) fn convert_match_to_let_else(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+ let let_stmt: ast::LetStmt = ctx.find_node_at_offset()?;
+ let binding = find_binding(let_stmt.pat()?)?;
+
+ let initializer = match let_stmt.initializer() {
+ Some(ast::Expr::MatchExpr(it)) => it,
+ _ => return None,
+ };
+ let initializer_expr = initializer.expr()?;
+
+ let (extracting_arm, diverging_arm) = match find_arms(ctx, &initializer) {
+ Some(it) => it,
+ None => return None,
+ };
+ if extracting_arm.guard().is_some() {
+ cov_mark::hit!(extracting_arm_has_guard);
+ return None;
+ }
+
+ let diverging_arm_expr = diverging_arm.expr()?;
+ let extracting_arm_pat = extracting_arm.pat()?;
+ let extracted_variable = find_extracted_variable(ctx, &extracting_arm)?;
+
+ acc.add(
+ AssistId("convert_match_to_let_else", AssistKind::RefactorRewrite),
+ "Convert match to let-else",
+ let_stmt.syntax().text_range(),
+ |builder| {
+ let extracting_arm_pat = rename_variable(&extracting_arm_pat, extracted_variable, binding);
+ builder.replace(
+ let_stmt.syntax().text_range(),
+ format!("let {extracting_arm_pat} = {initializer_expr} else {{ {diverging_arm_expr} }};")
+ )
+ },
+ )
+}
+
+// Given a pattern, find the name introduced to the surrounding scope.
+fn find_binding(pat: ast::Pat) -> Option<ast::IdentPat> {
+ if let ast::Pat::IdentPat(ident) = pat {
+ Some(ident)
+ } else {
+ None
+ }
+}
+
+// Given a match expression, find extracting and diverging arms.
+fn find_arms(
+ ctx: &AssistContext<'_>,
+ match_expr: &ast::MatchExpr,
+) -> Option<(ast::MatchArm, ast::MatchArm)> {
+ let arms = match_expr.match_arm_list()?.arms().collect::<Vec<_>>();
+ if arms.len() != 2 {
+ return None;
+ }
+
+ let mut extracting = None;
+ let mut diverging = None;
+ for arm in arms {
+ if ctx.sema.type_of_expr(&arm.expr().unwrap()).unwrap().original().is_never() {
+ diverging = Some(arm);
+ } else {
+ extracting = Some(arm);
+ }
+ }
+
+ match (extracting, diverging) {
+ (Some(extracting), Some(diverging)) => Some((extracting, diverging)),
+ _ => {
+ cov_mark::hit!(non_diverging_match);
+ None
+ }
+ }
+}
+
+// Given an extracting arm, find the extracted variable.
+fn find_extracted_variable(ctx: &AssistContext<'_>, arm: &ast::MatchArm) -> Option<ast::Name> {
+ match arm.expr()? {
+ ast::Expr::PathExpr(path) => {
+ let name_ref = path.syntax().descendants().find_map(ast::NameRef::cast)?;
+ match NameRefClass::classify(&ctx.sema, &name_ref)? {
+ NameRefClass::Definition(Definition::Local(local)) => {
+ let source = local.source(ctx.db()).value.left()?;
+ Some(source.name()?)
+ }
+ _ => None,
+ }
+ }
+ _ => {
+ cov_mark::hit!(extracting_arm_is_not_an_identity_expr);
+ return None;
+ }
+ }
+}
+
+// Rename `extracted` with `binding` in `pat`.
+fn rename_variable(pat: &ast::Pat, extracted: ast::Name, binding: ast::IdentPat) -> SyntaxNode {
+ let syntax = pat.syntax().clone_for_update();
+ let extracted_syntax = syntax.covering_element(extracted.syntax().text_range());
+
+ // If `extracted` variable is a record field, we should rename it to `binding`,
+ // otherwise we just need to replace `extracted` with `binding`.
+
+ if let Some(record_pat_field) = extracted_syntax.ancestors().find_map(ast::RecordPatField::cast)
+ {
+ if let Some(name_ref) = record_pat_field.field_name() {
+ ted::replace(
+ record_pat_field.syntax(),
+ ast::make::record_pat_field(ast::make::name_ref(&name_ref.text()), binding.into())
+ .syntax()
+ .clone_for_update(),
+ );
+ }
+ } else {
+ ted::replace(extracted_syntax, binding.syntax().clone_for_update());
+ }
+
+ syntax
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::tests::{check_assist, check_assist_not_applicable};
+
+ use super::*;
+
+ #[test]
+ fn should_not_be_applicable_for_non_diverging_match() {
+ cov_mark::check!(non_diverging_match);
+ check_assist_not_applicable(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+fn foo(opt: Option<()>) {
+ let val = $0match opt {
+ Some(it) => it,
+ None => (),
+ };
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn should_not_be_applicable_if_extracting_arm_is_not_an_identity_expr() {
+ cov_mark::check_count!(extracting_arm_is_not_an_identity_expr, 2);
+ check_assist_not_applicable(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+fn foo(opt: Option<i32>) {
+ let val = $0match opt {
+ Some(it) => it + 1,
+ None => return,
+ };
+}
+"#,
+ );
+
+ check_assist_not_applicable(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+fn foo(opt: Option<()>) {
+ let val = $0match opt {
+ Some(it) => {
+ let _ = 1 + 1;
+ it
+ },
+ None => return,
+ };
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn should_not_be_applicable_if_extracting_arm_has_guard() {
+ cov_mark::check!(extracting_arm_has_guard);
+ check_assist_not_applicable(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+fn foo(opt: Option<()>) {
+ let val = $0match opt {
+ Some(it) if 2 > 1 => it,
+ None => return,
+ };
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn basic_pattern() {
+ check_assist(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+fn foo(opt: Option<()>) {
+ let val = $0match opt {
+ Some(it) => it,
+ None => return,
+ };
+}
+ "#,
+ r#"
+fn foo(opt: Option<()>) {
+ let Some(val) = opt else { return };
+}
+ "#,
+ );
+ }
+
+ #[test]
+ fn keeps_modifiers() {
+ check_assist(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+fn foo(opt: Option<()>) {
+ let ref mut val = $0match opt {
+ Some(it) => it,
+ None => return,
+ };
+}
+ "#,
+ r#"
+fn foo(opt: Option<()>) {
+ let Some(ref mut val) = opt else { return };
+}
+ "#,
+ );
+ }
+
+ #[test]
+ fn nested_pattern() {
+ check_assist(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option, result
+fn foo(opt: Option<Result<()>>) {
+ let val = $0match opt {
+ Some(Ok(it)) => it,
+ _ => return,
+ };
+}
+ "#,
+ r#"
+fn foo(opt: Option<Result<()>>) {
+ let Some(Ok(val)) = opt else { return };
+}
+ "#,
+ );
+ }
+
+ #[test]
+ fn works_with_any_diverging_block() {
+ check_assist(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+fn foo(opt: Option<()>) {
+ loop {
+ let val = $0match opt {
+ Some(it) => it,
+ None => break,
+ };
+ }
+}
+ "#,
+ r#"
+fn foo(opt: Option<()>) {
+ loop {
+ let Some(val) = opt else { break };
+ }
+}
+ "#,
+ );
+
+ check_assist(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+fn foo(opt: Option<()>) {
+ loop {
+ let val = $0match opt {
+ Some(it) => it,
+ None => continue,
+ };
+ }
+}
+ "#,
+ r#"
+fn foo(opt: Option<()>) {
+ loop {
+ let Some(val) = opt else { continue };
+ }
+}
+ "#,
+ );
+
+ check_assist(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+fn panic() -> ! {}
+
+fn foo(opt: Option<()>) {
+ loop {
+ let val = $0match opt {
+ Some(it) => it,
+ None => panic(),
+ };
+ }
+}
+ "#,
+ r#"
+fn panic() -> ! {}
+
+fn foo(opt: Option<()>) {
+ loop {
+ let Some(val) = opt else { panic() };
+ }
+}
+ "#,
+ );
+ }
+
+ #[test]
+ fn struct_pattern() {
+ check_assist(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+fn foo(opt: Option<Point>) {
+ let val = $0match opt {
+ Some(Point { x: 0, y }) => y,
+ _ => return,
+ };
+}
+ "#,
+ r#"
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+fn foo(opt: Option<Point>) {
+ let Some(Point { x: 0, y: val }) = opt else { return };
+}
+ "#,
+ );
+ }
+
+ #[test]
+ fn renames_whole_binding() {
+ check_assist(
+ convert_match_to_let_else,
+ r#"
+//- minicore: option
+fn foo(opt: Option<i32>) -> Option<i32> {
+ let val = $0match opt {
+ it @ Some(42) => it,
+ _ => return None,
+ };
+ val
+}
+ "#,
+ r#"
+fn foo(opt: Option<i32>) -> Option<i32> {
+ let val @ Some(42) = opt else { return None };
+ val
+}
+ "#,
+ );
+ }
+}
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 cb75619ce..b97be34c5 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
@@ -129,32 +129,15 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext<'
}
Some((path, bound_ident)) => {
// If-let.
- let match_expr = {
- let happy_arm = {
- let pat = make::tuple_struct_pat(
- path,
- once(make::ext::simple_ident_pat(make::name("it")).into()),
- );
- let expr = {
- let path = make::ext::ident_path("it");
- make::expr_path(path)
- };
- make::match_arm(once(pat.into()), None, expr)
- };
-
- let sad_arm = make::match_arm(
- // FIXME: would be cool to use `None` or `Err(_)` if appropriate
- once(make::wildcard_pat().into()),
- None,
- early_expression,
- );
-
- make::expr_match(cond_expr, make::match_arm_list(vec![happy_arm, sad_arm]))
- };
-
- let let_stmt = make::let_stmt(bound_ident, None, Some(match_expr));
- let let_stmt = let_stmt.indent(if_indent_level);
- let_stmt.syntax().clone_for_update()
+ let pat = make::tuple_struct_pat(path, once(bound_ident));
+ let let_else_stmt = make::let_else_stmt(
+ pat.into(),
+ None,
+ cond_expr,
+ ast::make::tail_only_block_expr(early_expression),
+ );
+ let let_else_stmt = let_else_stmt.indent(if_indent_level);
+ let_else_stmt.syntax().clone_for_update()
}
};
@@ -238,10 +221,7 @@ fn main(n: Option<String>) {
r#"
fn main(n: Option<String>) {
bar();
- let n = match n {
- Some(it) => it,
- _ => return,
- };
+ let Some(n) = n else { return };
foo(n);
// comment
@@ -264,10 +244,7 @@ fn main() {
"#,
r#"
fn main() {
- let x = match Err(92) {
- Ok(it) => it,
- _ => return,
- };
+ let Ok(x) = Err(92) else { return };
foo(x);
}
"#,
@@ -292,10 +269,7 @@ fn main(n: Option<String>) {
r#"
fn main(n: Option<String>) {
bar();
- let n = match n {
- Some(it) => it,
- _ => return,
- };
+ let Some(n) = n else { return };
foo(n);
// comment
@@ -323,10 +297,7 @@ fn main(n: Option<String>) {
r#"
fn main(n: Option<String>) {
bar();
- let mut n = match n {
- Some(it) => it,
- _ => return,
- };
+ let Some(mut n) = n else { return };
foo(n);
// comment
@@ -354,10 +325,7 @@ fn main(n: Option<&str>) {
r#"
fn main(n: Option<&str>) {
bar();
- let ref n = match n {
- Some(it) => it,
- _ => return,
- };
+ let Some(ref n) = n else { return };
foo(n);
// comment
@@ -412,10 +380,7 @@ fn main() {
r#"
fn main() {
while true {
- let n = match n {
- Some(it) => it,
- _ => continue,
- };
+ let Some(n) = n else { continue };
foo(n);
bar();
}
@@ -469,10 +434,7 @@ fn main() {
r#"
fn main() {
loop {
- let n = match n {
- Some(it) => it,
- _ => continue,
- };
+ let Some(n) = n else { continue };
foo(n);
bar();
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
index d8f522708..92e091fca 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
@@ -226,7 +226,13 @@ fn edit_field_references(
}
fn generate_names(fields: impl Iterator<Item = ast::TupleField>) -> Vec<ast::Name> {
- fields.enumerate().map(|(i, _)| ast::make::name(&format!("field{}", i + 1))).collect()
+ fields
+ .enumerate()
+ .map(|(i, _)| {
+ let idx = i + 1;
+ ast::make::name(&format!("field{idx}"))
+ })
+ .collect()
}
#[cfg(test)]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
index 54a7f480a..b1b0f587c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs
@@ -58,16 +58,16 @@ pub(crate) fn convert_two_arm_bool_match_to_matches_macro(
target_range,
|builder| {
let mut arm_str = String::new();
- if let Some(ref pat) = first_arm.pat() {
+ if let Some(pat) = &first_arm.pat() {
arm_str += &pat.to_string();
}
- if let Some(ref guard) = first_arm.guard() {
- arm_str += &format!(" {}", &guard.to_string());
+ if let Some(guard) = &first_arm.guard() {
+ arm_str += &format!(" {guard}");
}
if invert_matches {
- builder.replace(target_range, format!("!matches!({}, {})", expr, arm_str));
+ builder.replace(target_range, format!("!matches!({expr}, {arm_str})"));
} else {
- builder.replace(target_range, format!("matches!({}, {})", expr, arm_str));
+ builder.replace(target_range, format!("matches!({expr}, {arm_str})"));
}
},
)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
index dc581ff3b..31c2ce7c1 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
@@ -133,7 +133,7 @@ fn generate_name(
_usages: &Option<UsageSearchResult>,
) -> String {
// FIXME: detect if name already used
- format!("_{}", index)
+ format!("_{index}")
}
enum RefType {
@@ -168,12 +168,12 @@ fn edit_tuple_assignment(
let add_cursor = |text: &str| {
// place cursor on first tuple item
let first_tuple = &data.field_names[0];
- text.replacen(first_tuple, &format!("$0{}", first_tuple), 1)
+ text.replacen(first_tuple, &format!("$0{first_tuple}"), 1)
};
// with sub_pattern: keep original tuple and add subpattern: `tup @ (_0, _1)`
if in_sub_pattern {
- let text = format!(" @ {}", tuple_pat);
+ let text = format!(" @ {tuple_pat}");
match ctx.config.snippet_cap {
Some(cap) => {
let snip = add_cursor(&text);
@@ -314,9 +314,9 @@ struct RefData {
impl RefData {
fn format(&self, field_name: &str) -> String {
match (self.needs_deref, self.needs_parentheses) {
- (true, true) => format!("(*{})", field_name),
- (true, false) => format!("*{}", field_name),
- (false, true) => format!("({})", field_name),
+ (true, true) => format!("(*{field_name})"),
+ (true, false) => format!("*{field_name}"),
+ (false, true) => format!("({field_name})"),
(false, false) => field_name.to_string(),
}
}
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 d6c8ea785..c1e2f19ab 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
@@ -109,8 +109,6 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
let params =
body.extracted_function_params(ctx, &container_info, locals_used.iter().copied());
- let extracted_from_trait_impl = body.extracted_from_trait_impl();
-
let name = make_function_name(&semantics_scope);
let fun = Function {
@@ -129,8 +127,11 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
builder.replace(target_range, make_call(ctx, &fun, old_indent));
+ let has_impl_wrapper =
+ insert_after.ancestors().any(|a| a.kind() == SyntaxKind::IMPL && a != insert_after);
+
let fn_def = match fun.self_param_adt(ctx) {
- Some(adt) if extracted_from_trait_impl => {
+ Some(adt) if anchor == Anchor::Method && !has_impl_wrapper => {
let fn_def = format_function(ctx, module, &fun, old_indent, new_indent + 1);
generate_impl_text(&adt, &fn_def).replace("{\n\n", "{")
}
@@ -181,7 +182,7 @@ fn make_function_name(semantics_scope: &hir::SemanticsScope<'_>) -> ast::NameRef
let mut counter = 0;
while names_in_scope.contains(&name) {
counter += 1;
- name = format!("{}{}", &default_name, counter)
+ name = format!("{default_name}{counter}")
}
make::name_ref(&name)
}
@@ -272,7 +273,7 @@ enum FunType {
}
/// Where to put extracted function definition
-#[derive(Debug)]
+#[derive(Debug, Eq, PartialEq, Clone, Copy)]
enum Anchor {
/// Extract free function and put right after current top-level function
Freestanding,
@@ -1245,6 +1246,14 @@ fn node_to_insert_after(body: &FunctionBody, anchor: Anchor) -> Option<SyntaxNod
while let Some(next_ancestor) = ancestors.next() {
match next_ancestor.kind() {
SyntaxKind::SOURCE_FILE => break,
+ SyntaxKind::IMPL => {
+ if body.extracted_from_trait_impl() && matches!(anchor, Anchor::Method) {
+ let impl_node = find_non_trait_impl(&next_ancestor);
+ if let target_node @ Some(_) = impl_node.as_ref().and_then(last_impl_member) {
+ return target_node;
+ }
+ }
+ }
SyntaxKind::ITEM_LIST if !matches!(anchor, Anchor::Freestanding) => continue,
SyntaxKind::ITEM_LIST => {
if ancestors.peek().map(SyntaxNode::kind) == Some(SyntaxKind::MODULE) {
@@ -1265,6 +1274,29 @@ fn node_to_insert_after(body: &FunctionBody, anchor: Anchor) -> Option<SyntaxNod
last_ancestor
}
+fn find_non_trait_impl(trait_impl: &SyntaxNode) -> Option<ast::Impl> {
+ let as_impl = ast::Impl::cast(trait_impl.clone())?;
+ let impl_type = Some(impl_type_name(&as_impl)?);
+
+ let sibblings = trait_impl.parent()?.children();
+ sibblings
+ .filter_map(ast::Impl::cast)
+ .find(|s| impl_type_name(s) == impl_type && !is_trait_impl(s))
+}
+
+fn last_impl_member(impl_node: &ast::Impl) -> Option<SyntaxNode> {
+ let last_child = impl_node.assoc_item_list()?.assoc_items().last()?;
+ Some(last_child.syntax().clone())
+}
+
+fn is_trait_impl(node: &ast::Impl) -> bool {
+ node.trait_().is_some()
+}
+
+fn impl_type_name(impl_node: &ast::Impl) -> Option<String> {
+ Some(impl_node.self_ty()?.to_string())
+}
+
fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> String {
let ret_ty = fun.return_type(ctx);
@@ -1291,19 +1323,23 @@ fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> St
match fun.outliving_locals.as_slice() {
[] => {}
[var] => {
- format_to!(buf, "let {}{} = ", mut_modifier(var), var.local.name(ctx.db()))
+ let modifier = mut_modifier(var);
+ let name = var.local.name(ctx.db());
+ format_to!(buf, "let {modifier}{name} = ")
}
vars => {
buf.push_str("let (");
let bindings = vars.iter().format_with(", ", |local, f| {
- f(&format_args!("{}{}", mut_modifier(local), local.local.name(ctx.db())))
+ let modifier = mut_modifier(local);
+ let name = local.local.name(ctx.db());
+ f(&format_args!("{modifier}{name}"))
});
- format_to!(buf, "{}", bindings);
+ format_to!(buf, "{bindings}");
buf.push_str(") = ");
}
}
- format_to!(buf, "{}", expr);
+ format_to!(buf, "{expr}");
let insert_comma = fun
.body
.parent()
@@ -1447,6 +1483,8 @@ fn format_function(
new_indent: IndentLevel,
) -> String {
let mut fn_def = String::new();
+
+ let fun_name = &fun.name;
let params = fun.make_param_list(ctx, module);
let ret_ty = fun.make_ret_ty(ctx, module);
let body = make_body(ctx, old_indent, new_indent, fun);
@@ -1454,42 +1492,28 @@ fn format_function(
let async_kw = if fun.control_flow.is_async { "async " } else { "" };
let unsafe_kw = if fun.control_flow.is_unsafe { "unsafe " } else { "" };
let (generic_params, where_clause) = make_generic_params_and_where_clause(ctx, fun);
+
+ format_to!(fn_def, "\n\n{new_indent}{const_kw}{async_kw}{unsafe_kw}");
match ctx.config.snippet_cap {
- Some(_) => format_to!(
- fn_def,
- "\n\n{}{}{}{}fn $0{}",
- new_indent,
- const_kw,
- async_kw,
- unsafe_kw,
- fun.name,
- ),
- None => format_to!(
- fn_def,
- "\n\n{}{}{}{}fn {}",
- new_indent,
- const_kw,
- async_kw,
- unsafe_kw,
- fun.name,
- ),
+ Some(_) => format_to!(fn_def, "fn $0{fun_name}"),
+ None => format_to!(fn_def, "fn {fun_name}"),
}
if let Some(generic_params) = generic_params {
- format_to!(fn_def, "{}", generic_params);
+ format_to!(fn_def, "{generic_params}");
}
- format_to!(fn_def, "{}", params);
+ format_to!(fn_def, "{params}");
if let Some(ret_ty) = ret_ty {
- format_to!(fn_def, " {}", ret_ty);
+ format_to!(fn_def, " {ret_ty}");
}
if let Some(where_clause) = where_clause {
- format_to!(fn_def, " {}", where_clause);
+ format_to!(fn_def, " {where_clause}");
}
- format_to!(fn_def, " {}", body);
+ format_to!(fn_def, " {body}");
fn_def
}
@@ -5060,6 +5084,236 @@ impl Struct {
}
#[test]
+ fn extract_method_from_trait_with_existing_non_empty_impl_block() {
+ check_assist(
+ extract_function,
+ r#"
+struct Struct(i32);
+trait Trait {
+ fn bar(&self) -> i32;
+}
+
+impl Struct {
+ fn foo() {}
+}
+
+impl Trait for Struct {
+ fn bar(&self) -> i32 {
+ $0self.0 + 2$0
+ }
+}
+"#,
+ r#"
+struct Struct(i32);
+trait Trait {
+ fn bar(&self) -> i32;
+}
+
+impl Struct {
+ fn foo() {}
+
+ fn $0fun_name(&self) -> i32 {
+ self.0 + 2
+ }
+}
+
+impl Trait for Struct {
+ fn bar(&self) -> i32 {
+ self.fun_name()
+ }
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn extract_function_from_trait_with_existing_non_empty_impl_block() {
+ check_assist(
+ extract_function,
+ r#"
+struct Struct(i32);
+trait Trait {
+ fn bar(&self) -> i32;
+}
+
+impl Struct {
+ fn foo() {}
+}
+
+impl Trait for Struct {
+ fn bar(&self) -> i32 {
+ let three_squared = $03 * 3$0;
+ self.0 + three_squared
+ }
+}
+"#,
+ r#"
+struct Struct(i32);
+trait Trait {
+ fn bar(&self) -> i32;
+}
+
+impl Struct {
+ fn foo() {}
+}
+
+impl Trait for Struct {
+ fn bar(&self) -> i32 {
+ let three_squared = fun_name();
+ self.0 + three_squared
+ }
+}
+
+fn $0fun_name() -> i32 {
+ 3 * 3
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn extract_method_from_trait_with_multiple_existing_impl_blocks() {
+ check_assist(
+ extract_function,
+ r#"
+struct Struct(i32);
+struct StructBefore(i32);
+struct StructAfter(i32);
+trait Trait {
+ fn bar(&self) -> i32;
+}
+
+impl StructBefore {
+ fn foo(){}
+}
+
+impl Struct {
+ fn foo(){}
+}
+
+impl StructAfter {
+ fn foo(){}
+}
+
+impl Trait for Struct {
+ fn bar(&self) -> i32 {
+ $0self.0 + 2$0
+ }
+}
+"#,
+ r#"
+struct Struct(i32);
+struct StructBefore(i32);
+struct StructAfter(i32);
+trait Trait {
+ fn bar(&self) -> i32;
+}
+
+impl StructBefore {
+ fn foo(){}
+}
+
+impl Struct {
+ fn foo(){}
+
+ fn $0fun_name(&self) -> i32 {
+ self.0 + 2
+ }
+}
+
+impl StructAfter {
+ fn foo(){}
+}
+
+impl Trait for Struct {
+ fn bar(&self) -> i32 {
+ self.fun_name()
+ }
+}
+"#,
+ )
+ }
+
+ #[test]
+ fn extract_method_from_trait_with_multiple_existing_trait_impl_blocks() {
+ check_assist(
+ extract_function,
+ r#"
+struct Struct(i32);
+trait Trait {
+ fn bar(&self) -> i32;
+}
+trait TraitBefore {
+ fn before(&self) -> i32;
+}
+trait TraitAfter {
+ fn after(&self) -> i32;
+}
+
+impl TraitBefore for Struct {
+ fn before(&self) -> i32 {
+ 42
+ }
+}
+
+impl Struct {
+ fn foo(){}
+}
+
+impl TraitAfter for Struct {
+ fn after(&self) -> i32 {
+ 42
+ }
+}
+
+impl Trait for Struct {
+ fn bar(&self) -> i32 {
+ $0self.0 + 2$0
+ }
+}
+"#,
+ r#"
+struct Struct(i32);
+trait Trait {
+ fn bar(&self) -> i32;
+}
+trait TraitBefore {
+ fn before(&self) -> i32;
+}
+trait TraitAfter {
+ fn after(&self) -> i32;
+}
+
+impl TraitBefore for Struct {
+ fn before(&self) -> i32 {
+ 42
+ }
+}
+
+impl Struct {
+ fn foo(){}
+
+ fn $0fun_name(&self) -> i32 {
+ self.0 + 2
+ }
+}
+
+impl TraitAfter for Struct {
+ fn after(&self) -> i32 {
+ 42
+ }
+}
+
+impl Trait for Struct {
+ fn bar(&self) -> i32 {
+ self.fun_name()
+ }
+}
+"#,
+ )
+ }
+
+ #[test]
fn closure_arguments() {
check_assist(
extract_function,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
index 897980c66..56834394a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_module.rs
@@ -127,7 +127,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
for item in items_to_be_processed {
let item = item.indent(IndentLevel(1));
let mut indented_item = String::new();
- format_to!(indented_item, "{}{}", new_item_indent, item.to_string());
+ format_to!(indented_item, "{new_item_indent}{item}");
body_items.push(indented_item);
}
@@ -137,30 +137,28 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
let mut impl_body_def = String::new();
if let Some(self_ty) = impl_.self_ty() {
- format_to!(
- impl_body_def,
- "{}impl {} {{\n{}\n{}}}",
- old_item_indent + 1,
- self_ty.to_string(),
- body,
- old_item_indent + 1
- );
-
+ {
+ let impl_indent = old_item_indent + 1;
+ format_to!(
+ impl_body_def,
+ "{impl_indent}impl {self_ty} {{\n{body}\n{impl_indent}}}",
+ );
+ }
body = impl_body_def;
// Add the import for enum/struct corresponding to given impl block
module.make_use_stmt_of_node_with_super(self_ty.syntax());
for item in module.use_items {
- let mut indented_item = String::new();
- format_to!(indented_item, "{}{}", old_item_indent + 1, item.to_string());
- body = format!("{}\n\n{}", indented_item, body);
+ let item_indent = old_item_indent + 1;
+ body = format!("{item_indent}{item}\n\n{body}");
}
}
}
let mut module_def = String::new();
- format_to!(module_def, "mod {} {{\n{}\n{}}}", module.name, body, old_item_indent);
+ let module_name = module.name;
+ format_to!(module_def, "mod {module_name} {{\n{body}\n{old_item_indent}}}");
let mut usages_to_be_updated_for_curr_file = vec![];
for usages_to_be_updated_for_file in usages_to_be_processed {
@@ -199,7 +197,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
builder.delete(range);
}
- builder.insert(impl_.syntax().text_range().end(), format!("\n\n{}", module_def));
+ builder.insert(impl_.syntax().text_range().end(), format!("\n\n{module_def}"));
} else {
builder.replace(module.text_range, module_def)
}
@@ -343,9 +341,10 @@ impl Module {
&& !self.text_range.contains_range(desc.text_range())
{
if let Some(name_ref) = ast::NameRef::cast(desc) {
+ let mod_name = self.name;
return Some((
name_ref.syntax().text_range(),
- format!("{}::{}", self.name, name_ref),
+ format!("{mod_name}::{name_ref}"),
));
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
index 970e948df..b4e10667b 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -296,10 +296,14 @@ fn create_struct_def(
fn update_variant(variant: &ast::Variant, generics: Option<ast::GenericParamList>) -> Option<()> {
let name = variant.name()?;
- let ty = generics
+ let generic_args = generics
.filter(|generics| generics.generic_params().count() > 0)
- .map(|generics| make::ty(&format!("{}{}", &name.text(), generics.to_generic_args())))
- .unwrap_or_else(|| make::ty(&name.text()));
+ .map(|generics| generics.to_generic_args());
+ // FIXME: replace with a `ast::make` constructor
+ let ty = match generic_args {
+ Some(generic_args) => make::ty(&format!("{name}{generic_args}")),
+ None => make::ty(&name.text()),
+ };
// change from a record to a tuple field list
let tuple_field = make::tuple_field(None, ty);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
index 03aa8601d..3116935fc 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_type_alias.rs
@@ -1,8 +1,7 @@
use either::Either;
use ide_db::syntax_helpers::node_ext::walk_ty;
-use itertools::Itertools;
use syntax::{
- ast::{self, edit::IndentLevel, AstNode, HasGenericParams, HasName},
+ ast::{self, edit::IndentLevel, make, AstNode, HasGenericParams, HasName},
match_ast,
};
@@ -64,41 +63,29 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
known_generics.extend(it.generic_params());
}
let generics = collect_used_generics(&ty, &known_generics);
+ let generic_params =
+ generics.map(|it| make::generic_param_list(it.into_iter().cloned()));
- let replacement = if !generics.is_empty() {
- format!(
- "Type<{}>",
- generics.iter().format_with(", ", |generic, f| {
- match generic {
- ast::GenericParam::ConstParam(cp) => f(&cp.name().unwrap()),
- ast::GenericParam::LifetimeParam(lp) => f(&lp.lifetime().unwrap()),
- ast::GenericParam::TypeParam(tp) => f(&tp.name().unwrap()),
- }
- })
- )
- } else {
- String::from("Type")
- };
+ let ty_args = generic_params
+ .as_ref()
+ .map_or(String::new(), |it| it.to_generic_args().to_string());
+ let replacement = format!("Type{ty_args}");
builder.replace(target, replacement);
let indent = IndentLevel::from_node(node);
- let generics = if !generics.is_empty() {
- format!("<{}>", generics.iter().format(", "))
- } else {
- String::new()
- };
+ let generic_params = generic_params.map_or(String::new(), |it| it.to_string());
match ctx.config.snippet_cap {
Some(cap) => {
builder.insert_snippet(
cap,
insert_pos,
- format!("type $0Type{} = {};\n\n{}", generics, ty, indent),
+ format!("type $0Type{generic_params} = {ty};\n\n{indent}"),
);
}
None => {
builder.insert(
insert_pos,
- format!("type Type{} = {};\n\n{}", generics, ty, indent),
+ format!("type Type{generic_params} = {ty};\n\n{indent}"),
);
}
}
@@ -109,7 +96,7 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
fn collect_used_generics<'gp>(
ty: &ast::Type,
known_generics: &'gp [ast::GenericParam],
-) -> Vec<&'gp ast::GenericParam> {
+) -> Option<Vec<&'gp ast::GenericParam>> {
// can't use a closure -> closure here cause lifetime inference fails for that
fn find_lifetime(text: &str) -> impl Fn(&&ast::GenericParam) -> bool + '_ {
move |gp: &&ast::GenericParam| match gp {
@@ -198,7 +185,8 @@ fn collect_used_generics<'gp>(
ast::GenericParam::LifetimeParam(_) => 0,
ast::GenericParam::TypeParam(_) => 1,
});
- generics
+
+ Some(generics).filter(|it| it.len() > 0)
}
#[cfg(test)]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
index 3596b6f82..a738deffb 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs
@@ -91,13 +91,13 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
match anchor {
Anchor::Before(_) | Anchor::Replace(_) => {
- format_to!(buf, "let {}{} = {}", var_modifier, var_name, reference_modifier)
+ format_to!(buf, "let {var_modifier}{var_name} = {reference_modifier}")
}
Anchor::WrapInBlock(_) => {
- format_to!(buf, "{{ let {} = {}", var_name, reference_modifier)
+ format_to!(buf, "{{ let {var_name} = {reference_modifier}")
}
};
- format_to!(buf, "{}", to_extract.syntax());
+ format_to!(buf, "{to_extract}");
if let Anchor::Replace(stmt) = anchor {
cov_mark::hit!(test_extract_var_expr_stmt);
@@ -107,8 +107,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
match ctx.config.snippet_cap {
Some(cap) => {
let snip = buf.replace(
- &format!("let {}{}", var_modifier, var_name),
- &format!("let {}$0{}", var_modifier, var_name),
+ &format!("let {var_modifier}{var_name}"),
+ &format!("let {var_modifier}$0{var_name}"),
);
edit.replace_snippet(cap, expr_range, snip)
}
@@ -135,8 +135,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
match ctx.config.snippet_cap {
Some(cap) => {
let snip = buf.replace(
- &format!("let {}{}", var_modifier, var_name),
- &format!("let {}$0{}", var_modifier, var_name),
+ &format!("let {var_modifier}{var_name}"),
+ &format!("let {var_modifier}$0{var_name}"),
);
edit.insert_snippet(cap, offset, snip)
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs
index b33846f54..d9e00435e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs
@@ -1,4 +1,4 @@
-use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution};
+use hir::{db::HirDatabase, HasSource, HasVisibility, ModuleDef, PathResolution, ScopeDef};
use ide_db::base_db::FileId;
use syntax::{
ast::{self, HasVisibility as _},
@@ -18,7 +18,7 @@ use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists};
// fn frobnicate() {}
// }
// fn main() {
-// m::frobnicate$0() {}
+// m::frobnicate$0();
// }
// ```
// ->
@@ -27,7 +27,7 @@ use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists};
// $0pub(crate) fn frobnicate() {}
// }
// fn main() {
-// m::frobnicate() {}
+// m::frobnicate();
// }
// ```
pub(crate) fn fix_visibility(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
@@ -37,11 +37,15 @@ pub(crate) fn fix_visibility(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
let path: ast::Path = ctx.find_node_at_offset()?;
- let path_res = ctx.sema.resolve_path(&path)?;
- let def = match path_res {
- PathResolution::Def(def) => def,
- _ => return None,
- };
+ let qualifier = path.qualifier()?;
+ let name_ref = path.segment()?.name_ref()?;
+ let qualifier_res = ctx.sema.resolve_path(&qualifier)?;
+ let PathResolution::Def(ModuleDef::Module(module)) = qualifier_res else { return None; };
+ let (_, def) = module
+ .scope(ctx.db(), None)
+ .into_iter()
+ .find(|(name, _)| name.to_smol_str() == name_ref.text().as_str())?;
+ let ScopeDef::ModuleDef(def) = def else { return None; };
let current_module = ctx.sema.scope(path.syntax())?.module();
let target_module = def.module(ctx.db())?;
@@ -57,8 +61,8 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
let assist_label = match target_name {
- None => format!("Change visibility to {}", missing_visibility),
- Some(name) => format!("Change visibility of {} to {}", name, missing_visibility),
+ None => format!("Change visibility to {missing_visibility}"),
+ Some(name) => format!("Change visibility of {name} to {missing_visibility}"),
};
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
@@ -68,15 +72,15 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
Some(current_visibility) => builder.replace_snippet(
cap,
current_visibility.syntax().text_range(),
- format!("$0{}", missing_visibility),
+ format!("$0{missing_visibility}"),
),
- None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
+ None => builder.insert_snippet(cap, offset, format!("$0{missing_visibility} ")),
},
None => match current_visibility {
Some(current_visibility) => {
builder.replace(current_visibility.syntax().text_range(), missing_visibility)
}
- None => builder.insert(offset, format!("{} ", missing_visibility)),
+ None => builder.insert(offset, format!("{missing_visibility} ")),
},
}
})
@@ -114,7 +118,7 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
let target_name = record_field_def.name(ctx.db());
let assist_label =
- format!("Change visibility of {}.{} to {}", parent_name, target_name, missing_visibility);
+ format!("Change visibility of {parent_name}.{target_name} to {missing_visibility}");
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
builder.edit_file(target_file);
@@ -123,15 +127,15 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
Some(current_visibility) => builder.replace_snippet(
cap,
current_visibility.syntax().text_range(),
- format!("$0{}", missing_visibility),
+ format!("$0{missing_visibility}"),
),
- None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
+ None => builder.insert_snippet(cap, offset, format!("$0{missing_visibility} ")),
},
None => match current_visibility {
Some(current_visibility) => {
builder.replace(current_visibility.syntax().text_range(), missing_visibility)
}
- None => builder.insert(offset, format!("{} ", missing_visibility)),
+ None => builder.insert(offset, format!("{missing_visibility} ")),
},
}
})
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
index bdd3cf4f0..c9aa41c84 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_projection_method.rs
@@ -124,6 +124,7 @@ fn generate_enum_projection_method(
happy_case,
sad_case,
} = props;
+
let variant = ctx.find_node_at_offset::<ast::Variant>()?;
let variant_name = variant.name()?;
let parent_enum = ast::Adt::Enum(variant.parent_enum());
@@ -144,7 +145,7 @@ fn generate_enum_projection_method(
ast::StructKind::Unit => return None,
};
- let fn_name = format!("{}_{}", fn_name_prefix, &to_lower_snake_case(&variant_name.text()));
+ let fn_name = format!("{fn_name_prefix}_{}", &to_lower_snake_case(&variant_name.text()));
// Return early if we've found an existing new fn
let impl_def = find_struct_impl(ctx, &parent_enum, &[fn_name.clone()])?;
@@ -156,15 +157,25 @@ fn generate_enum_projection_method(
assist_description,
target,
|builder| {
- let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{v} "));
+ let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v));
+
+ let field_type_syntax = field_type.syntax();
+
+ let must_use = if ctx.config.assist_emit_must_use {
+ "#[must_use]\n "
+ } else {
+ ""
+ };
+
let method = format!(
- " {vis}fn {fn_name}({self_param}) -> {return_prefix}{field_type}{return_suffix} {{
+ " {must_use}{vis}fn {fn_name}({self_param}) -> {return_prefix}{field_type_syntax}{return_suffix} {{
if let Self::{variant_name}{pattern_suffix} = self {{
{happy_case}({bound_name})
}} else {{
{sad_case}
}}
- }}");
+ }}"
+ );
add_method_to_adt(builder, &parent_enum, impl_def, &method);
},
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs
index 35cd42908..0bcb57283 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs
@@ -261,12 +261,12 @@ fn main() {
}
//- /foo.rs
-enum Foo {
+pub enum Foo {
Bar,
}
",
r"
-enum Foo {
+pub enum Foo {
Bar,
Baz,
}
@@ -310,7 +310,7 @@ fn main() {
generate_enum_variant,
r"
mod m {
- enum Foo {
+ pub enum Foo {
Bar,
}
}
@@ -320,7 +320,7 @@ fn main() {
",
r"
mod m {
- enum Foo {
+ pub enum Foo {
Bar,
Baz,
}
@@ -516,10 +516,10 @@ mod foo;
use foo::Foo::Bar$0;
//- /foo.rs
-enum Foo {}
+pub enum Foo {}
",
r"
-enum Foo {
+pub enum Foo {
Bar,
}
",
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
index c229127e4..57f198748 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
@@ -1324,7 +1324,7 @@ fn foo() {
generate_function,
r"
mod bar {
- mod baz {}
+ pub mod baz {}
}
fn foo() {
@@ -1333,7 +1333,7 @@ fn foo() {
",
r"
mod bar {
- mod baz {
+ pub mod baz {
pub(crate) fn my_fn() {
${0:todo!()}
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
index 9f51cdaf8..0c546ce5d 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_call.rs
@@ -1,3 +1,5 @@
+use std::collections::BTreeSet;
+
use ast::make;
use either::Either;
use hir::{db::HirDatabase, PathResolution, Semantics, TypeInfo};
@@ -190,10 +192,10 @@ pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
PathResolution::Def(hir::ModuleDef::Function(f)) => f,
_ => return None,
};
- (function, format!("Inline `{}`", path))
+ (function, format!("Inline `{path}`"))
}
ast::CallableExpr::MethodCall(call) => {
- (ctx.sema.resolve_method_call(call)?, format!("Inline `{}`", name_ref))
+ (ctx.sema.resolve_method_call(call)?, format!("Inline `{name_ref}`"))
}
};
@@ -373,8 +375,44 @@ fn inline(
})
}
}
+
+ let mut func_let_vars: BTreeSet<String> = BTreeSet::new();
+
+ // grab all of the local variable declarations in the function
+ for stmt in fn_body.statements() {
+ if let Some(let_stmt) = ast::LetStmt::cast(stmt.syntax().to_owned()) {
+ for has_token in let_stmt.syntax().children_with_tokens() {
+ if let Some(node) = has_token.as_node() {
+ if let Some(ident_pat) = ast::IdentPat::cast(node.to_owned()) {
+ func_let_vars.insert(ident_pat.syntax().text().to_string());
+ }
+ }
+ }
+ }
+ }
+
// Inline parameter expressions or generate `let` statements depending on whether inlining works or not.
for ((pat, param_ty, _), usages, expr) in izip!(params, param_use_nodes, arguments).rev() {
+ // izip confuses RA due to our lack of hygiene info currently losing us type info causing incorrect errors
+ let usages: &[ast::PathExpr] = &*usages;
+ let expr: &ast::Expr = expr;
+
+ let insert_let_stmt = || {
+ let ty = sema.type_of_expr(expr).filter(TypeInfo::has_adjustment).and(param_ty.clone());
+ if let Some(stmt_list) = body.stmt_list() {
+ stmt_list.push_front(
+ make::let_stmt(pat.clone(), ty, Some(expr.clone())).clone_for_update().into(),
+ )
+ }
+ };
+
+ // check if there is a local var in the function that conflicts with parameter
+ // if it does then emit a let statement and continue
+ if func_let_vars.contains(&expr.syntax().text().to_string()) {
+ insert_let_stmt();
+ continue;
+ }
+
let inline_direct = |usage, replacement: &ast::Expr| {
if let Some(field) = path_expr_as_record_field(usage) {
cov_mark::hit!(inline_call_inline_direct_field);
@@ -383,9 +421,7 @@ fn inline(
ted::replace(usage.syntax(), &replacement.syntax().clone_for_update());
}
};
- // izip confuses RA due to our lack of hygiene info currently losing us type info causing incorrect errors
- let usages: &[ast::PathExpr] = &*usages;
- let expr: &ast::Expr = expr;
+
match usages {
// inline single use closure arguments
[usage]
@@ -408,18 +444,11 @@ fn inline(
}
// can't inline, emit a let statement
_ => {
- let ty =
- sema.type_of_expr(expr).filter(TypeInfo::has_adjustment).and(param_ty.clone());
- if let Some(stmt_list) = body.stmt_list() {
- stmt_list.push_front(
- make::let_stmt(pat.clone(), ty, Some(expr.clone()))
- .clone_for_update()
- .into(),
- )
- }
+ insert_let_stmt();
}
}
}
+
if let Some(generic_arg_list) = generic_arg_list.clone() {
if let Some((target, source)) = &sema.scope(node.syntax()).zip(sema.scope(fn_body.syntax()))
{
@@ -1256,4 +1285,37 @@ impl A {
"#,
)
}
+
+ #[test]
+ fn local_variable_shadowing_callers_argument() {
+ check_assist(
+ inline_call,
+ r#"
+fn foo(bar: u32, baz: u32) -> u32 {
+ let a = 1;
+ bar * baz * a * 6
+}
+fn main() {
+ let a = 7;
+ let b = 1;
+ let res = foo$0(a, b);
+}
+"#,
+ r#"
+fn foo(bar: u32, baz: u32) -> u32 {
+ let a = 1;
+ bar * baz * a * 6
+}
+fn main() {
+ let a = 7;
+ let b = 1;
+ let res = {
+ let bar = a;
+ let a = 1;
+ bar * b * a * 6
+ };
+}
+"#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs
index 7259d6781..ce44100e3 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs
@@ -113,7 +113,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>)
.collect::<Option<Vec<_>>>()?;
let init_str = initializer_expr.syntax().text().to_string();
- let init_in_paren = format!("({})", &init_str);
+ let init_in_paren = format!("({init_str})");
let target = match target {
ast::NameOrNameRef::Name(it) => it.syntax().text_range(),
@@ -132,7 +132,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>)
let replacement = if should_wrap { &init_in_paren } else { &init_str };
if ast::RecordExprField::for_field_name(&name).is_some() {
cov_mark::hit!(inline_field_shorthand);
- builder.insert(range.end(), format!(": {}", replacement));
+ builder.insert(range.end(), format!(": {replacement}"));
} else {
builder.replace(range, replacement.clone())
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
index 2fc754e3e..a54dc4f96 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
@@ -127,7 +127,7 @@ fn generate_unique_lifetime_param_name(
Some(type_params) => {
let used_lifetime_params: FxHashSet<_> =
type_params.lifetime_params().map(|p| p.syntax().text().to_string()).collect();
- ('a'..='z').map(|it| format!("'{}", it)).find(|it| !used_lifetime_params.contains(it))
+ ('a'..='z').map(|it| format!("'{it}")).find(|it| !used_lifetime_params.contains(it))
}
None => Some("'a".to_string()),
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs
index c24015b1c..641c90885 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/merge_match_arms.rs
@@ -78,7 +78,7 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
.join(" | ")
};
- let arm = format!("{} => {},", pats, current_expr.syntax().text());
+ let arm = format!("{pats} => {current_expr},");
if let [first, .., last] = &*arms_to_merge {
let start = first.syntax().text_range().start();
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_format_string_arg.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_format_string_arg.rs
index aa710d2ce..11db6ae7f 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_format_string_arg.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_format_string_arg.rs
@@ -92,7 +92,7 @@ pub(crate) fn move_format_string_arg(acc: &mut Assists, ctx: &AssistContext<'_>)
NodeOrToken::Node(n) => {
format_to!(current_arg, "{n}");
},
- NodeOrToken::Token(t) if t.kind() == COMMA=> {
+ NodeOrToken::Token(t) if t.kind() == COMMA => {
existing_args.push(current_arg.trim().into());
current_arg.clear();
},
@@ -238,14 +238,14 @@ fn main() {
&add_macro_decl(
r#"
fn main() {
- print!("{} {x + 1:b} {Struct(1, 2)}$0", 1);
+ print!("{:b} {x + 1:b} {Struct(1, 2)}$0", 1);
}
"#,
),
&add_macro_decl(
r#"
fn main() {
- print!("{} {:b} {}"$0, 1, x + 1, Struct(1, 2));
+ print!("{:b} {:b} {}"$0, 1, x + 1, Struct(1, 2));
}
"#,
),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs
index a6c85a2b1..1728c03cd 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_from_mod_rs.rs
@@ -40,11 +40,11 @@ pub(crate) fn move_from_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
let target = source_file.syntax().text_range();
let module_name = module.name(ctx.db())?.to_string();
- let path = format!("../{}.rs", module_name);
+ let path = format!("../{module_name}.rs");
let dst = AnchoredPathBuf { anchor: ctx.file_id(), path };
acc.add(
AssistId("move_from_mod_rs", AssistKind::Refactor),
- format!("Convert {}/mod.rs to {}.rs", module_name, module_name),
+ format!("Convert {module_name}/mod.rs to {module_name}.rs"),
target,
|builder| {
builder.move_file(ctx.file_id(), dst);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs
index b8f1b36de..ec3281619 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_guard.rs
@@ -133,16 +133,16 @@ pub(crate) fn move_arm_cond_to_match_guard(
};
let then_arm_end = match_arm.syntax().text_range().end();
let indent_level = match_arm.indent_level();
- let spaces = " ".repeat(indent_level.0 as _);
+ let spaces = indent_level;
let mut first = true;
for (cond, block) in conds_blocks {
if !first {
- edit.insert(then_arm_end, format!("\n{}", spaces));
+ edit.insert(then_arm_end, format!("\n{spaces}"));
} else {
first = false;
}
- let guard = format!("{} if {} => ", match_pat, cond.syntax().text());
+ let guard = format!("{match_pat} if {cond} => ");
edit.insert(then_arm_end, guard);
let only_expr = block.statements().next().is_none();
match &block.tail_expr() {
@@ -158,7 +158,7 @@ pub(crate) fn move_arm_cond_to_match_guard(
}
if let Some(e) = tail {
cov_mark::hit!(move_guard_ifelse_else_tail);
- let guard = format!("\n{}{} => ", spaces, match_pat);
+ let guard = format!("\n{spaces}{match_pat} => ");
edit.insert(then_arm_end, guard);
let only_expr = e.statements().next().is_none();
match &e.tail_expr() {
@@ -183,7 +183,7 @@ pub(crate) fn move_arm_cond_to_match_guard(
{
cov_mark::hit!(move_guard_ifelse_has_wildcard);
}
- _ => edit.insert(then_arm_end, format!("\n{}{} => {{}}", spaces, match_pat)),
+ _ => edit.insert(then_arm_end, format!("\n{spaces}{match_pat} => {{}}")),
}
}
},
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs
index 7468318a5..a7c605325 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_module_to_file.rs
@@ -52,7 +52,7 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext<'_>) ->
let mut buf = String::from("./");
match parent_module.name(ctx.db()) {
Some(name) if !parent_module.is_mod_rs(ctx.db()) => {
- format_to!(buf, "{}/", name)
+ format_to!(buf, "{name}/")
}
_ => (),
}
@@ -82,7 +82,7 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext<'_>) ->
items
};
- let buf = format!("mod {};", module_name);
+ let buf = format!("mod {module_name};");
let replacement_start = match module_ast.mod_token() {
Some(mod_token) => mod_token.text_range(),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs
index a909ce8b2..076d25411 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/move_to_mod_rs.rs
@@ -40,11 +40,11 @@ pub(crate) fn move_to_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
let target = source_file.syntax().text_range();
let module_name = module.name(ctx.db())?.to_string();
- let path = format!("./{}/mod.rs", module_name);
+ let path = format!("./{module_name}/mod.rs");
let dst = AnchoredPathBuf { anchor: ctx.file_id(), path };
acc.add(
AssistId("move_to_mod_rs", AssistKind::Refactor),
- format!("Convert {}.rs to {}/mod.rs", module_name, module_name),
+ format!("Convert {module_name}.rs to {module_name}/mod.rs"),
target,
|builder| {
builder.move_file(ctx.file_id(), dst);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs
index 424db7437..7e3fef516 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/number_representation.rs
@@ -38,7 +38,7 @@ pub(crate) fn reformat_number_literal(acc: &mut Assists, ctx: &AssistContext<'_>
converted.push_str(suffix);
let group_id = GroupLabel("Reformat number literal".into());
- let label = format!("Convert {} to {}", literal, converted);
+ let label = format!("Convert {literal} to {converted}");
let range = literal.syntax().text_range();
acc.add_group(
&group_id,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
index e57d1d065..1ea87429c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_method_call.rs
@@ -54,7 +54,7 @@ pub(crate) fn qualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>) ->
acc.add(
AssistId("qualify_method_call", AssistKind::RefactorInline),
- format!("Qualify `{}` method call", ident.text()),
+ format!("Qualify `{ident}` method call"),
range,
|builder| {
qualify_candidate.qualify(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs
index 4b2af550b..e759e1561 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/qualify_path.rs
@@ -118,14 +118,14 @@ impl QualifyCandidate<'_> {
match self {
QualifyCandidate::QualifierStart(segment, generics) => {
let generics = generics.as_ref().map_or_else(String::new, ToString::to_string);
- replacer(format!("{}{}::{}", import, generics, segment));
+ replacer(format!("{import}{generics}::{segment}"));
}
QualifyCandidate::UnqualifiedName(generics) => {
let generics = generics.as_ref().map_or_else(String::new, ToString::to_string);
- replacer(format!("{}{}", import, generics));
+ replacer(format!("{import}{generics}"));
}
QualifyCandidate::TraitAssocItem(qualifier, segment) => {
- replacer(format!("<{} as {}>::{}", qualifier, import, segment));
+ replacer(format!("<{qualifier} as {import}>::{segment}"));
}
QualifyCandidate::TraitMethod(db, mcall_expr) => {
Self::qualify_trait_method(db, mcall_expr, replacer, import, item);
@@ -155,16 +155,11 @@ impl QualifyCandidate<'_> {
hir::Access::Exclusive => make::expr_ref(receiver, true),
hir::Access::Owned => receiver,
};
- replacer(format!(
- "{}::{}{}{}",
- import,
- method_name,
- generics,
- match arg_list {
- Some(args) => make::arg_list(iter::once(receiver).chain(args)),
- None => make::arg_list(iter::once(receiver)),
- }
- ));
+ let arg_list = match arg_list {
+ Some(args) => make::arg_list(iter::once(receiver).chain(args)),
+ None => make::arg_list(iter::once(receiver)),
+ };
+ replacer(format!("{import}::{method_name}{generics}{arg_list}"));
}
Some(())
}
@@ -218,15 +213,17 @@ fn group_label(candidate: &ImportCandidate) -> GroupLabel {
}
}
.text();
- GroupLabel(format!("Qualify {}", name))
+ GroupLabel(format!("Qualify {name}"))
}
fn label(candidate: &ImportCandidate, import: &LocatedImport) -> String {
+ let import_path = &import.import_path;
+
match candidate {
ImportCandidate::Path(candidate) if candidate.qualifier.is_none() => {
- format!("Qualify as `{}`", import.import_path)
+ format!("Qualify as `{import_path}`")
}
- _ => format!("Qualify with `{}`", import.import_path),
+ _ => format!("Qualify with `{import_path}`"),
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs
index dbe8cb7bf..c9bc25b27 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/raw_string.rs
@@ -34,13 +34,10 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
let hashes = "#".repeat(required_hashes(&value).max(1));
if matches!(value, Cow::Borrowed(_)) {
// Avoid replacing the whole string to better position the cursor.
- edit.insert(token.syntax().text_range().start(), format!("r{}", hashes));
+ edit.insert(token.syntax().text_range().start(), format!("r{hashes}"));
edit.insert(token.syntax().text_range().end(), hashes);
} else {
- edit.replace(
- token.syntax().text_range(),
- format!("r{}\"{}\"{}", hashes, value, hashes),
- );
+ edit.replace(token.syntax().text_range(), format!("r{hashes}\"{value}\"{hashes}"));
}
},
)
@@ -83,7 +80,7 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
}
}
- edit.replace(token.syntax().text_range(), format!("\"{}\"", escaped));
+ edit.replace(token.syntax().text_range(), format!("\"{escaped}\""));
},
)
}
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 afaa7c933..99ae60e07 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
@@ -1,7 +1,7 @@
use itertools::Itertools;
use syntax::{
ast::{self, AstNode, AstToken},
- match_ast, NodeOrToken, SyntaxElement, TextSize, T,
+ match_ast, NodeOrToken, SyntaxElement, TextRange, TextSize, T,
};
use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -22,7 +22,36 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
// }
// ```
pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
- let macro_call = ctx.find_node_at_offset::<ast::MacroCall>()?;
+ let macro_calls = if ctx.has_empty_selection() {
+ vec![ctx.find_node_at_offset::<ast::MacroCall>()?]
+ } else {
+ ctx.covering_element()
+ .as_node()?
+ .descendants()
+ .filter(|node| ctx.selection_trimmed().contains_range(node.text_range()))
+ .filter_map(ast::MacroCall::cast)
+ .collect()
+ };
+
+ 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!()",
+ ctx.selection_trimmed(),
+ |builder| {
+ for (range, text) in replacements {
+ builder.replace(range, text);
+ }
+ },
+ )
+}
+
+fn compute_dbg_replacement(macro_call: ast::MacroCall) -> Option<(TextRange, String)> {
let tt = macro_call.token_tree()?;
let r_delim = NodeOrToken::Token(tt.right_delimiter_token()?);
if macro_call.path()?.segment()?.name_ref()?.text() != "dbg"
@@ -41,7 +70,7 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
let macro_expr = ast::MacroExpr::cast(macro_call.syntax().parent()?)?;
let parent = macro_expr.syntax().parent()?;
- let (range, text) = match &*input_expressions {
+ Some(match &*input_expressions {
// dbg!()
[] => {
match_ast! {
@@ -102,15 +131,11 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
};
(
macro_call.syntax().text_range(),
- if wrap { format!("({})", expr) } else { expr.to_string() },
+ if wrap { format!("({expr})") } else { expr.to_string() },
)
}
// dbg!(expr0, expr1, ...)
exprs => (macro_call.syntax().text_range(), format!("({})", exprs.iter().format(", "))),
- };
-
- acc.add(AssistId("remove_dbg", AssistKind::Refactor), "Remove dbg!()", range, |builder| {
- builder.replace(range, text);
})
}
@@ -127,8 +152,8 @@ mod tests {
fn check(ra_fixture_before: &str, ra_fixture_after: &str) {
check_assist(
remove_dbg,
- &format!("fn main() {{\n{}\n}}", ra_fixture_before),
- &format!("fn main() {{\n{}\n}}", ra_fixture_after),
+ &format!("fn main() {{\n{ra_fixture_before}\n}}"),
+ &format!("fn main() {{\n{ra_fixture_after}\n}}"),
);
}
@@ -238,4 +263,28 @@ fn foo() {
check(r#"$0dbg!(0, 1)"#, r#"(0, 1)"#);
check(r#"$0dbg!(0, (1, 2))"#, r#"(0, (1, 2))"#);
}
+
+ #[test]
+ fn test_range() {
+ check(
+ r#"
+fn f() {
+ dbg!(0) + $0dbg!(1);
+ dbg!(())$0
+}
+"#,
+ r#"
+fn f() {
+ dbg!(0) + 1;
+ ()
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn test_range_partial() {
+ check_assist_not_applicable(remove_dbg, r#"$0dbg$0!(0)"#);
+ check_assist_not_applicable(remove_dbg, r#"$0dbg!(0$0)"#);
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index 9fd5e1886..6fa15b28e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -124,7 +124,7 @@ fn add_assist(
) -> Option<()> {
let target = attr.syntax().text_range();
let annotated_name = adt.name()?;
- let label = format!("Convert to manual `impl {} for {}`", replace_trait_path, annotated_name);
+ let label = format!("Convert to manual `impl {replace_trait_path} for {annotated_name}`");
acc.add(
AssistId("replace_derive_with_manual_impl", AssistKind::Refactor),
@@ -158,11 +158,8 @@ fn add_assist(
}
}
- builder.insert_snippet(
- cap,
- insert_pos,
- format!("\n\n{}", render_snippet(cap, impl_def.syntax(), cursor)),
- )
+ let rendered = render_snippet(cap, impl_def.syntax(), cursor);
+ builder.insert_snippet(cap, insert_pos, format!("\n\n{rendered}"))
}
};
},
@@ -1022,8 +1019,6 @@ struct Foo {
impl foo::Bar for Foo {
$0type Qux;
- const Baz: usize = 42;
-
const Fez: usize;
fn foo() {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs
index 7d91be621..77382056c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_or_with_or_else.rs
@@ -62,7 +62,7 @@ pub(crate) fn replace_or_with_or_else(acc: &mut Assists, ctx: &AssistContext<'_>
acc.add(
AssistId("replace_or_with_or_else", AssistKind::RefactorRewrite),
- format!("Replace {} with {}", name.text(), replace),
+ format!("Replace {name} with {replace}"),
call.syntax().text_range(),
|builder| {
builder.replace(name.syntax().text_range(), replace);
@@ -138,7 +138,7 @@ pub(crate) fn replace_or_else_with_or(acc: &mut Assists, ctx: &AssistContext<'_>
acc.add(
AssistId("replace_or_else_with_or", AssistKind::RefactorRewrite),
- format!("Replace {} with {}", name.text(), replace),
+ format!("Replace {name} with {replace}"),
call.syntax().text_range(),
|builder| {
builder.replace(name.syntax().text_range(), replace);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs
index 521447c26..c177adc7a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs
@@ -79,7 +79,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
"Replace turbofish with explicit type",
TextRange::new(initializer_start, turbofish_range.end()),
|builder| {
- builder.insert(ident_range.end(), format!(": {}", returned_type));
+ builder.insert(ident_range.end(), format!(": {returned_type}"));
builder.delete(turbofish_range);
},
);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
index d5cd2d551..043988322 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs
@@ -44,6 +44,12 @@ pub(crate) fn unnecessary_async(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
if function.body()?.syntax().descendants().find_map(ast::AwaitExpr::cast).is_some() {
return None;
}
+ // Do nothing if the method is a member of trait.
+ if let Some(impl_) = function.syntax().ancestors().nth(2).and_then(ast::Impl::cast) {
+ if let Some(_) = impl_.trait_() {
+ return None;
+ }
+ }
// Remove the `async` keyword plus whitespace after it, if any.
let async_range = {
@@ -254,4 +260,18 @@ pub async fn f(s: &S) { s.f2() }"#,
fn does_not_apply_when_not_on_prototype() {
check_assist_not_applicable(unnecessary_async, "pub async fn f() { $0f2() }")
}
+
+ #[test]
+ fn does_not_apply_on_async_trait_method() {
+ check_assist_not_applicable(
+ unnecessary_async,
+ r#"
+trait Trait {
+ async fn foo();
+}
+impl Trait for () {
+ $0async fn foo() {}
+}"#,
+ );
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs
index 25c58d086..d09614c51 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unwrap_tuple.rs
@@ -69,13 +69,13 @@ pub(crate) fn unwrap_tuple(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
for (pat, ty, expr) in
itertools::izip!(tuple_pat.fields(), tys.fields(), tuple_init.fields())
{
- zipped_decls.push_str(&format!("{}let {pat}: {ty} = {expr};\n", indents))
+ zipped_decls.push_str(&format!("{indents}let {pat}: {ty} = {expr};\n"))
}
edit.replace(parent.text_range(), zipped_decls.trim());
} else {
let mut zipped_decls = String::new();
for (pat, expr) in itertools::izip!(tuple_pat.fields(), tuple_init.fields()) {
- zipped_decls.push_str(&format!("{}let {pat} = {expr};\n", indents));
+ zipped_decls.push_str(&format!("{indents}let {pat} = {expr};\n"));
}
edit.replace(parent.text_range(), zipped_decls.trim());
}
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 83446387d..b6c489eb6 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
@@ -76,11 +76,11 @@ pub(crate) fn wrap_return_type_in_result(acc: &mut Assists, ctx: &AssistContext<
match ctx.config.snippet_cap {
Some(cap) => {
- let snippet = format!("Result<{}, ${{0:_}}>", type_ref);
+ let snippet = format!("Result<{type_ref}, ${{0:_}}>");
builder.replace_snippet(cap, type_ref.syntax().text_range(), snippet)
}
None => builder
- .replace(type_ref.syntax().text_range(), format!("Result<{}, _>", type_ref)),
+ .replace(type_ref.syntax().text_range(), format!("Result<{type_ref}, _>")),
}
},
)
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 a07318cef..387cc6314 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
@@ -120,6 +120,7 @@ mod handlers {
mod convert_into_to_from;
mod convert_iter_for_each_to_for;
mod convert_let_else_to_match;
+ mod convert_match_to_let_else;
mod convert_tuple_struct_to_named_struct;
mod convert_named_struct_to_tuple_struct;
mod convert_to_guarded_return;
@@ -220,6 +221,7 @@ mod handlers {
convert_iter_for_each_to_for::convert_for_loop_with_for_each,
convert_let_else_to_match::convert_let_else_to_match,
convert_named_struct_to_tuple_struct::convert_named_struct_to_tuple_struct,
+ convert_match_to_let_else::convert_match_to_let_else,
convert_to_guarded_return::convert_to_guarded_return,
convert_tuple_struct_to_named_struct::convert_tuple_struct_to_named_struct,
convert_two_arm_bool_match_to_matches_macro::convert_two_arm_bool_match_to_matches_macro,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
index f7f2417d0..92ced27c7 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests.rs
@@ -30,6 +30,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
skip_glob_imports: true,
},
prefer_no_std: false,
+ assist_emit_must_use: false,
};
pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) {
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 2c4000efe..c09317572 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
@@ -408,6 +408,27 @@ fn main() {
}
#[test]
+fn doctest_convert_match_to_let_else() {
+ check_doc_test(
+ "convert_match_to_let_else",
+ r#####"
+//- minicore: option
+fn foo(opt: Option<()>) {
+ let val = $0match opt {
+ Some(it) => it,
+ None => return,
+ };
+}
+"#####,
+ r#####"
+fn foo(opt: Option<()>) {
+ let Some(val) = opt else { return };
+}
+"#####,
+ )
+}
+
+#[test]
fn doctest_convert_named_struct_to_tuple_struct() {
check_doc_test(
"convert_named_struct_to_tuple_struct",
@@ -720,7 +741,7 @@ mod m {
fn frobnicate() {}
}
fn main() {
- m::frobnicate$0() {}
+ m::frobnicate$0();
}
"#####,
r#####"
@@ -728,7 +749,7 @@ mod m {
$0pub(crate) fn frobnicate() {}
}
fn main() {
- m::frobnicate() {}
+ m::frobnicate();
}
"#####,
)
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
index db32e7182..68c31b4f8 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -119,6 +119,10 @@ pub fn filter_assoc_items(
(default_methods, def.body()),
(DefaultMethods::Only, Some(_)) | (DefaultMethods::No, None)
),
+ ast::AssocItem::Const(def) => matches!(
+ (default_methods, def.body()),
+ (DefaultMethods::Only, Some(_)) | (DefaultMethods::No, None)
+ ),
_ => default_methods == DefaultMethods::No,
})
.collect::<Vec<_>>()
@@ -189,8 +193,8 @@ pub(crate) fn render_snippet(_cap: SnippetCap, node: &SyntaxNode, cursor: Cursor
let mut placeholder = cursor.node().to_string();
escape(&mut placeholder);
let tab_stop = match cursor {
- Cursor::Replace(placeholder) => format!("${{0:{}}}", placeholder),
- Cursor::Before(placeholder) => format!("$0{}", placeholder),
+ Cursor::Replace(placeholder) => format!("${{0:{placeholder}}}"),
+ Cursor::Before(placeholder) => format!("$0{placeholder}"),
};
let mut buf = node.to_string();
@@ -539,17 +543,17 @@ impl ReferenceConversion {
ReferenceConversionType::AsRefSlice => {
let type_argument_name =
self.ty.type_arguments().next().unwrap().display(db).to_string();
- format!("&[{}]", type_argument_name)
+ format!("&[{type_argument_name}]")
}
ReferenceConversionType::Dereferenced => {
let type_argument_name =
self.ty.type_arguments().next().unwrap().display(db).to_string();
- format!("&{}", type_argument_name)
+ format!("&{type_argument_name}")
}
ReferenceConversionType::Option => {
let type_argument_name =
self.ty.type_arguments().next().unwrap().display(db).to_string();
- format!("Option<&{}>", type_argument_name)
+ format!("Option<&{type_argument_name}>")
}
ReferenceConversionType::Result => {
let mut type_arguments = self.ty.type_arguments();
@@ -557,19 +561,19 @@ impl ReferenceConversion {
type_arguments.next().unwrap().display(db).to_string();
let second_type_argument_name =
type_arguments.next().unwrap().display(db).to_string();
- format!("Result<&{}, &{}>", first_type_argument_name, second_type_argument_name)
+ format!("Result<&{first_type_argument_name}, &{second_type_argument_name}>")
}
}
}
pub(crate) fn getter(&self, field_name: String) -> String {
match self.conversion {
- ReferenceConversionType::Copy => format!("self.{}", field_name),
+ ReferenceConversionType::Copy => format!("self.{field_name}"),
ReferenceConversionType::AsRefStr
| ReferenceConversionType::AsRefSlice
| ReferenceConversionType::Dereferenced
| ReferenceConversionType::Option
- | ReferenceConversionType::Result => format!("self.{}.as_ref()", field_name),
+ | ReferenceConversionType::Result => format!("self.{field_name}.as_ref()"),
}
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs
index 7a0c91295..6c87e66c1 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils/gen_trait_fn_body.rs
@@ -41,7 +41,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut arms = vec![];
for variant in list.variants() {
let name = variant.name()?;
- let variant_name = make::ext::path_from_idents(["Self", &format!("{}", name)])?;
+ let variant_name = make::ext::path_from_idents(["Self", &format!("{name}")])?;
match variant.field_list() {
// => match self { Self::Name { x } => Self::Name { x: x.clone() } }
@@ -70,7 +70,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut pats = vec![];
let mut fields = vec![];
for (i, _) in list.fields().enumerate() {
- let field_name = format!("arg{}", i);
+ let field_name = format!("arg{i}");
let pat = make::ident_pat(false, false, make::name(&field_name));
pats.push(pat.into());
@@ -118,7 +118,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut fields = vec![];
for (i, _) in field_list.fields().enumerate() {
let f_path = make::expr_path(make::ext::ident_path("self"));
- let target = make::expr_field(f_path, &format!("{}", i));
+ let target = make::expr_field(f_path, &format!("{i}"));
fields.push(gen_clone_call(target));
}
let struct_name = make::expr_path(make::ext::ident_path("Self"));
@@ -151,7 +151,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut arms = vec![];
for variant in list.variants() {
let name = variant.name()?;
- let variant_name = make::ext::path_from_idents(["Self", &format!("{}", name)])?;
+ let variant_name = make::ext::path_from_idents(["Self", &format!("{name}")])?;
let target = make::expr_path(make::ext::ident_path("f"));
match variant.field_list() {
@@ -159,7 +159,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
// => f.debug_struct(name)
let target = make::expr_path(make::ext::ident_path("f"));
let method = make::name_ref("debug_struct");
- let struct_name = format!("\"{}\"", name);
+ let struct_name = format!("\"{name}\"");
let args = make::arg_list(Some(make::expr_literal(&struct_name).into()));
let mut expr = make::expr_method_call(target, method, args);
@@ -173,8 +173,8 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
// => <expr>.field("field_name", field)
let method_name = make::name_ref("field");
- let name = make::expr_literal(&(format!("\"{}\"", field_name))).into();
- let path = &format!("{}", field_name);
+ let name = make::expr_literal(&(format!("\"{field_name}\""))).into();
+ let path = &format!("{field_name}");
let path = make::expr_path(make::ext::ident_path(path));
let args = make::arg_list(vec![name, path]);
expr = make::expr_method_call(expr, method_name, args);
@@ -192,13 +192,13 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
// => f.debug_tuple(name)
let target = make::expr_path(make::ext::ident_path("f"));
let method = make::name_ref("debug_tuple");
- let struct_name = format!("\"{}\"", name);
+ let struct_name = format!("\"{name}\"");
let args = make::arg_list(Some(make::expr_literal(&struct_name).into()));
let mut expr = make::expr_method_call(target, method, args);
let mut pats = vec![];
for (i, _) in list.fields().enumerate() {
- let name = format!("arg{}", i);
+ let name = format!("arg{i}");
// create a field pattern for use in `MyStruct(fields..)`
let field_name = make::name(&name);
@@ -222,7 +222,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
arms.push(make::match_arm(Some(pat.into()), None, expr));
}
None => {
- let fmt_string = make::expr_literal(&(format!("\"{}\"", name))).into();
+ let fmt_string = make::expr_literal(&(format!("\"{name}\""))).into();
let args = make::arg_list([target, fmt_string]);
let macro_name = make::expr_path(make::ext::ident_path("write"));
let macro_call = make::expr_macro_call(macro_name, args);
@@ -244,7 +244,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
}
ast::Adt::Struct(strukt) => {
- let name = format!("\"{}\"", annotated_name);
+ let name = format!("\"{annotated_name}\"");
let args = make::arg_list(Some(make::expr_literal(&name).into()));
let target = make::expr_path(make::ext::ident_path("f"));
@@ -258,10 +258,10 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut expr = make::expr_method_call(target, method, args);
for field in field_list.fields() {
let name = field.name()?;
- let f_name = make::expr_literal(&(format!("\"{}\"", name))).into();
+ let f_name = make::expr_literal(&(format!("\"{name}\""))).into();
let f_path = make::expr_path(make::ext::ident_path("self"));
let f_path = make::expr_ref(f_path, false);
- let f_path = make::expr_field(f_path, &format!("{}", name));
+ let f_path = make::expr_field(f_path, &format!("{name}"));
let args = make::arg_list([f_name, f_path]);
expr = make::expr_method_call(expr, make::name_ref("field"), args);
}
@@ -275,7 +275,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
for (i, _) in field_list.fields().enumerate() {
let f_path = make::expr_path(make::ext::ident_path("self"));
let f_path = make::expr_ref(f_path, false);
- let f_path = make::expr_field(f_path, &format!("{}", i));
+ let f_path = make::expr_field(f_path, &format!("{i}"));
let method = make::name_ref("field");
expr = make::expr_method_call(expr, method, make::arg_list(Some(f_path)));
}
@@ -379,7 +379,7 @@ fn gen_hash_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut stmts = vec![];
for (i, _) in field_list.fields().enumerate() {
let base = make::expr_path(make::ext::ident_path("self"));
- let target = make::expr_field(base, &format!("{}", i));
+ let target = make::expr_field(base, &format!("{i}"));
stmts.push(gen_hash_call(target));
}
make::block_expr(stmts, None).indent(ast::edit::IndentLevel(1))
@@ -453,10 +453,10 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
for field in list.fields() {
let field_name = field.name()?.to_string();
- let l_name = &format!("l_{}", field_name);
+ let l_name = &format!("l_{field_name}");
l_fields.push(gen_record_pat_field(&field_name, l_name));
- let r_name = &format!("r_{}", field_name);
+ let r_name = &format!("r_{field_name}");
r_fields.push(gen_record_pat_field(&field_name, r_name));
let lhs = make::expr_path(make::ext::ident_path(l_name));
@@ -484,12 +484,12 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut r_fields = vec![];
for (i, _) in list.fields().enumerate() {
- let field_name = format!("{}", i);
+ let field_name = format!("{i}");
- let l_name = format!("l{}", field_name);
+ let l_name = format!("l{field_name}");
l_fields.push(gen_tuple_field(&l_name));
- let r_name = format!("r{}", field_name);
+ let r_name = format!("r{field_name}");
r_fields.push(gen_tuple_field(&r_name));
let lhs = make::expr_path(make::ext::ident_path(&l_name));
@@ -548,7 +548,7 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
Some(ast::FieldList::TupleFieldList(field_list)) => {
let mut expr = None;
for (i, _) in field_list.fields().enumerate() {
- let idx = format!("{}", i);
+ let idx = format!("{i}");
let lhs = make::expr_path(make::ext::ident_path("self"));
let lhs = make::expr_field(lhs, &idx);
let rhs = make::expr_path(make::ext::ident_path("other"));
@@ -628,7 +628,7 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
Some(ast::FieldList::TupleFieldList(field_list)) => {
let mut exprs = vec![];
for (i, _) in field_list.fields().enumerate() {
- let idx = format!("{}", i);
+ let idx = format!("{i}");
let lhs = make::expr_path(make::ext::ident_path("self"));
let lhs = make::expr_field(lhs, &idx);
let rhs = make::expr_path(make::ext::ident_path("other"));
diff --git a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml
index 75835bce9..11310e2f1 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
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 e82cbfdcb..7384a3f2d 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
@@ -157,7 +157,7 @@ fn complete_trait_impl(
add_function_impl(acc, ctx, replacement_range, func, hir_impl)
}
(hir::AssocItem::TypeAlias(type_alias), All | TypeAlias) => {
- add_type_alias_impl(acc, ctx, replacement_range, type_alias)
+ add_type_alias_impl(acc, ctx, replacement_range, type_alias, hir_impl)
}
(hir::AssocItem::Const(const_), All | Const) => {
add_const_impl(acc, ctx, replacement_range, const_, hir_impl)
@@ -236,9 +236,7 @@ fn get_transformed_assoc_item(
);
transform.apply(assoc_item.syntax());
- if let ast::AssocItem::Fn(func) = &assoc_item {
- func.remove_attrs_and_docs();
- }
+ assoc_item.remove_attrs_and_docs();
Some(assoc_item)
}
@@ -247,24 +245,50 @@ fn add_type_alias_impl(
ctx: &CompletionContext<'_>,
replacement_range: TextRange,
type_alias: hir::TypeAlias,
+ impl_def: hir::Impl,
) {
- let alias_name = type_alias.name(ctx.db);
- let (alias_name, escaped_name) =
- (alias_name.unescaped().to_smol_str(), alias_name.to_smol_str());
+ let alias_name = type_alias.name(ctx.db).unescaped().to_smol_str();
let label = format!("type {} =", alias_name);
- let replacement = format!("type {} = ", escaped_name);
let mut item = CompletionItem::new(SymbolKind::TypeAlias, replacement_range, label);
item.lookup_by(format!("type {}", alias_name))
.set_documentation(type_alias.docs(ctx.db))
.set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() });
- match ctx.config.snippet_cap {
- Some(cap) => item
- .snippet_edit(cap, TextEdit::replace(replacement_range, format!("{}$0;", replacement))),
- None => item.text_edit(TextEdit::replace(replacement_range, replacement)),
- };
- item.add_to(acc);
+
+ if let Some(source) = ctx.sema.source(type_alias) {
+ let assoc_item = ast::AssocItem::TypeAlias(source.value);
+ if let Some(transformed_item) = get_transformed_assoc_item(ctx, assoc_item, impl_def) {
+ let transformed_ty = match transformed_item {
+ ast::AssocItem::TypeAlias(ty) => ty,
+ _ => unreachable!(),
+ };
+
+ let start = transformed_ty.syntax().text_range().start();
+ let Some(end) = transformed_ty
+ .eq_token()
+ .map(|tok| tok.text_range().start())
+ .or(transformed_ty.semicolon_token().map(|tok| tok.text_range().start())) else { return };
+
+ let len = end - start;
+ let mut decl = transformed_ty.syntax().text().slice(..len).to_string();
+ if !decl.ends_with(' ') {
+ decl.push(' ');
+ }
+ decl.push_str("= ");
+
+ match ctx.config.snippet_cap {
+ Some(cap) => {
+ let snippet = format!("{}$0;", decl);
+ item.snippet_edit(cap, TextEdit::replace(replacement_range, snippet));
+ }
+ None => {
+ item.text_edit(TextEdit::replace(replacement_range, decl));
+ }
+ };
+ item.add_to(acc);
+ }
+ }
}
fn add_const_impl(
@@ -309,7 +333,6 @@ fn add_const_impl(
}
fn make_const_compl_syntax(const_: &ast::Const, needs_whitespace: bool) -> String {
- const_.remove_attrs_and_docs();
let const_ = if needs_whitespace {
insert_whitespace_into_node::insert_ws_into(const_.syntax().clone())
} else {
@@ -333,8 +356,6 @@ fn make_const_compl_syntax(const_: &ast::Const, needs_whitespace: bool) -> Strin
}
fn function_declaration(node: &ast::Fn, needs_whitespace: bool) -> String {
- node.remove_attrs_and_docs();
-
let node = if needs_whitespace {
insert_whitespace_into_node::insert_ws_into(node.syntax().clone())
} else {
@@ -350,9 +371,7 @@ fn function_declaration(node: &ast::Fn, needs_whitespace: bool) -> String {
.map_or(end, |f| f.text_range().start());
let len = end - start;
- let range = TextRange::new(0.into(), len);
-
- let syntax = node.text().slice(range).to_string();
+ let syntax = node.text().slice(..len).to_string();
syntax.trim_end().to_owned()
}
@@ -1163,4 +1182,104 @@ impl Foo for Test {
"#,
);
}
+
+ #[test]
+ fn includes_gat_generics() {
+ check_edit(
+ "type Ty",
+ r#"
+trait Tr<'b> {
+ type Ty<'a: 'b, T: Copy, const C: usize>;
+}
+
+impl<'b> Tr<'b> for () {
+ $0
+}
+"#,
+ r#"
+trait Tr<'b> {
+ type Ty<'a: 'b, T: Copy, const C: usize>;
+}
+
+impl<'b> Tr<'b> for () {
+ type Ty<'a: 'b, T: Copy, const C: usize> = $0;
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn strips_comments() {
+ check_edit(
+ "fn func",
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ fn func();
+}
+impl Tr for () {
+ $0
+}
+"#,
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ fn func();
+}
+impl Tr for () {
+ fn func() {
+ $0
+}
+}
+"#,
+ );
+ check_edit(
+ "const C",
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ const C: usize;
+}
+impl Tr for () {
+ $0
+}
+"#,
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ const C: usize;
+}
+impl Tr for () {
+ const C: usize = $0;
+}
+"#,
+ );
+ check_edit(
+ "type Item",
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ type Item;
+}
+impl Tr for () {
+ $0
+}
+"#,
+ r#"
+trait Tr {
+ /// docs
+ #[attr]
+ type Item;
+}
+impl Tr for () {
+ type Item = $0;
+}
+"#,
+ );
+ }
}
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 9a891cea2..b9bd47f7d 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
@@ -69,10 +69,6 @@ pub(crate) fn complete_postfix(
}
}
- if !ctx.config.snippets.is_empty() {
- add_custom_postfix_completions(acc, ctx, &postfix_snippet, &receiver_text);
- }
-
let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty.strip_references());
if let Some(try_enum) = &try_enum {
match try_enum {
@@ -140,6 +136,10 @@ pub(crate) fn complete_postfix(
None => return,
};
+ if !ctx.config.snippets.is_empty() {
+ add_custom_postfix_completions(acc, ctx, &postfix_snippet, &receiver_text);
+ }
+
match try_enum {
Some(try_enum) => match try_enum {
TryEnum::Result => {
@@ -613,4 +613,25 @@ fn main() {
r#"fn main() { log::error!("{}", 2+2) }"#,
);
}
+
+ #[test]
+ fn postfix_custom_snippets_completion_for_references() {
+ check_edit_with_config(
+ CompletionConfig {
+ snippets: vec![Snippet::new(
+ &[],
+ &["ok".into()],
+ &["Ok(${receiver})".into()],
+ "",
+ &[],
+ crate::SnippetScope::Expr,
+ )
+ .unwrap()],
+ ..TEST_CONFIG
+ },
+ "ok",
+ r#"fn main() { &&42.$0 }"#,
+ r#"fn main() { Ok(&&42) }"#,
+ );
+ }
}
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 04111ec7e..c142a7305 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
@@ -681,9 +681,13 @@ fn classify_name_ref(
ast::Item::ExternBlock(it) => it.extern_item_list().is_none(),
ast::Item::Fn(it) => it.body().is_none(),
ast::Item::Impl(it) => it.assoc_item_list().is_none(),
- ast::Item::Module(it) => it.item_list().is_none(),
+ ast::Item::Module(it) => {
+ it.item_list().is_none() && it.semicolon_token().is_none()
+ }
ast::Item::Static(it) => it.body().is_none(),
- ast::Item::Struct(it) => it.field_list().is_none(),
+ ast::Item::Struct(it) => {
+ it.field_list().is_none() && it.semicolon_token().is_none()
+ }
ast::Item::Trait(it) => it.assoc_item_list().is_none(),
ast::Item::TypeAlias(it) => it.ty().is_none(),
ast::Item::Union(it) => it.record_field_list().is_none(),
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs
index 5076c6e86..8ed6cb3cf 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/item_list.rs
@@ -245,3 +245,35 @@ impl Test for () {
"#]],
);
}
+
+#[test]
+fn after_unit_struct() {
+ check(
+ r#"struct S; f$0"#,
+ expect![[r#"
+ ma makro!(…) macro_rules! makro
+ md module
+ kw const
+ kw crate::
+ kw enum
+ kw extern
+ kw fn
+ kw impl
+ kw mod
+ kw pub
+ kw pub(crate)
+ kw pub(super)
+ kw self::
+ kw static
+ kw struct
+ kw trait
+ kw type
+ kw union
+ kw unsafe
+ kw use
+ sn macro_rules
+ sn tfn (Test function)
+ sn tmod (Test module)
+ "#]],
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
index cf0bcd5c9..f48cce58c 100644
--- a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/line_index.rs b/src/tools/rust-analyzer/crates/ide-db/src/line_index.rs
index 75d49ff2f..1b8f56187 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/line_index.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/line_index.rs
@@ -58,8 +58,11 @@ impl LineIndex {
let mut utf16_lines = NoHashHashMap::default();
let mut utf16_chars = Vec::new();
- let mut newlines = vec![0.into()];
- let mut curr_row @ mut curr_col = 0.into();
+ let mut newlines = Vec::with_capacity(16);
+ newlines.push(TextSize::from(0));
+
+ let mut curr_row = 0.into();
+ let mut curr_col = 0.into();
let mut line = 0;
for c in text.chars() {
let c_len = TextSize::of(c);
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 82b85f2fa..aa5d7e9be 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -446,33 +446,47 @@ impl<'a> FindUsages<'a> {
})
}
- // 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.
+ let find_nodes = move |name: &str, node: &syntax::SyntaxNode, offset: TextSize| {
+ node.token_at_offset(offset).find(|it| it.text() == name).map(|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())
+ })
+ };
+
for (text, file_id, search_range) in scope_files(sema, &search_scope) {
let tree = Lazy::new(move || sema.parse(file_id).syntax().clone());
// Search for occurrences of the items name
for offset in match_indices(&text, finder, search_range) {
- for name in sema.find_nodes_at_offset_with_descend(&tree, offset) {
- if match name {
- ast::NameLike::NameRef(name_ref) => self.found_name_ref(&name_ref, sink),
- ast::NameLike::Name(name) => self.found_name(&name, sink),
- ast::NameLike::Lifetime(lifetime) => self.found_lifetime(&lifetime, sink),
- } {
- return;
+ if let Some(iter) = find_nodes(name, &tree, offset) {
+ for name in iter.filter_map(ast::NameLike::cast) {
+ if match name {
+ ast::NameLike::NameRef(name_ref) => {
+ self.found_name_ref(&name_ref, sink)
+ }
+ ast::NameLike::Name(name) => self.found_name(&name, sink),
+ ast::NameLike::Lifetime(lifetime) => {
+ self.found_lifetime(&lifetime, sink)
+ }
+ } {
+ return;
+ }
}
}
}
// Search for occurrences of the `Self` referring to our type
if let Some((self_ty, finder)) = &include_self_kw_refs {
for offset in match_indices(&text, finder, search_range) {
- for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
- if self.found_self_ty_name_ref(self_ty, &name_ref, sink) {
- return;
+ if let Some(iter) = find_nodes("Self", &tree, offset) {
+ for name_ref in iter.filter_map(ast::NameRef::cast) {
+ if self.found_self_ty_name_ref(self_ty, &name_ref, sink) {
+ return;
+ }
}
}
}
@@ -493,17 +507,21 @@ impl<'a> FindUsages<'a> {
let tree = Lazy::new(move || sema.parse(file_id).syntax().clone());
for offset in match_indices(&text, finder, search_range) {
- for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
- if self.found_name_ref(&name_ref, sink) {
- return;
+ if let Some(iter) = find_nodes("super", &tree, offset) {
+ for name_ref in iter.filter_map(ast::NameRef::cast) {
+ if self.found_name_ref(&name_ref, sink) {
+ return;
+ }
}
}
}
if let Some(finder) = &is_crate_root {
for offset in match_indices(&text, finder, search_range) {
- for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
- if self.found_name_ref(&name_ref, sink) {
- return;
+ if let Some(iter) = find_nodes("crate", &tree, offset) {
+ for name_ref in iter.filter_map(ast::NameRef::cast) {
+ if self.found_name_ref(&name_ref, sink) {
+ return;
+ }
}
}
}
@@ -544,9 +562,11 @@ impl<'a> FindUsages<'a> {
let finder = &Finder::new("self");
for offset in match_indices(&text, finder, search_range) {
- for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
- if self.found_self_module_name_ref(&name_ref, sink) {
- return;
+ if let Some(iter) = find_nodes("self", &tree, offset) {
+ for name_ref in iter.filter_map(ast::NameRef::cast) {
+ if self.found_self_module_name_ref(&name_ref, sink) {
+ return;
+ }
}
}
}
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs
index ac6c6e8fe..313346ee1 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/format_string_exprs.rs
@@ -104,6 +104,11 @@ pub fn parse_format_exprs(input: &str) -> Result<(String, Vec<Arg>), ()> {
extracted_expressions.push(Arg::Placeholder);
state = State::NotArg;
}
+ (State::MaybeArg, ':') => {
+ output.push(chr);
+ extracted_expressions.push(Arg::Placeholder);
+ state = State::FormatOpts;
+ }
(State::MaybeArg, _) => {
if matches!(chr, '\\' | '$') {
current_expr.push('\\');
@@ -118,44 +123,41 @@ pub fn parse_format_exprs(input: &str) -> Result<(String, Vec<Arg>), ()> {
state = State::Expr;
}
}
- (State::Ident | State::Expr, '}') => {
- if inexpr_open_count == 0 {
- output.push(chr);
-
- if matches!(state, State::Expr) {
- extracted_expressions.push(Arg::Expr(current_expr.trim().into()));
- } else {
- extracted_expressions.push(Arg::Ident(current_expr.trim().into()));
- }
-
- current_expr = String::new();
- state = State::NotArg;
- } else {
- // We're closing one brace met before inside of the expression.
- current_expr.push(chr);
- inexpr_open_count -= 1;
- }
- }
(State::Ident | State::Expr, ':') if matches!(chars.peek(), Some(':')) => {
// path separator
state = State::Expr;
current_expr.push_str("::");
chars.next();
}
- (State::Ident | State::Expr, ':') => {
+ (State::Ident | State::Expr, ':' | '}') => {
if inexpr_open_count == 0 {
- // We're outside of braces, thus assume that it's a specifier, like "{Some(value):?}"
- output.push(chr);
+ let trimmed = current_expr.trim();
- if matches!(state, State::Expr) {
- extracted_expressions.push(Arg::Expr(current_expr.trim().into()));
+ // if the expression consists of a single number, like "0" or "12", it can refer to
+ // format args in the order they are specified.
+ // see: https://doc.rust-lang.org/std/fmt/#positional-parameters
+ if trimmed.chars().fold(true, |only_num, c| c.is_ascii_digit() && only_num) {
+ output.push_str(trimmed);
+ } else if matches!(state, State::Expr) {
+ extracted_expressions.push(Arg::Expr(trimmed.into()));
} else {
- extracted_expressions.push(Arg::Ident(current_expr.trim().into()));
+ extracted_expressions.push(Arg::Ident(trimmed.into()));
}
- current_expr = String::new();
- state = State::FormatOpts;
- } else {
+ output.push(chr);
+ current_expr.clear();
+ state = if chr == ':' {
+ State::FormatOpts
+ } else if chr == '}' {
+ State::NotArg
+ } else {
+ unreachable!()
+ };
+ } else if chr == '}' {
+ // We're closing one brace met before inside of the expression.
+ current_expr.push(chr);
+ inexpr_open_count -= 1;
+ } else if chr == ':' {
// We're inside of braced expression, assume that it's a struct field name/value delimiter.
current_expr.push(chr);
}
@@ -219,6 +221,10 @@ mod tests {
("{expr} is {2 + 2}", expect![["{} is {}; expr, 2 + 2"]]),
("{expr:?}", expect![["{:?}; expr"]]),
("{expr:1$}", expect![[r"{:1\$}; expr"]]),
+ ("{:1$}", expect![[r"{:1\$}; $1"]]),
+ ("{:>padding$}", expect![[r"{:>padding\$}; $1"]]),
+ ("{}, {}, {0}", expect![[r"{}, {}, {0}; $1, $2"]]),
+ ("{}, {}, {0:b}", expect![[r"{}, {}, {0:b}; $1, $2"]]),
("{$0}", expect![[r"{}; \$0"]]),
("{malformed", expect![["-"]]),
("malformed}", expect![["-"]]),
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
index e1d146f4e..7e9a1125d 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
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 43ff4ed5a..870c78d1f 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
@@ -5,10 +5,7 @@ use crate::{Diagnostic, DiagnosticsContext};
// This diagnostic is shown for macro expansion errors.
pub(crate) fn macro_error(ctx: &DiagnosticsContext<'_>, d: &hir::MacroError) -> Diagnostic {
// Use more accurate position if available.
- let display_range = d
- .precise_location
- .unwrap_or_else(|| ctx.sema.diagnostics_display_range(d.node.clone()).range);
-
+ let display_range = ctx.resolve_precise_location(&d.node, d.precise_location);
Diagnostic::new("macro-error", d.message.clone(), display_range).experimental()
}
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 a80299106..d8f2a9de9 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
@@ -268,12 +268,12 @@ fn main() {
foo::Foo { bar: 3, $0baz: false};
}
//- /foo.rs
-struct Foo {
+pub struct Foo {
bar: i32
}
"#,
r#"
-struct Foo {
+pub struct Foo {
bar: i32,
pub(crate) baz: bool
}
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs
index 4b4312475..87531f4ac 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs
@@ -9,10 +9,7 @@ pub(crate) fn unresolved_macro_call(
d: &hir::UnresolvedMacroCall,
) -> Diagnostic {
// Use more accurate position if available.
- let display_range = d
- .precise_location
- .unwrap_or_else(|| ctx.sema.diagnostics_display_range(d.macro_call.clone()).range);
-
+ let display_range = ctx.resolve_precise_location(&d.macro_call, d.precise_location);
let bang = if d.is_bang { "!" } else { "" };
Diagnostic::new(
"unresolved-macro-call",
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs
index 760f51f90..23818d883 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unresolved_proc_macro.rs
@@ -1,5 +1,4 @@
use hir::db::DefDatabase;
-use syntax::NodeOrToken;
use crate::{Diagnostic, DiagnosticsContext, Severity};
@@ -19,16 +18,7 @@ pub(crate) fn unresolved_proc_macro(
proc_attr_macros_enabled: bool,
) -> Diagnostic {
// Use more accurate position if available.
- let display_range = (|| {
- let precise_location = d.precise_location?;
- let root = ctx.sema.parse_or_expand(d.node.file_id)?;
- match root.covering_element(precise_location) {
- NodeOrToken::Node(it) => Some(ctx.sema.original_range(&it)),
- NodeOrToken::Token(it) => d.node.with_value(it).original_file_range_opt(ctx.sema.db),
- }
- })()
- .unwrap_or_else(|| ctx.sema.diagnostics_display_range(d.node.clone()))
- .range;
+ let display_range = ctx.resolve_precise_location(&d.node, d.precise_location);
let config_enabled = match d.kind {
hir::MacroKind::Attr => proc_macros_enabled && proc_attr_macros_enabled,
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 8b9330e04..289ed0458 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
@@ -71,9 +71,9 @@ use a;
use a::{c, d::e};
mod a {
- mod c {}
- mod d {
- mod e {}
+ pub mod c {}
+ pub mod d {
+ pub mod e {}
}
}
"#,
@@ -87,9 +87,9 @@ use a::{
};
mod a {
- mod c {}
- mod d {
- mod e {}
+ pub mod c {}
+ pub mod d {
+ pub mod e {}
}
}
"#,
@@ -116,11 +116,11 @@ use b;
);
check_fix(
r#"
-mod a { mod c {} }
+mod a { pub mod c {} }
use a::{c$0};
"#,
r#"
-mod a { mod c {} }
+mod a { pub mod c {} }
use a::c;
"#,
);
@@ -136,11 +136,11 @@ use a;
);
check_fix(
r#"
-mod a { mod c {} mod d { mod e {} } }
+mod a { pub mod c {} pub mod d { pub mod e {} } }
use a::{c, d::{e$0}};
"#,
r#"
-mod a { mod c {} mod d { mod e {} } }
+mod a { pub mod c {} pub mod d { pub mod e {} } }
use a::{c, d::e};
"#,
);
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 ae299f058..d81e36a1f 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
@@ -182,6 +182,28 @@ struct DiagnosticsContext<'a> {
resolve: &'a AssistResolveStrategy,
}
+impl<'a> DiagnosticsContext<'a> {
+ fn resolve_precise_location(
+ &self,
+ node: &InFile<SyntaxNodePtr>,
+ precise_location: Option<TextRange>,
+ ) -> TextRange {
+ let sema = &self.sema;
+ (|| {
+ let precise_location = precise_location?;
+ let root = sema.parse_or_expand(node.file_id)?;
+ match root.covering_element(precise_location) {
+ syntax::NodeOrToken::Node(it) => Some(sema.original_range(&it)),
+ syntax::NodeOrToken::Token(it) => {
+ node.with_value(it).original_file_range_opt(sema.db)
+ }
+ }
+ })()
+ .unwrap_or_else(|| sema.diagnostics_display_range(node.clone()))
+ .range
+ }
+}
+
pub fn diagnostics(
db: &RootDatabase,
config: &DiagnosticsConfig,
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml
index 4baf786c4..7be62a8d9 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml
@@ -5,7 +5,7 @@ description = "Structural search and replace of Rust code"
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/rust-analyzer"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/ide/Cargo.toml b/src/tools/rust-analyzer/crates/ide/Cargo.toml
index 712459a7e..73f202630 100644
--- a/src/tools/rust-analyzer/crates/ide/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
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 d0be1b3f4..43f7a529b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -289,10 +289,10 @@ mod b;
enum E { X(Foo$0) }
//- /a.rs
-struct Foo;
- //^^^
+pub struct Foo;
+ //^^^
//- /b.rs
-struct Foo;
+pub struct Foo;
"#,
);
}
@@ -1834,4 +1834,86 @@ fn f() {
"#,
);
}
+
+ #[test]
+ fn goto_bin_op_multiple_impl() {
+ check(
+ r#"
+//- minicore: add
+struct S;
+impl core::ops::Add for S {
+ fn add(
+ //^^^
+ ) {}
+}
+impl core::ops::Add<usize> for S {
+ fn add(
+ ) {}
+}
+
+fn f() {
+ S +$0 S
+}
+"#,
+ );
+
+ check(
+ r#"
+//- minicore: add
+struct S;
+impl core::ops::Add for S {
+ fn add(
+ ) {}
+}
+impl core::ops::Add<usize> for S {
+ fn add(
+ //^^^
+ ) {}
+}
+
+fn f() {
+ S +$0 0usize
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn path_call_multiple_trait_impl() {
+ check(
+ r#"
+trait Trait<T> {
+ fn f(_: T);
+}
+impl Trait<i32> for usize {
+ fn f(_: i32) {}
+ //^
+}
+impl Trait<i64> for usize {
+ fn f(_: i64) {}
+}
+fn main() {
+ usize::f$0(0i32);
+}
+"#,
+ );
+
+ check(
+ r#"
+trait Trait<T> {
+ fn f(_: T);
+}
+impl Trait<i32> for usize {
+ fn f(_: i32) {}
+}
+impl Trait<i64> for usize {
+ fn f(_: i64) {}
+ //^
+}
+fn main() {
+ usize::f$0(0i64);
+}
+"#,
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index 3687b597f..838fb18c3 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -119,7 +119,14 @@ pub(crate) fn hover(
});
}
- let in_attr = matches!(original_token.parent().and_then(ast::TokenTree::cast), Some(tt) if tt.syntax().ancestors().any(|it| ast::Meta::can_cast(it.kind())));
+ let in_attr = original_token
+ .parent_ancestors()
+ .filter_map(ast::Item::cast)
+ .any(|item| sema.is_attr_macro_call(&item))
+ && !matches!(
+ original_token.parent().and_then(ast::TokenTree::cast),
+ Some(tt) if tt.syntax().ancestors().any(|it| ast::Meta::can_cast(it.kind()))
+ );
// prefer descending the same token kind in attribute expansions, in normal macros text
// equivalency is more important
let descended = if in_attr {
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 34d8bf67a..37384c4e7 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
@@ -1,7 +1,10 @@
use std::fmt;
use either::Either;
-use hir::{known, Callable, HasVisibility, HirDisplay, Mutability, Semantics, TypeInfo};
+use hir::{
+ known, Adjust, AutoBorrow, Callable, HasVisibility, HirDisplay, Mutability, OverloadedDeref,
+ PointerCast, Safety, Semantics, TypeInfo,
+};
use ide_db::{
base_db::FileRange, famous_defs::FamousDefs, syntax_helpers::node_ext::walk_ty, FxHashMap,
RootDatabase,
@@ -22,7 +25,7 @@ pub struct InlayHintsConfig {
pub type_hints: bool,
pub parameter_hints: bool,
pub chaining_hints: bool,
- pub reborrow_hints: ReborrowHints,
+ pub adjustment_hints: AdjustmentHints,
pub closure_return_type_hints: ClosureReturnTypeHints,
pub binding_mode_hints: bool,
pub lifetime_elision_hints: LifetimeElisionHints,
@@ -48,9 +51,9 @@ pub enum LifetimeElisionHints {
}
#[derive(Clone, Debug, PartialEq, Eq)]
-pub enum ReborrowHints {
+pub enum AdjustmentHints {
Always,
- MutableOnly,
+ ReborrowOnly,
Never,
}
@@ -61,7 +64,8 @@ pub enum InlayKind {
ClosingBraceHint,
ClosureReturnTypeHint,
GenericParamListHint,
- ImplicitReborrowHint,
+ AdjustmentHint,
+ AdjustmentHintClosingParenthesis,
LifetimeHint,
ParameterHint,
TypeHint,
@@ -115,6 +119,12 @@ impl From<String> for InlayHintLabel {
}
}
+impl From<&str> for InlayHintLabel {
+ fn from(s: &str) -> Self {
+ Self { parts: vec![InlayHintLabelPart { text: s.into(), linked_location: None }] }
+ }
+}
+
impl fmt::Display for InlayHintLabel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.parts.iter().map(|part| &part.text).format(""))
@@ -180,7 +190,7 @@ impl fmt::Debug for InlayHintLabelPart {
pub(crate) fn inlay_hints(
db: &RootDatabase,
file_id: FileId,
- range_limit: Option<FileRange>,
+ range_limit: Option<TextRange>,
config: &InlayHintsConfig,
) -> Vec<InlayHint> {
let _p = profile::span("inlay_hints");
@@ -195,7 +205,7 @@ pub(crate) fn inlay_hints(
let hints = |node| hints(&mut acc, &famous_defs, config, file_id, node);
match range_limit {
- Some(FileRange { range, .. }) => match file.covering_element(range) {
+ Some(range) => match file.covering_element(range) {
NodeOrToken::Token(_) => return acc,
NodeOrToken::Node(n) => n
.descendants()
@@ -221,6 +231,7 @@ fn hints(
match node {
ast::Expr(expr) => {
chaining_hints(hints, sema, &famous_defs, config, file_id, &expr);
+ adjustment_hints(hints, sema, config, &expr);
match expr {
ast::Expr::CallExpr(it) => param_name_hints(hints, sema, config, ast::Expr::from(it)),
ast::Expr::MethodCallExpr(it) => {
@@ -229,7 +240,7 @@ fn hints(
ast::Expr::ClosureExpr(it) => closure_ret_hints(hints, sema, &famous_defs, config, file_id, it),
// We could show reborrows for all expressions, but usually that is just noise to the user
// and the main point here is to show why "moving" a mutable reference doesn't necessarily move it
- ast::Expr::PathExpr(_) => reborrow_hints(hints, sema, config, &expr),
+ // ast::Expr::PathExpr(_) => reborrow_hints(hints, sema, config, &expr),
_ => None,
}
},
@@ -617,30 +628,95 @@ fn closure_ret_hints(
Some(())
}
-fn reborrow_hints(
+fn adjustment_hints(
acc: &mut Vec<InlayHint>,
sema: &Semantics<'_, RootDatabase>,
config: &InlayHintsConfig,
expr: &ast::Expr,
) -> Option<()> {
- if config.reborrow_hints == ReborrowHints::Never {
+ if config.adjustment_hints == AdjustmentHints::Never {
+ return None;
+ }
+
+ if let ast::Expr::ParenExpr(_) = expr {
+ // These inherit from the inner expression which would result in duplicate hints
return None;
}
+ let parent = expr.syntax().parent().and_then(ast::Expr::cast);
let descended = sema.descend_node_into_attributes(expr.clone()).pop();
let desc_expr = descended.as_ref().unwrap_or(expr);
- let mutability = sema.is_implicit_reborrow(desc_expr)?;
- let label = match mutability {
- hir::Mutability::Shared if config.reborrow_hints != ReborrowHints::MutableOnly => "&*",
- hir::Mutability::Mut => "&mut *",
- _ => return None,
+ let adjustments = sema.expr_adjustments(desc_expr).filter(|it| !it.is_empty())?;
+ let needs_parens = match parent {
+ Some(parent) => {
+ match parent {
+ ast::Expr::AwaitExpr(_)
+ | ast::Expr::CallExpr(_)
+ | ast::Expr::CastExpr(_)
+ | ast::Expr::FieldExpr(_)
+ | ast::Expr::MethodCallExpr(_)
+ | ast::Expr::TryExpr(_) => true,
+ // FIXME: shorthands need special casing, though not sure if adjustments are even valid there
+ ast::Expr::RecordExpr(_) => false,
+ ast::Expr::IndexExpr(index) => index.base().as_ref() == Some(expr),
+ _ => false,
+ }
+ }
+ None => false,
};
- acc.push(InlayHint {
- range: expr.syntax().text_range(),
- kind: InlayKind::ImplicitReborrowHint,
- label: label.to_string().into(),
- tooltip: Some(InlayTooltip::String("Compiler inserted reborrow".into())),
- });
+ if needs_parens {
+ acc.push(InlayHint {
+ range: expr.syntax().text_range(),
+ kind: InlayKind::AdjustmentHint,
+ label: "(".into(),
+ tooltip: None,
+ });
+ }
+ for adjustment in adjustments.into_iter().rev() {
+ // FIXME: Add some nicer tooltips to each of these
+ let text = match adjustment {
+ Adjust::NeverToAny if config.adjustment_hints == AdjustmentHints::Always => {
+ "<never-to-any>"
+ }
+ Adjust::Deref(None) => "*",
+ Adjust::Deref(Some(OverloadedDeref(Mutability::Mut))) => "*",
+ Adjust::Deref(Some(OverloadedDeref(Mutability::Shared))) => "*",
+ Adjust::Borrow(AutoBorrow::Ref(Mutability::Shared)) => "&",
+ Adjust::Borrow(AutoBorrow::Ref(Mutability::Mut)) => "&mut ",
+ Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Shared)) => "&raw const ",
+ Adjust::Borrow(AutoBorrow::RawPtr(Mutability::Mut)) => "&raw mut ",
+ // some of these could be represented via `as` casts, but that's not too nice and
+ // handling everything as a prefix expr makes the `(` and `)` insertion easier
+ Adjust::Pointer(cast) if config.adjustment_hints == AdjustmentHints::Always => {
+ match cast {
+ PointerCast::ReifyFnPointer => "<fn-item-to-fn-pointer>",
+ PointerCast::UnsafeFnPointer => "<safe-fn-pointer-to-unsafe-fn-pointer>",
+ PointerCast::ClosureFnPointer(Safety::Unsafe) => {
+ "<closure-to-unsafe-fn-pointer>"
+ }
+ PointerCast::ClosureFnPointer(Safety::Safe) => "<closure-to-fn-pointer>",
+ PointerCast::MutToConstPointer => "<mut-ptr-to-const-ptr>",
+ PointerCast::ArrayToPointer => "<array-ptr-to-element-ptr>",
+ PointerCast::Unsize => "<unsize>",
+ }
+ }
+ _ => continue,
+ };
+ acc.push(InlayHint {
+ range: expr.syntax().text_range(),
+ kind: InlayKind::AdjustmentHint,
+ label: text.into(),
+ tooltip: None,
+ });
+ }
+ if needs_parens {
+ acc.push(InlayHint {
+ range: expr.syntax().text_range(),
+ kind: InlayKind::AdjustmentHintClosingParenthesis,
+ label: ")".into(),
+ tooltip: None,
+ });
+ }
Some(())
}
@@ -1213,12 +1289,11 @@ fn get_callable(
#[cfg(test)]
mod tests {
use expect_test::{expect, Expect};
- use ide_db::base_db::FileRange;
use itertools::Itertools;
use syntax::{TextRange, TextSize};
use test_utils::extract_annotations;
- use crate::inlay_hints::ReborrowHints;
+ use crate::inlay_hints::AdjustmentHints;
use crate::{fixture, inlay_hints::InlayHintsConfig, LifetimeElisionHints};
use super::ClosureReturnTypeHints;
@@ -1230,7 +1305,7 @@ mod tests {
chaining_hints: false,
lifetime_elision_hints: LifetimeElisionHints::Never,
closure_return_type_hints: ClosureReturnTypeHints::Never,
- reborrow_hints: ReborrowHints::Always,
+ adjustment_hints: AdjustmentHints::Never,
binding_mode_hints: false,
hide_named_constructor_hints: false,
hide_closure_initialization_hints: false,
@@ -1242,7 +1317,6 @@ mod tests {
type_hints: true,
parameter_hints: true,
chaining_hints: true,
- reborrow_hints: ReborrowHints::Always,
closure_return_type_hints: ClosureReturnTypeHints::WithBlock,
binding_mode_hints: true,
lifetime_elision_hints: LifetimeElisionHints::Always,
@@ -1838,10 +1912,7 @@ fn main() {
.inlay_hints(
&InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG },
file_id,
- Some(FileRange {
- file_id,
- range: TextRange::new(TextSize::from(500), TextSize::from(600)),
- }),
+ Some(TextRange::new(TextSize::from(500), TextSize::from(600))),
)
.unwrap();
let actual =
@@ -2846,48 +2917,6 @@ impl () {
}
#[test]
- fn hints_implicit_reborrow() {
- check_with_config(
- InlayHintsConfig {
- reborrow_hints: ReborrowHints::Always,
- parameter_hints: true,
- ..DISABLED_CONFIG
- },
- r#"
-fn __() {
- let unique = &mut ();
- let r_mov = unique;
- let foo: &mut _ = unique;
- //^^^^^^ &mut *
- ref_mut_id(unique);
- //^^^^^^ mut_ref
- //^^^^^^ &mut *
- let shared = ref_id(unique);
- //^^^^^^ shared_ref
- //^^^^^^ &*
- let mov = shared;
- let r_mov: &_ = shared;
- ref_id(shared);
- //^^^^^^ shared_ref
-
- identity(unique);
- identity(shared);
-}
-fn identity<T>(t: T) -> T {
- t
-}
-fn ref_mut_id(mut_ref: &mut ()) -> &mut () {
- mut_ref
- //^^^^^^^ &mut *
-}
-fn ref_id(shared_ref: &()) -> &() {
- shared_ref
-}
-"#,
- );
- }
-
- #[test]
fn hints_binding_modes() {
check_with_config(
InlayHintsConfig { binding_mode_hints: true, ..DISABLED_CONFIG },
@@ -2994,4 +3023,76 @@ fn f() {
"#,
);
}
+
+ #[test]
+ fn adjustment_hints() {
+ check_with_config(
+ InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG },
+ r#"
+//- minicore: coerce_unsized
+fn main() {
+ let _: u32 = loop {};
+ //^^^^^^^<never-to-any>
+ let _: &u32 = &mut 0;
+ //^^^^^^&
+ //^^^^^^*
+ let _: &mut u32 = &mut 0;
+ //^^^^^^&mut $
+ //^^^^^^*
+ let _: *const u32 = &mut 0;
+ //^^^^^^&raw const $
+ //^^^^^^*
+ let _: *mut u32 = &mut 0;
+ //^^^^^^&raw mut $
+ //^^^^^^*
+ let _: fn() = main;
+ //^^^^<fn-item-to-fn-pointer>
+ let _: unsafe fn() = main;
+ //^^^^<safe-fn-pointer-to-unsafe-fn-pointer>
+ //^^^^<fn-item-to-fn-pointer>
+ let _: unsafe fn() = main as fn();
+ //^^^^^^^^^^^^<safe-fn-pointer-to-unsafe-fn-pointer>
+ let _: fn() = || {};
+ //^^^^^<closure-to-fn-pointer>
+ let _: unsafe fn() = || {};
+ //^^^^^<closure-to-unsafe-fn-pointer>
+ let _: *const u32 = &mut 0u32 as *mut u32;
+ //^^^^^^^^^^^^^^^^^^^^^<mut-ptr-to-const-ptr>
+ let _: &mut [_] = &mut [0; 0];
+ //^^^^^^^^^^^<unsize>
+ //^^^^^^^^^^^&mut $
+ //^^^^^^^^^^^*
+
+ Struct.consume();
+ Struct.by_ref();
+ //^^^^^^(
+ //^^^^^^&
+ //^^^^^^)
+ Struct.by_ref_mut();
+ //^^^^^^(
+ //^^^^^^&mut $
+ //^^^^^^)
+
+ (&Struct).consume();
+ //^^^^^^^*
+ (&Struct).by_ref();
+
+ (&mut Struct).consume();
+ //^^^^^^^^^^^*
+ (&mut Struct).by_ref();
+ //^^^^^^^^^^^&
+ //^^^^^^^^^^^*
+ (&mut Struct).by_ref_mut();
+}
+
+#[derive(Copy, Clone)]
+struct Struct;
+impl Struct {
+ fn consume(self) {}
+ fn by_ref(&self) {}
+ fn by_ref_mut(&mut self) {}
+}
+"#,
+ )
+ }
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index 416817ca0..7402e86f3 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -81,8 +81,8 @@ pub use crate::{
highlight_related::{HighlightRelatedConfig, HighlightedRange},
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
inlay_hints::{
- ClosureReturnTypeHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind,
- InlayTooltip, LifetimeElisionHints, ReborrowHints,
+ AdjustmentHints, ClosureReturnTypeHints, InlayHint, InlayHintLabel, InlayHintsConfig,
+ InlayKind, InlayTooltip, LifetimeElisionHints,
},
join_lines::JoinLinesConfig,
markup::Markup,
@@ -367,7 +367,7 @@ impl Analysis {
&self,
config: &InlayHintsConfig,
file_id: FileId,
- range: Option<FileRange>,
+ range: Option<TextRange>,
) -> Cancellable<Vec<InlayHint>> {
self.with_db(|db| inlay_hints::inlay_hints(db, file_id, range, config))
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
index 852a8fd83..fcbf6d8e5 100644
--- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
@@ -1,9 +1,9 @@
//! This module generates [moniker](https://microsoft.github.io/language-server-protocol/specifications/lsif/0.6.0/specification/#exportsImports)
//! for LSIF and LSP.
-use hir::{db::DefDatabase, AsAssocItem, AssocItemContainer, Crate, Name, Semantics};
+use hir::{AsAssocItem, AssocItemContainer, Crate, Name, Semantics};
use ide_db::{
- base_db::{CrateOrigin, FileId, FileLoader, FilePosition, LangCrateOrigin},
+ base_db::{CrateOrigin, FilePosition, LangCrateOrigin},
defs::{Definition, IdentClass},
helpers::pick_best_token,
RootDatabase,
@@ -11,7 +11,7 @@ use ide_db::{
use itertools::Itertools;
use syntax::{AstNode, SyntaxKind::*, T};
-use crate::{doc_links::token_as_doc_comment, RangeInfo};
+use crate::{doc_links::token_as_doc_comment, parent_module::crates_for, RangeInfo};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum MonikerDescriptorKind {
@@ -73,20 +73,8 @@ impl MonikerResult {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PackageInformation {
pub name: String,
- pub repo: String,
- pub version: String,
-}
-
-pub(crate) fn crate_for_file(db: &RootDatabase, file_id: FileId) -> Option<Crate> {
- for &krate in db.relevant_crates(file_id).iter() {
- let crate_def_map = db.crate_def_map(krate);
- for (_, data) in crate_def_map.modules() {
- if data.origin.file_id() == Some(file_id) {
- return Some(krate.into());
- }
- }
- }
- None
+ pub repo: Option<String>,
+ pub version: Option<String>,
}
pub(crate) fn moniker(
@@ -95,7 +83,7 @@ pub(crate) fn moniker(
) -> Option<RangeInfo<Vec<MonikerResult>>> {
let sema = &Semantics::new(db);
let file = sema.parse(file_id).syntax().clone();
- let current_crate = crate_for_file(db, file_id)?;
+ let current_crate: hir::Crate = crates_for(db, file_id).pop()?.into();
let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind {
IDENT
| INT_NUMBER
@@ -256,18 +244,18 @@ pub(crate) fn def_to_moniker(
let (name, repo, version) = match krate.origin(db) {
CrateOrigin::CratesIo { repo, name } => (
name.unwrap_or(krate.display_name(db)?.canonical_name().to_string()),
- repo?,
- krate.version(db)?,
+ repo,
+ krate.version(db),
),
CrateOrigin::Lang(lang) => (
krate.display_name(db)?.canonical_name().to_string(),
- "https://github.com/rust-lang/rust/".to_string(),
- match lang {
+ Some("https://github.com/rust-lang/rust/".to_string()),
+ Some(match lang {
LangCrateOrigin::Other => {
"https://github.com/rust-lang/rust/library/".into()
}
lang => format!("https://github.com/rust-lang/rust/library/{lang}",),
- },
+ }),
),
};
PackageInformation { name, repo, version }
@@ -315,7 +303,7 @@ pub mod module {
}
"#,
"foo::module::func",
- r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+ r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
MonikerKind::Import,
);
check_moniker(
@@ -331,7 +319,7 @@ pub mod module {
}
"#,
"foo::module::func",
- r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+ r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
MonikerKind::Export,
);
}
@@ -348,7 +336,7 @@ pub mod module {
}
"#,
"foo::module::MyTrait::func",
- r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+ r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
MonikerKind::Export,
);
}
@@ -365,7 +353,7 @@ pub mod module {
}
"#,
"foo::module::MyTrait::MY_CONST",
- r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+ r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
MonikerKind::Export,
);
}
@@ -382,7 +370,7 @@ pub mod module {
}
"#,
"foo::module::MyTrait::MyType",
- r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+ r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
MonikerKind::Export,
);
}
@@ -405,7 +393,7 @@ pub mod module {
}
"#,
"foo::module::MyStruct::MyTrait::func",
- r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+ r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
MonikerKind::Export,
);
}
@@ -425,7 +413,7 @@ pub struct St {
}
"#,
"foo::St::a",
- r#"PackageInformation { name: "foo", repo: "https://a.b/foo.git", version: "0.1.0" }"#,
+ r#"PackageInformation { name: "foo", repo: Some("https://a.b/foo.git"), version: Some("0.1.0") }"#,
MonikerKind::Import,
);
}
diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs
index e942413c1..0f758cfa2 100644
--- a/src/tools/rust-analyzer/crates/ide/src/references.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/references.rs
@@ -16,6 +16,7 @@ use ide_db::{
search::{ReferenceCategory, SearchScope, UsageSearchResult},
RootDatabase,
};
+use itertools::Itertools;
use stdx::hash::NoHashHashMap;
use syntax::{
algo::find_node_at_offset,
@@ -86,6 +87,7 @@ pub(crate) fn find_all_refs(
file_id,
refs.into_iter()
.map(|file_ref| (file_ref.range, file_ref.category))
+ .unique()
.collect(),
)
})
diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs
index fe44856dc..b4df04370 100644
--- a/src/tools/rust-analyzer/crates/ide/src/rename.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs
@@ -40,7 +40,9 @@ pub(crate) fn prepare_rename(
if def.range_for_rename(&sema).is_none() {
bail!("No references found at position")
}
- let frange = sema.original_range(name_like.syntax());
+ let Some(frange) = sema.original_range_opt(name_like.syntax()) else {
+ bail!("No references found at position");
+ };
always!(
frange.range.contains_inclusive(position.offset)
@@ -51,7 +53,7 @@ pub(crate) fn prepare_rename(
.reduce(|acc, cur| match (acc, cur) {
// ensure all ranges are the same
(Ok(acc_inner), Ok(cur_inner)) if acc_inner == cur_inner => Ok(acc_inner),
- (Err(e), _) => Err(e),
+ (e @ Err(_), _) | (_, e @ Err(_)) => e,
_ => bail!("inconsistent text range"),
});
@@ -2249,4 +2251,33 @@ fn foo((bar | bar | bar): ()) {
"#,
);
}
+
+ #[test]
+ fn regression_13498() {
+ check(
+ "Testing",
+ r"
+mod foo {
+ pub struct Test$0;
+}
+
+use foo::Test as Tester;
+
+fn main() {
+ let t = Tester;
+}
+",
+ r"
+mod foo {
+ pub struct Testing;
+}
+
+use foo::Testing as Tester;
+
+fn main() {
+ let t = Tester;
+}
+",
+ )
+ }
}
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 fedc1a435..e7412d27f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs
@@ -149,7 +149,7 @@ fn signature_help_for_call(
variant.name(db)
);
}
- hir::CallableKind::Closure | hir::CallableKind::FnPtr => (),
+ hir::CallableKind::Closure | hir::CallableKind::FnPtr | hir::CallableKind::Other => (),
}
res.signature.push('(');
@@ -189,9 +189,10 @@ fn signature_help_for_call(
hir::CallableKind::Function(func) if callable.return_type().contains_unknown() => {
render(func.ret_type(db))
}
- hir::CallableKind::Function(_) | hir::CallableKind::Closure | hir::CallableKind::FnPtr => {
- render(callable.return_type())
- }
+ hir::CallableKind::Function(_)
+ | hir::CallableKind::Closure
+ | hir::CallableKind::FnPtr
+ | hir::CallableKind::Other => render(callable.return_type()),
hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_) => {}
}
Some(res)
@@ -387,10 +388,9 @@ mod tests {
}
fn check(ra_fixture: &str, expect: Expect) {
- // Implicitly add `Sized` to avoid noisy `T: ?Sized` in the results.
let fixture = format!(
r#"
-#[lang = "sized"] trait Sized {{}}
+//- minicore: sized, fn
{ra_fixture}
"#
);
@@ -1331,4 +1331,50 @@ fn f() {
"#]],
);
}
+
+ #[test]
+ fn help_for_generic_call() {
+ check(
+ r#"
+fn f<F: FnOnce(u8, u16) -> i32>(f: F) {
+ f($0)
+}
+"#,
+ expect![[r#"
+ (u8, u16) -> i32
+ ^^ ---
+ "#]],
+ );
+ check(
+ r#"
+fn f<T, F: FnOnce(&T, u16) -> &T>(f: F) {
+ f($0)
+}
+"#,
+ expect![[r#"
+ (&T, u16) -> &T
+ ^^ ---
+ "#]],
+ );
+ }
+
+ #[test]
+ fn regression_13579() {
+ check(
+ r#"
+fn f() {
+ take(2)($0);
+}
+
+fn take<C, Error>(
+ count: C
+) -> impl Fn() -> C {
+ move || count
+}
+"#,
+ expect![[r#"
+ () -> i32
+ "#]],
+ );
+ }
}
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 27ad1a948..2380cf738 100644
--- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
@@ -13,7 +13,8 @@ use syntax::{AstNode, SyntaxKind::*, SyntaxToken, TextRange, T};
use crate::{
hover::hover_for_definition,
- moniker::{crate_for_file, def_to_moniker, MonikerResult},
+ moniker::{def_to_moniker, MonikerResult},
+ parent_module::crates_for,
Analysis, Fold, HoverConfig, HoverDocFormat, HoverResult, InlayHint, InlayHintsConfig,
TryToNav,
};
@@ -99,7 +100,7 @@ fn all_modules(db: &dyn HirDatabase) -> Vec<Module> {
impl StaticIndex<'_> {
fn add_file(&mut self, file_id: FileId) {
- let current_crate = crate_for_file(self.db, file_id);
+ let current_crate = crates_for(self.db, file_id).pop().map(Into::into);
let folds = self.analysis.folding_ranges(file_id).unwrap();
let inlay_hints = self
.analysis
@@ -111,7 +112,7 @@ impl StaticIndex<'_> {
chaining_hints: true,
closure_return_type_hints: crate::ClosureReturnTypeHints::WithBlock,
lifetime_elision_hints: crate::LifetimeElisionHints::Never,
- reborrow_hints: crate::ReborrowHints::Never,
+ adjustment_hints: crate::AdjustmentHints::Never,
hide_named_constructor_hints: false,
hide_closure_initialization_hints: false,
param_names_for_lifetime_elision_hints: false,
diff --git a/src/tools/rust-analyzer/crates/limit/Cargo.toml b/src/tools/rust-analyzer/crates/limit/Cargo.toml
index 893db436d..3536f73da 100644
--- a/src/tools/rust-analyzer/crates/limit/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/limit/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[features]
tracking = []
diff --git a/src/tools/rust-analyzer/crates/mbe/Cargo.toml b/src/tools/rust-analyzer/crates/mbe/Cargo.toml
index 13cd89010..bce2fc9a7 100644
--- a/src/tools/rust-analyzer/crates/mbe/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/mbe/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
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 e4c56565b..cf53c1672 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge.rs
@@ -12,6 +12,9 @@ use tt::buffer::{Cursor, TokenBuffer};
use crate::{to_parser_input::to_parser_input, tt_iter::TtIter, TokenMap};
+#[cfg(test)]
+mod tests;
+
/// Convert the syntax node to a `TokenTree` (what macro
/// will consume).
pub fn syntax_node_to_token_tree(node: &SyntaxNode) -> (tt::Subtree, TokenMap) {
@@ -35,7 +38,7 @@ pub fn syntax_node_to_token_tree_with_modifications(
append: FxHashMap<SyntaxElement, Vec<SyntheticToken>>,
) -> (tt::Subtree, TokenMap, u32) {
let global_offset = node.text_range().start();
- let mut c = Convertor::new(node, global_offset, existing_token_map, next_id, replace, append);
+ let mut c = Converter::new(node, global_offset, existing_token_map, next_id, replace, append);
let subtree = convert_tokens(&mut c);
c.id_alloc.map.shrink_to_fit();
always!(c.replace.is_empty(), "replace: {:?}", c.replace);
@@ -100,7 +103,7 @@ pub fn parse_to_token_tree(text: &str) -> Option<(tt::Subtree, TokenMap)> {
return None;
}
- let mut conv = RawConvertor {
+ let mut conv = RawConverter {
lexed,
pos: 0,
id_alloc: TokenIdAlloc {
@@ -148,7 +151,7 @@ pub fn parse_exprs_with_sep(tt: &tt::Subtree, sep: char) -> Vec<tt::Subtree> {
res
}
-fn convert_tokens<C: TokenConvertor>(conv: &mut C) -> tt::Subtree {
+fn convert_tokens<C: TokenConverter>(conv: &mut C) -> tt::Subtree {
struct StackEntry {
subtree: tt::Subtree,
idx: usize,
@@ -228,7 +231,7 @@ fn convert_tokens<C: TokenConvertor>(conv: &mut C) -> tt::Subtree {
}
let spacing = match conv.peek().map(|next| next.kind(conv)) {
- Some(kind) if !kind.is_trivia() => tt::Spacing::Joint,
+ Some(kind) if is_single_token_op(kind) => tt::Spacing::Joint,
_ => tt::Spacing::Alone,
};
let char = match token.to_char(conv) {
@@ -307,6 +310,35 @@ fn convert_tokens<C: TokenConvertor>(conv: &mut C) -> tt::Subtree {
}
}
+fn is_single_token_op(kind: SyntaxKind) -> bool {
+ matches!(
+ kind,
+ EQ | L_ANGLE
+ | R_ANGLE
+ | BANG
+ | AMP
+ | PIPE
+ | TILDE
+ | AT
+ | DOT
+ | COMMA
+ | SEMICOLON
+ | COLON
+ | POUND
+ | DOLLAR
+ | QUESTION
+ | PLUS
+ | MINUS
+ | STAR
+ | SLASH
+ | PERCENT
+ | CARET
+ // LIFETIME_IDENT will be split into a sequence of `'` (a single quote) and an
+ // identifier.
+ | LIFETIME_IDENT
+ )
+}
+
/// Returns the textual content of a doc comment block as a quoted string
/// That is, strips leading `///` (or `/**`, etc)
/// and strips the ending `*/`
@@ -425,8 +457,8 @@ impl TokenIdAlloc {
}
}
-/// A raw token (straight from lexer) convertor
-struct RawConvertor<'a> {
+/// A raw token (straight from lexer) converter
+struct RawConverter<'a> {
lexed: parser::LexedStr<'a>,
pos: usize,
id_alloc: TokenIdAlloc,
@@ -442,7 +474,7 @@ trait SrcToken<Ctx>: std::fmt::Debug {
fn synthetic_id(&self, ctx: &Ctx) -> Option<SyntheticTokenId>;
}
-trait TokenConvertor: Sized {
+trait TokenConverter: Sized {
type Token: SrcToken<Self>;
fn convert_doc_comment(&self, token: &Self::Token) -> Option<Vec<tt::TokenTree>>;
@@ -454,25 +486,25 @@ trait TokenConvertor: Sized {
fn id_alloc(&mut self) -> &mut TokenIdAlloc;
}
-impl<'a> SrcToken<RawConvertor<'a>> for usize {
- fn kind(&self, ctx: &RawConvertor<'a>) -> SyntaxKind {
+impl<'a> SrcToken<RawConverter<'a>> for usize {
+ fn kind(&self, ctx: &RawConverter<'a>) -> SyntaxKind {
ctx.lexed.kind(*self)
}
- fn to_char(&self, ctx: &RawConvertor<'a>) -> Option<char> {
+ fn to_char(&self, ctx: &RawConverter<'a>) -> Option<char> {
ctx.lexed.text(*self).chars().next()
}
- fn to_text(&self, ctx: &RawConvertor<'_>) -> SmolStr {
+ fn to_text(&self, ctx: &RawConverter<'_>) -> SmolStr {
ctx.lexed.text(*self).into()
}
- fn synthetic_id(&self, _ctx: &RawConvertor<'a>) -> Option<SyntheticTokenId> {
+ fn synthetic_id(&self, _ctx: &RawConverter<'a>) -> Option<SyntheticTokenId> {
None
}
}
-impl<'a> TokenConvertor for RawConvertor<'a> {
+impl<'a> TokenConverter for RawConverter<'a> {
type Token = usize;
fn convert_doc_comment(&self, &token: &usize) -> Option<Vec<tt::TokenTree>> {
@@ -504,7 +536,7 @@ impl<'a> TokenConvertor for RawConvertor<'a> {
}
}
-struct Convertor {
+struct Converter {
id_alloc: TokenIdAlloc,
current: Option<SyntaxToken>,
current_synthetic: Vec<SyntheticToken>,
@@ -515,7 +547,7 @@ struct Convertor {
punct_offset: Option<(SyntaxToken, TextSize)>,
}
-impl Convertor {
+impl Converter {
fn new(
node: &SyntaxNode,
global_offset: TextSize,
@@ -523,11 +555,11 @@ impl Convertor {
next_id: u32,
mut replace: FxHashMap<SyntaxElement, Vec<SyntheticToken>>,
mut append: FxHashMap<SyntaxElement, Vec<SyntheticToken>>,
- ) -> Convertor {
+ ) -> Converter {
let range = node.text_range();
let mut preorder = node.preorder_with_tokens();
let (first, synthetic) = Self::next_token(&mut preorder, &mut replace, &mut append);
- Convertor {
+ Converter {
id_alloc: { TokenIdAlloc { map: existing_token_map, global_offset, next_id } },
current: first,
current_synthetic: synthetic,
@@ -590,15 +622,15 @@ impl SynToken {
}
}
-impl SrcToken<Convertor> for SynToken {
- fn kind(&self, _ctx: &Convertor) -> SyntaxKind {
+impl SrcToken<Converter> for SynToken {
+ fn kind(&self, ctx: &Converter) -> SyntaxKind {
match self {
SynToken::Ordinary(token) => token.kind(),
- SynToken::Punch(token, _) => token.kind(),
+ SynToken::Punch(..) => SyntaxKind::from_char(self.to_char(ctx).unwrap()).unwrap(),
SynToken::Synthetic(token) => token.kind,
}
}
- fn to_char(&self, _ctx: &Convertor) -> Option<char> {
+ fn to_char(&self, _ctx: &Converter) -> Option<char> {
match self {
SynToken::Ordinary(_) => None,
SynToken::Punch(it, i) => it.text().chars().nth((*i).into()),
@@ -606,7 +638,7 @@ impl SrcToken<Convertor> for SynToken {
SynToken::Synthetic(_) => None,
}
}
- fn to_text(&self, _ctx: &Convertor) -> SmolStr {
+ fn to_text(&self, _ctx: &Converter) -> SmolStr {
match self {
SynToken::Ordinary(token) => token.text().into(),
SynToken::Punch(token, _) => token.text().into(),
@@ -614,7 +646,7 @@ impl SrcToken<Convertor> for SynToken {
}
}
- fn synthetic_id(&self, _ctx: &Convertor) -> Option<SyntheticTokenId> {
+ fn synthetic_id(&self, _ctx: &Converter) -> Option<SyntheticTokenId> {
match self {
SynToken::Synthetic(token) => Some(token.id),
_ => None,
@@ -622,7 +654,7 @@ impl SrcToken<Convertor> for SynToken {
}
}
-impl TokenConvertor for Convertor {
+impl TokenConverter for Converter {
type Token = SynToken;
fn convert_doc_comment(&self, token: &Self::Token) -> Option<Vec<tt::TokenTree>> {
convert_doc_comment(token.token()?)
@@ -651,7 +683,7 @@ impl TokenConvertor for Convertor {
}
let curr = self.current.clone()?;
- if !&self.range.contains_range(curr.text_range()) {
+ if !self.range.contains_range(curr.text_range()) {
return None;
}
let (new_current, new_synth) =
@@ -809,12 +841,15 @@ impl<'a> TtTreeSink<'a> {
let next = last.bump();
if let (
Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Punct(curr), _)),
- Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Punct(_), _)),
+ Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Punct(next), _)),
) = (last.token_tree(), next.token_tree())
{
// Note: We always assume the semi-colon would be the last token in
// other parts of RA such that we don't add whitespace here.
- if curr.spacing == tt::Spacing::Alone && curr.char != ';' {
+ //
+ // When `next` is a `Punct` of `'`, that's a part of a lifetime identifier so we don't
+ // need to add whitespace either.
+ if curr.spacing == tt::Spacing::Alone && curr.char != ';' && next.char != '\'' {
self.inner.token(WHITESPACE, " ");
self.text_pos += TextSize::of(' ');
}
diff --git a/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge/tests.rs b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge/tests.rs
new file mode 100644
index 000000000..4e04d2bc1
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/mbe/src/syntax_bridge/tests.rs
@@ -0,0 +1,93 @@
+use std::collections::HashMap;
+
+use syntax::{ast, AstNode};
+use test_utils::extract_annotations;
+use tt::{
+ buffer::{TokenBuffer, TokenTreeRef},
+ Leaf, Punct, Spacing,
+};
+
+use super::syntax_node_to_token_tree;
+
+fn check_punct_spacing(fixture: &str) {
+ let source_file = ast::SourceFile::parse(fixture).ok().unwrap();
+ let (subtree, token_map) = syntax_node_to_token_tree(source_file.syntax());
+ let mut annotations: HashMap<_, _> = extract_annotations(fixture)
+ .into_iter()
+ .map(|(range, annotation)| {
+ let token = token_map.token_by_range(range).expect("no token found");
+ let spacing = match annotation.as_str() {
+ "Alone" => Spacing::Alone,
+ "Joint" => Spacing::Joint,
+ a => panic!("unknown annotation: {}", a),
+ };
+ (token, spacing)
+ })
+ .collect();
+
+ let buf = TokenBuffer::from_subtree(&subtree);
+ let mut cursor = buf.begin();
+ while !cursor.eof() {
+ while let Some(token_tree) = cursor.token_tree() {
+ if let TokenTreeRef::Leaf(Leaf::Punct(Punct { spacing, id, .. }), _) = token_tree {
+ if let Some(expected) = annotations.remove(&id) {
+ assert_eq!(expected, *spacing);
+ }
+ }
+ cursor = cursor.bump_subtree();
+ }
+ cursor = cursor.bump();
+ }
+
+ assert!(annotations.is_empty(), "unchecked annotations: {:?}", annotations);
+}
+
+#[test]
+fn punct_spacing() {
+ check_punct_spacing(
+ r#"
+fn main() {
+ 0+0;
+ //^ Alone
+ 0+(0);
+ //^ Alone
+ 0<=0;
+ //^ Joint
+ // ^ Alone
+ 0<=(0);
+ // ^ Alone
+ a=0;
+ //^ Alone
+ a=(0);
+ //^ Alone
+ a+=0;
+ //^ Joint
+ // ^ Alone
+ a+=(0);
+ // ^ Alone
+ a&&b;
+ //^ Joint
+ // ^ Alone
+ a&&(b);
+ // ^ Alone
+ foo::bar;
+ // ^ Joint
+ // ^ Alone
+ use foo::{bar,baz,};
+ // ^ Alone
+ // ^ Alone
+ // ^ Alone
+ struct Struct<'a> {};
+ // ^ Joint
+ // ^ Joint
+ Struct::<0>;
+ // ^ Alone
+ Struct::<{0}>;
+ // ^ Alone
+ ;;
+ //^ Joint
+ // ^ Alone
+}
+ "#,
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/parser/Cargo.toml b/src/tools/rust-analyzer/crates/parser/Cargo.toml
index a286a6bcd..d1420de89 100644
--- a/src/tools/rust-analyzer/crates/parser/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/parser/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/paths/Cargo.toml b/src/tools/rust-analyzer/crates/paths/Cargo.toml
index 5e83de7d9..d23a63d2a 100644
--- a/src/tools/rust-analyzer/crates/paths/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/paths/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml
index 54879c187..f261f3def 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml
index 9d0da5dee..7991e125a 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[dependencies]
proc-macro-srv = { version = "0.0.0", path = "../proc-macro-srv" }
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
index e39026ac7..a136abc12 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs
index 2f854bc15..0ce099ae0 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/mod.rs
@@ -117,7 +117,7 @@ impl Abi {
let inner = unsafe { Abi_1_63::from_lib(lib, symbol_name) }?;
Ok(Abi::Abi1_63(inner))
}
- _ => Err(LoadProcMacroDylibError::UnsupportedABI),
+ _ => Err(LoadProcMacroDylibError::UnsupportedABI(info.version_string.clone())),
}
}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
index 7aba74e53..0722cd89d 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs
@@ -80,14 +80,14 @@ fn load_library(file: &Path) -> Result<Library, libloading::Error> {
pub enum LoadProcMacroDylibError {
Io(io::Error),
LibLoading(libloading::Error),
- UnsupportedABI,
+ UnsupportedABI(String),
}
impl fmt::Display for LoadProcMacroDylibError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Io(e) => e.fmt(f),
- Self::UnsupportedABI => write!(f, "unsupported ABI version"),
+ Self::UnsupportedABI(v) => write!(f, "unsupported ABI `{v}`"),
Self::LibLoading(e) => e.fmt(f),
}
}
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
index 72a2dfe72..b4f5ebd15 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
@@ -113,12 +113,12 @@ impl ProcMacroSrv {
fn expander(&mut self, path: &Path) -> Result<&dylib::Expander, String> {
let time = fs::metadata(path).and_then(|it| it.modified()).map_err(|err| {
- format!("Failed to get file metadata for {}: {:?}", path.display(), err)
+ format!("Failed to get file metadata for {}: {}", path.display(), err)
})?;
Ok(match self.expanders.entry((path.to_path_buf(), time)) {
Entry::Vacant(v) => v.insert(dylib::Expander::new(path).map_err(|err| {
- format!("Cannot create expander for {}: {:?}", path.display(), err)
+ format!("Cannot create expander for {}: {}", path.display(), err)
})?),
Entry::Occupied(e) => e.into_mut(),
})
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
index b46cdddcf..cc0fc91fe 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs
@@ -19,7 +19,7 @@ fn test_derive_error() {
expect![[r##"
SUBTREE $
IDENT compile_error 4294967295
- PUNCH ! [joint] 4294967295
+ PUNCH ! [alone] 4294967295
SUBTREE () 4294967295
LITERAL "#[derive(DeriveError)] struct S ;" 4294967295
PUNCH ; [alone] 4294967295"##]],
@@ -109,7 +109,7 @@ fn test_fn_like_macro_clone_literals() {
PUNCH , [alone] 4294967295
LITERAL 2_u32 4294967295
PUNCH , [alone] 4294967295
- PUNCH - [joint] 4294967295
+ PUNCH - [alone] 4294967295
LITERAL 4i64 4294967295
PUNCH , [alone] 4294967295
LITERAL 3.14f32 4294967295
@@ -130,7 +130,7 @@ fn test_attr_macro() {
expect![[r##"
SUBTREE $
IDENT compile_error 4294967295
- PUNCH ! [joint] 4294967295
+ PUNCH ! [alone] 4294967295
SUBTREE () 4294967295
LITERAL "#[attr_error(some arguments)] mod m {}" 4294967295
PUNCH ; [alone] 4294967295"##]],
diff --git a/src/tools/rust-analyzer/crates/proc-macro-test/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-test/Cargo.toml
index 684477191..d2a79f910 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-test/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-test/Cargo.toml
@@ -3,7 +3,7 @@ name = "proc-macro-test"
version = "0.0.0"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
publish = false
[lib]
diff --git a/src/tools/rust-analyzer/crates/proc-macro-test/imp/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-test/imp/Cargo.toml
index 2d1fc3c5c..1bd14070e 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-test/imp/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-test/imp/Cargo.toml
@@ -3,7 +3,7 @@ name = "proc-macro-test-impl"
version = "0.0.0"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
publish = false
[lib]
diff --git a/src/tools/rust-analyzer/crates/profile/Cargo.toml b/src/tools/rust-analyzer/crates/profile/Cargo.toml
index 5697aea96..01d1735bf 100644
--- a/src/tools/rust-analyzer/crates/profile/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/profile/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/project-model/Cargo.toml b/src/tools/rust-analyzer/crates/project-model/Cargo.toml
index cf9868740..39902a532 100644
--- a/src/tools/rust-analyzer/crates/project-model/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/project-model/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
index a26a7c57a..ae2b41f27 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/build_scripts.rs
@@ -69,7 +69,7 @@ impl WorkspaceBuildScripts {
cmd.args(&["check", "--quiet", "--workspace", "--message-format=json"]);
// --all-targets includes tests, benches and examples in addition to the
- // default lib and bins. This is an independent concept from the --targets
+ // default lib and bins. This is an independent concept from the --target
// flag below.
cmd.arg("--all-targets");
diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
index b4c2ba436..02ec7a4f6 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
@@ -270,11 +270,7 @@ impl CargoWorkspace {
config: &CargoConfig,
progress: &dyn Fn(String),
) -> Result<cargo_metadata::Metadata> {
- let target = config
- .target
- .clone()
- .or_else(|| cargo_config_build_target(cargo_toml, &config.extra_env))
- .or_else(|| rustc_discover_host_triple(cargo_toml, &config.extra_env));
+ let targets = find_list_of_build_targets(config, cargo_toml);
let mut meta = MetadataCommand::new();
meta.cargo_path(toolchain::cargo());
@@ -294,8 +290,12 @@ impl CargoWorkspace {
}
meta.current_dir(current_dir.as_os_str());
- if let Some(target) = target {
- meta.other_options(vec![String::from("--filter-platform"), target]);
+ if !targets.is_empty() {
+ let other_options: Vec<_> = targets
+ .into_iter()
+ .flat_map(|target| ["--filter-platform".to_string(), target])
+ .collect();
+ meta.other_options(other_options);
}
// FIXME: Fetching metadata is a slow process, as it might require
@@ -469,6 +469,19 @@ impl CargoWorkspace {
}
}
+fn find_list_of_build_targets(config: &CargoConfig, cargo_toml: &ManifestPath) -> Vec<String> {
+ if let Some(target) = &config.target {
+ return [target.into()].to_vec();
+ }
+
+ let build_targets = cargo_config_build_target(cargo_toml, &config.extra_env);
+ if !build_targets.is_empty() {
+ return build_targets;
+ }
+
+ rustc_discover_host_triple(cargo_toml, &config.extra_env).into_iter().collect()
+}
+
fn rustc_discover_host_triple(
cargo_toml: &ManifestPath,
extra_env: &FxHashMap<String, String>,
@@ -499,7 +512,7 @@ fn rustc_discover_host_triple(
fn cargo_config_build_target(
cargo_toml: &ManifestPath,
extra_env: &FxHashMap<String, String>,
-) -> Option<String> {
+) -> Vec<String> {
let mut cargo_config = Command::new(toolchain::cargo());
cargo_config.envs(extra_env);
cargo_config
@@ -507,12 +520,21 @@ fn cargo_config_build_target(
.args(&["-Z", "unstable-options", "config", "get", "build.target"])
.env("RUSTC_BOOTSTRAP", "1");
// if successful we receive `build.target = "target-triple"`
+ // or `build.target = ["<target 1>", ..]`
tracing::debug!("Discovering cargo config target by {:?}", cargo_config);
- match utf8_stdout(cargo_config) {
- Ok(stdout) => stdout
- .strip_prefix("build.target = \"")
- .and_then(|stdout| stdout.strip_suffix('"'))
- .map(ToOwned::to_owned),
- Err(_) => None,
+ utf8_stdout(cargo_config).map(parse_output_cargo_config_build_target).unwrap_or_default()
+}
+
+fn parse_output_cargo_config_build_target(stdout: String) -> Vec<String> {
+ let trimmed = stdout.trim_start_matches("build.target = ").trim_matches('"');
+
+ if !trimmed.starts_with('[') {
+ return [trimmed.to_string()].to_vec();
+ }
+
+ let res = serde_json::from_str(trimmed);
+ if let Err(e) = &res {
+ tracing::warn!("Failed to parse `build.target` as an array of target: {}`", e);
}
+ res.unwrap_or_default()
}
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 fa8d76f3f..f6c09a27c 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
@@ -128,14 +128,18 @@ impl Sysroot {
}
if let Some(alloc) = sysroot.by_name("alloc") {
- if let Some(core) = sysroot.by_name("core") {
- sysroot.crates[alloc].deps.push(core);
+ for dep in ALLOC_DEPS.trim().lines() {
+ if let Some(dep) = sysroot.by_name(dep) {
+ sysroot.crates[alloc].deps.push(dep)
+ }
}
}
if let Some(proc_macro) = sysroot.by_name("proc_macro") {
- if let Some(std) = sysroot.by_name("std") {
- sysroot.crates[proc_macro].deps.push(std);
+ for dep in PROC_MACRO_DEPS.trim().lines() {
+ if let Some(dep) = sysroot.by_name(dep) {
+ sysroot.crates[proc_macro].deps.push(dep)
+ }
}
}
@@ -239,6 +243,7 @@ fn get_rust_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
const SYSROOT_CRATES: &str = "
alloc
+backtrace
core
panic_abort
panic_unwind
@@ -246,17 +251,19 @@ proc_macro
profiler_builtins
std
stdarch/crates/std_detect
-term
test
unwind";
+const ALLOC_DEPS: &str = "core";
+
const STD_DEPS: &str = "
alloc
-core
-panic_abort
panic_unwind
+panic_abort
+core
profiler_builtins
+unwind
std_detect
-term
-test
-unwind";
+test";
+
+const PROC_MACRO_DEPS: &str = "std";
diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
index e2444e249..a1cb438bd 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
@@ -1566,10 +1566,10 @@ fn rust_project_hello_world_project_model() {
},
Dependency {
crate_id: CrateId(
- 1,
+ 3,
),
name: CrateName(
- "core",
+ "panic_unwind",
),
prelude: true,
},
@@ -1584,10 +1584,10 @@ fn rust_project_hello_world_project_model() {
},
Dependency {
crate_id: CrateId(
- 3,
+ 1,
),
name: CrateName(
- "panic_unwind",
+ "core",
),
prelude: true,
},
@@ -1602,40 +1602,31 @@ fn rust_project_hello_world_project_model() {
},
Dependency {
crate_id: CrateId(
- 7,
+ 9,
),
name: CrateName(
- "std_detect",
+ "unwind",
),
prelude: true,
},
Dependency {
crate_id: CrateId(
- 8,
+ 7,
),
name: CrateName(
- "term",
+ "std_detect",
),
prelude: true,
},
Dependency {
crate_id: CrateId(
- 9,
+ 8,
),
name: CrateName(
"test",
),
prelude: true,
},
- Dependency {
- crate_id: CrateId(
- 10,
- ),
- name: CrateName(
- "unwind",
- ),
- prelude: true,
- },
],
proc_macro: Err(
"no proc macro loaded for sysroot crate",
@@ -1690,40 +1681,6 @@ fn rust_project_hello_world_project_model() {
display_name: Some(
CrateDisplayName {
crate_name: CrateName(
- "term",
- ),
- canonical_name: "term",
- },
- ),
- cfg_options: CfgOptions(
- [],
- ),
- potential_cfg_options: CfgOptions(
- [],
- ),
- env: Env {
- entries: {},
- },
- dependencies: [],
- proc_macro: Err(
- "no proc macro loaded for sysroot crate",
- ),
- origin: Lang(
- Other,
- ),
- is_proc_macro: false,
- },
- CrateId(
- 9,
- ): CrateData {
- root_file_id: FileId(
- 10,
- ),
- edition: Edition2018,
- version: None,
- display_name: Some(
- CrateDisplayName {
- crate_name: CrateName(
"test",
),
canonical_name: "test",
@@ -1748,10 +1705,10 @@ fn rust_project_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 10,
+ 9,
): CrateData {
root_file_id: FileId(
- 11,
+ 10,
),
edition: Edition2018,
version: None,
@@ -1782,10 +1739,10 @@ fn rust_project_hello_world_project_model() {
is_proc_macro: false,
},
CrateId(
- 11,
+ 10,
): CrateData {
root_file_id: FileId(
- 12,
+ 11,
),
edition: Edition2018,
version: None,
@@ -1836,7 +1793,7 @@ fn rust_project_hello_world_project_model() {
},
Dependency {
crate_id: CrateId(
- 9,
+ 8,
),
name: CrateName(
"test",
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 2780c62ed..3d199ed24 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -377,6 +377,21 @@ impl ProjectWorkspace {
}
}
+ pub fn find_sysroot_proc_macro_srv(&self) -> Option<AbsPathBuf> {
+ match self {
+ ProjectWorkspace::Cargo { sysroot: Some(sysroot), .. }
+ | ProjectWorkspace::Json { sysroot: Some(sysroot), .. } => {
+ let standalone_server_name =
+ format!("rust-analyzer-proc-macro-srv{}", std::env::consts::EXE_SUFFIX);
+ ["libexec", "lib"]
+ .into_iter()
+ .map(|segment| sysroot.root().join(segment).join(&standalone_server_name))
+ .find(|server_path| std::fs::metadata(&server_path).is_ok())
+ }
+ _ => None,
+ }
+ }
+
/// Returns the roots for the current `ProjectWorkspace`
/// The return type contains the path and whether or not
/// the root is a member of the current workspace
@@ -509,14 +524,14 @@ impl ProjectWorkspace {
build_scripts,
toolchain: _,
} => cargo_to_crate_graph(
- rustc_cfg.clone(),
- cfg_overrides,
load_proc_macro,
load,
+ rustc,
cargo,
- build_scripts,
sysroot.as_ref(),
- rustc,
+ rustc_cfg.clone(),
+ cfg_overrides,
+ build_scripts,
),
ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => {
detached_files_to_crate_graph(rustc_cfg.clone(), load, files, sysroot)
@@ -602,7 +617,7 @@ fn project_json_to_crate_graph(
for (from, krate) in project.crates() {
if let Some(&from) = crates.get(&from) {
if let Some((public_deps, libproc_macro)) = &sysroot_deps {
- public_deps.add(from, &mut crate_graph);
+ public_deps.add_to_crate_graph(&mut crate_graph, from);
if krate.is_proc_macro {
if let Some(proc_macro) = libproc_macro {
add_dep(
@@ -626,14 +641,14 @@ fn project_json_to_crate_graph(
}
fn cargo_to_crate_graph(
- rustc_cfg: Vec<CfgFlag>,
- override_cfg: &CfgOverrides,
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
+ rustc: &Option<CargoWorkspace>,
cargo: &CargoWorkspace,
- build_scripts: &WorkspaceBuildScripts,
sysroot: Option<&Sysroot>,
- rustc: &Option<CargoWorkspace>,
+ rustc_cfg: Vec<CfgFlag>,
+ override_cfg: &CfgOverrides,
+ build_scripts: &WorkspaceBuildScripts,
) -> CrateGraph {
let _p = profile::span("cargo_to_crate_graph");
let mut crate_graph = CrateGraph::default();
@@ -642,13 +657,15 @@ fn cargo_to_crate_graph(
None => (SysrootPublicDeps::default(), None),
};
- let mut cfg_options = CfgOptions::default();
- cfg_options.extend(rustc_cfg);
+ let cfg_options = {
+ let mut cfg_options = CfgOptions::default();
+ cfg_options.extend(rustc_cfg);
+ cfg_options.insert_atom("debug_assertions".into());
+ cfg_options
+ };
let mut pkg_to_lib_crate = FxHashMap::default();
- cfg_options.insert_atom("debug_assertions".into());
-
let mut pkg_crates = FxHashMap::default();
// Does any crate signal to rust-analyzer that they need the rustc_private crates?
let mut has_private = false;
@@ -723,7 +740,7 @@ fn cargo_to_crate_graph(
// Set deps to the core, std and to the lib target of the current package
for &(from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
// Add sysroot deps first so that a lib target named `core` etc. can overwrite them.
- public_deps.add(from, &mut crate_graph);
+ public_deps.add_to_crate_graph(&mut crate_graph, from);
if let Some((to, name)) = lib_tgt.clone() {
if to != from && kind != TargetKind::BuildScript {
@@ -767,15 +784,16 @@ fn cargo_to_crate_graph(
if let Some(rustc_workspace) = rustc {
handle_rustc_crates(
&mut crate_graph,
- rustc_workspace,
+ &mut pkg_to_lib_crate,
load,
- &cfg_options,
- override_cfg,
load_proc_macro,
- &mut pkg_to_lib_crate,
- &public_deps,
+ rustc_workspace,
cargo,
+ &public_deps,
+ libproc_macro,
&pkg_crates,
+ &cfg_options,
+ override_cfg,
build_scripts,
);
}
@@ -825,28 +843,29 @@ fn detached_files_to_crate_graph(
},
);
- public_deps.add(detached_file_crate, &mut crate_graph);
+ public_deps.add_to_crate_graph(&mut crate_graph, detached_file_crate);
}
crate_graph
}
fn handle_rustc_crates(
crate_graph: &mut CrateGraph,
- rustc_workspace: &CargoWorkspace,
+ pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
- cfg_options: &CfgOptions,
- override_cfg: &CfgOverrides,
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
- pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
- public_deps: &SysrootPublicDeps,
+ rustc_workspace: &CargoWorkspace,
cargo: &CargoWorkspace,
+ public_deps: &SysrootPublicDeps,
+ libproc_macro: Option<CrateId>,
pkg_crates: &FxHashMap<Package, Vec<(CrateId, TargetKind)>>,
+ cfg_options: &CfgOptions,
+ override_cfg: &CfgOverrides,
build_scripts: &WorkspaceBuildScripts,
) {
let mut rustc_pkg_crates = FxHashMap::default();
// The root package of the rustc-dev component is rustc_driver, so we match that
let root_pkg =
- rustc_workspace.packages().find(|package| rustc_workspace[*package].name == "rustc_driver");
+ rustc_workspace.packages().find(|&package| rustc_workspace[package].name == "rustc_driver");
// The rustc workspace might be incomplete (such as if rustc-dev is not
// installed for the current toolchain) and `rustc_source` is set to discover.
if let Some(root_pkg) = root_pkg {
@@ -901,7 +920,16 @@ fn handle_rustc_crates(
);
pkg_to_lib_crate.insert(pkg, crate_id);
// Add dependencies on core / std / alloc for this crate
- public_deps.add(crate_id, crate_graph);
+ public_deps.add_to_crate_graph(crate_graph, crate_id);
+ if let Some(proc_macro) = libproc_macro {
+ add_dep_with_prelude(
+ crate_graph,
+ crate_id,
+ CrateName::new("proc_macro").unwrap(),
+ proc_macro,
+ rustc_workspace[tgt].is_proc_macro,
+ );
+ }
rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
}
}
@@ -1009,7 +1037,7 @@ struct SysrootPublicDeps {
impl SysrootPublicDeps {
/// Makes `from` depend on the public sysroot crates.
- fn add(&self, from: CrateId, crate_graph: &mut CrateGraph) {
+ fn add_to_crate_graph(&self, crate_graph: &mut CrateGraph, from: CrateId) {
for (name, krate, prelude) in &self.deps {
add_dep_with_prelude(crate_graph, from, name.clone(), *krate, *prelude);
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
index 544502853..56f14fe18 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
@@ -8,7 +8,7 @@ documentation = "https://rust-analyzer.github.io/manual.html"
license = "MIT OR Apache-2.0"
autobins = false
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
@@ -23,7 +23,7 @@ crossbeam-channel = "0.5.5"
dissimilar = "1.0.4"
itertools = "0.10.5"
scip = "0.1.1"
-lsp-types = { version = "0.93.1", features = ["proposed"] }
+lsp-types = { version = "=0.93.2", features = ["proposed"] }
parking_lot = "0.12.1"
xflags = "0.3.0"
oorandom = "11.1.3"
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
index eabfcf194..7bf595d2a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs
@@ -11,7 +11,7 @@ use std::{env, fs, path::Path, process};
use lsp_server::Connection;
use project_model::ProjectManifest;
-use rust_analyzer::{cli::flags, config::Config, from_json, lsp_ext::supports_utf8, Result};
+use rust_analyzer::{cli::flags, config::Config, from_json, Result};
use vfs::AbsPathBuf;
#[cfg(all(feature = "mimalloc"))]
@@ -191,11 +191,7 @@ fn run_server() -> Result<()> {
name: String::from("rust-analyzer"),
version: Some(rust_analyzer::version().to_string()),
}),
- offset_encoding: if supports_utf8(config.caps()) {
- Some("utf-8".to_string())
- } else {
- None
- },
+ offset_encoding: None,
};
let initialize_result = serde_json::to_value(initialize_result).unwrap();
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 cda95cd86..723b888d9 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/caps.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/caps.rs
@@ -6,19 +6,25 @@ use lsp_types::{
FileOperationFilter, FileOperationPattern, FileOperationPatternKind,
FileOperationRegistrationOptions, FoldingRangeProviderCapability, HoverProviderCapability,
ImplementationProviderCapability, InlayHintOptions, InlayHintServerCapabilities, OneOf,
- RenameOptions, SaveOptions, SelectionRangeProviderCapability, SemanticTokensFullOptions,
- SemanticTokensLegend, SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions,
- TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions,
- TypeDefinitionProviderCapability, WorkDoneProgressOptions,
+ PositionEncodingKind, RenameOptions, SaveOptions, SelectionRangeProviderCapability,
+ SemanticTokensFullOptions, SemanticTokensLegend, SemanticTokensOptions, ServerCapabilities,
+ SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
+ TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions,
WorkspaceFileOperationsServerCapabilities, WorkspaceServerCapabilities,
};
use serde_json::json;
use crate::config::{Config, RustfmtConfig};
+use crate::lsp_ext::supports_utf8;
use crate::semantic_tokens;
pub fn server_capabilities(config: &Config) -> ServerCapabilities {
ServerCapabilities {
+ position_encoding: if supports_utf8(config.caps()) {
+ Some(PositionEncodingKind::UTF8)
+ } else {
+ None
+ },
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
open_close: Some(true),
change: Some(TextDocumentSyncKind::INCREMENTAL),
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cargo_target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cargo_target_spec.rs
index 6ede194ba..cf51cf15a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cargo_target_spec.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cargo_target_spec.rs
@@ -3,11 +3,11 @@
use std::mem;
use cfg::{CfgAtom, CfgExpr};
-use ide::{FileId, RunnableKind, TestId};
+use ide::{Cancellable, FileId, RunnableKind, TestId};
use project_model::{self, CargoFeatures, ManifestPath, TargetKind};
use vfs::AbsPathBuf;
-use crate::{global_state::GlobalStateSnapshot, Result};
+use crate::global_state::GlobalStateSnapshot;
/// Abstract representation of Cargo target.
///
@@ -29,7 +29,7 @@ impl CargoTargetSpec {
spec: Option<CargoTargetSpec>,
kind: &RunnableKind,
cfg: &Option<CfgExpr>,
- ) -> Result<(Vec<String>, Vec<String>)> {
+ ) -> (Vec<String>, Vec<String>) {
let mut args = Vec::new();
let mut extra_args = Vec::new();
@@ -111,13 +111,13 @@ impl CargoTargetSpec {
}
}
}
- Ok((args, extra_args))
+ (args, extra_args)
}
pub(crate) fn for_file(
global_state_snapshot: &GlobalStateSnapshot,
file_id: FileId,
- ) -> Result<Option<CargoTargetSpec>> {
+ ) -> Cancellable<Option<CargoTargetSpec>> {
let crate_id = match &*global_state_snapshot.analysis.crates_for(file_id)? {
&[crate_id, ..] => crate_id,
_ => return Ok(None),
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/load_cargo.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/load_cargo.rs
index 5dba545b8..762d7d3a1 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -60,24 +60,12 @@ pub fn load_workspace(
};
let proc_macro_client = if load_config.with_proc_macro {
- let mut path = AbsPathBuf::assert(std::env::current_exe()?);
- let mut args = vec!["proc-macro"];
-
- if let ProjectWorkspace::Cargo { sysroot, .. } | ProjectWorkspace::Json { sysroot, .. } =
- &ws
- {
- if let Some(sysroot) = sysroot.as_ref() {
- let standalone_server_name =
- format!("rust-analyzer-proc-macro-srv{}", std::env::consts::EXE_SUFFIX);
- let server_path = sysroot.root().join("libexec").join(&standalone_server_name);
- if std::fs::metadata(&server_path).is_ok() {
- path = server_path;
- args = vec![];
- }
- }
- }
+ let (server_path, args): (_, &[_]) = match ws.find_sysroot_proc_macro_srv() {
+ Some(server_path) => (server_path, &[]),
+ None => (AbsPathBuf::assert(std::env::current_exe()?), &["proc-macro"]),
+ };
- ProcMacroServer::spawn(path.clone(), args.clone()).map_err(|e| e.to_string())
+ ProcMacroServer::spawn(server_path, args).map_err(|e| e.to_string())
} else {
Err("proc macro server disabled".to_owned())
};
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 748306ea5..c74ddabb1 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
@@ -20,7 +20,7 @@ use crate::cli::{
load_cargo::{load_workspace, LoadCargoConfig},
Result,
};
-use crate::line_index::{LineEndings, LineIndex, OffsetEncoding};
+use crate::line_index::{LineEndings, LineIndex, PositionEncoding};
use crate::to_proto;
use crate::version::version;
@@ -106,12 +106,12 @@ impl LsifManager<'_> {
manager: "cargo".to_string(),
uri: None,
content: None,
- repository: Some(lsif::Repository {
- url: pi.repo,
+ repository: pi.repo.map(|url| lsif::Repository {
+ url,
r#type: "git".to_string(),
commit_id: None,
}),
- version: Some(pi.version),
+ version: pi.version,
}));
self.package_map.insert(package_information, result_set_id);
result_set_id
@@ -126,7 +126,7 @@ impl LsifManager<'_> {
let line_index = self.db.line_index(file_id);
let line_index = LineIndex {
index: line_index,
- encoding: OffsetEncoding::Utf16,
+ encoding: PositionEncoding::Utf16,
endings: LineEndings::Unix,
};
let range_id = self.add_vertex(lsif::Vertex::Range {
@@ -248,7 +248,7 @@ impl LsifManager<'_> {
let line_index = self.db.line_index(file_id);
let line_index = LineIndex {
index: line_index,
- encoding: OffsetEncoding::Utf16,
+ encoding: PositionEncoding::Utf16,
endings: LineEndings::Unix,
};
let result = folds
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 8b77ccde0..9edd045ab 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
@@ -5,7 +5,7 @@ use std::{
time::Instant,
};
-use crate::line_index::{LineEndings, LineIndex, OffsetEncoding};
+use crate::line_index::{LineEndings, LineIndex, PositionEncoding};
use hir::Name;
use ide::{
LineCol, MonikerDescriptorKind, StaticIndex, StaticIndexedFile, TextRange, TokenId,
@@ -47,30 +47,27 @@ impl flags::Scip {
let si = StaticIndex::compute(&analysis);
- let mut index = scip_types::Index {
- metadata: Some(scip_types::Metadata {
- version: scip_types::ProtocolVersion::UnspecifiedProtocolVersion.into(),
- tool_info: Some(scip_types::ToolInfo {
- name: "rust-analyzer".to_owned(),
- version: "0.1".to_owned(),
- arguments: vec![],
- ..Default::default()
- })
- .into(),
- project_root: format!(
- "file://{}",
- path.normalize()
- .as_os_str()
- .to_str()
- .ok_or(anyhow::anyhow!("Unable to normalize project_root path"))?
- .to_string()
- ),
- text_document_encoding: scip_types::TextEncoding::UTF8.into(),
- ..Default::default()
+ let metadata = scip_types::Metadata {
+ version: scip_types::ProtocolVersion::UnspecifiedProtocolVersion.into(),
+ tool_info: Some(scip_types::ToolInfo {
+ name: "rust-analyzer".to_owned(),
+ version: "0.1".to_owned(),
+ arguments: vec![],
+ special_fields: Default::default(),
})
.into(),
- ..Default::default()
+ project_root: format!(
+ "file://{}",
+ path.normalize()
+ .as_os_str()
+ .to_str()
+ .ok_or(anyhow::anyhow!("Unable to normalize project_root path"))?
+ .to_string()
+ ),
+ text_document_encoding: scip_types::TextEncoding::UTF8.into(),
+ special_fields: Default::default(),
};
+ let mut documents = Vec::new();
let mut symbols_emitted: HashSet<TokenId> = HashSet::default();
let mut tokens_to_symbol: HashMap<TokenId, String> = HashMap::new();
@@ -91,22 +88,18 @@ impl flags::Scip {
let line_index = LineIndex {
index: db.line_index(file_id),
- encoding: OffsetEncoding::Utf8,
+ encoding: PositionEncoding::Utf8,
endings: LineEndings::Unix,
};
- let mut doc = scip_types::Document {
- relative_path,
- language: "rust".to_string(),
- ..Default::default()
- };
+ let mut occurrences = Vec::new();
+ let mut symbols = Vec::new();
- tokens.into_iter().for_each(|(range, id)| {
+ tokens.into_iter().for_each(|(text_range, id)| {
let token = si.tokens.get(id).unwrap();
- let mut occurrence = scip_types::Occurrence::default();
- occurrence.range = text_range_to_scip_range(&line_index, range);
- occurrence.symbol = tokens_to_symbol
+ let range = text_range_to_scip_range(&line_index, text_range);
+ let symbol = tokens_to_symbol
.entry(id)
.or_insert_with(|| {
let symbol = token_to_symbol(&token).unwrap_or_else(&mut new_local_symbol);
@@ -114,34 +107,62 @@ impl flags::Scip {
})
.clone();
+ let mut symbol_roles = Default::default();
+
if let Some(def) = token.definition {
- if def.range == range {
- occurrence.symbol_roles |= scip_types::SymbolRole::Definition as i32;
+ if def.range == text_range {
+ symbol_roles |= scip_types::SymbolRole::Definition as i32;
}
if symbols_emitted.insert(id) {
- let mut symbol_info = scip_types::SymbolInformation::default();
- symbol_info.symbol = occurrence.symbol.clone();
- if let Some(hover) = &token.hover {
- if !hover.markup.as_str().is_empty() {
- symbol_info.documentation = vec![hover.markup.as_str().to_string()];
- }
- }
-
- doc.symbols.push(symbol_info)
+ let documentation = token
+ .hover
+ .as_ref()
+ .map(|hover| hover.markup.as_str())
+ .filter(|it| !it.is_empty())
+ .map(|it| vec![it.to_owned()]);
+ let symbol_info = scip_types::SymbolInformation {
+ symbol: symbol.clone(),
+ documentation: documentation.unwrap_or_default(),
+ relationships: Vec::new(),
+ special_fields: Default::default(),
+ };
+
+ symbols.push(symbol_info)
}
}
- doc.occurrences.push(occurrence);
+ occurrences.push(scip_types::Occurrence {
+ range,
+ symbol,
+ symbol_roles,
+ override_documentation: Vec::new(),
+ syntax_kind: Default::default(),
+ diagnostics: Vec::new(),
+ special_fields: Default::default(),
+ });
});
- if doc.occurrences.is_empty() {
+ if occurrences.is_empty() {
continue;
}
- index.documents.push(doc);
+ documents.push(scip_types::Document {
+ relative_path,
+ language: "rust".to_string(),
+ occurrences,
+ symbols,
+ special_fields: Default::default(),
+ });
}
+ let index = scip_types::Index {
+ metadata: Some(metadata).into(),
+ documents,
+ external_symbols: Vec::new(),
+ special_fields: Default::default(),
+ };
+
scip::write_message_to_file("index.scip", index)
.map_err(|err| anyhow::anyhow!("Failed to write scip to file: {}", err))?;
@@ -181,7 +202,7 @@ fn new_descriptor_str(
name: name.to_string(),
disambiguator: "".to_string(),
suffix: suffix.into(),
- ..Default::default()
+ special_fields: Default::default(),
}
}
@@ -231,12 +252,12 @@ fn token_to_symbol(token: &TokenStaticData) -> Option<scip_types::Symbol> {
package: Some(scip_types::Package {
manager: "cargo".to_string(),
name: package_name,
- version,
- ..Default::default()
+ version: version.unwrap_or_else(|| ".".to_string()),
+ special_fields: Default::default(),
})
.into(),
descriptors,
- ..Default::default()
+ special_fields: Default::default(),
})
}
@@ -415,4 +436,42 @@ pub mod module {
"",
);
}
+
+ #[test]
+ fn global_symbol_for_pub_struct() {
+ check_symbol(
+ r#"
+ //- /lib.rs crate:main
+ mod foo;
+
+ fn main() {
+ let _bar = foo::Bar { i: 0 };
+ }
+ //- /foo.rs
+ pub struct Bar$0 {
+ pub i: i32,
+ }
+ "#,
+ "rust-analyzer cargo main . foo/Bar#",
+ );
+ }
+
+ #[test]
+ fn global_symbol_for_pub_struct_reference() {
+ check_symbol(
+ r#"
+ //- /lib.rs crate:main
+ mod foo;
+
+ fn main() {
+ let _bar = foo::Bar$0 { i: 0 };
+ }
+ //- /foo.rs
+ pub struct Bar {
+ pub i: i32,
+ }
+ "#,
+ "rust-analyzer cargo main . foo/Bar#",
+ );
+ }
}
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 85322f12a..6b2f22faa 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -32,7 +32,7 @@ use vfs::AbsPathBuf;
use crate::{
caps::completion_item_edit_resolve,
diagnostics::DiagnosticsMapConfig,
- line_index::OffsetEncoding,
+ line_index::PositionEncoding,
lsp_ext::{self, supports_utf8, WorkspaceSymbolSearchKind, WorkspaceSymbolSearchScope},
};
@@ -56,6 +56,9 @@ mod patch_old_style;
// parsing the old name.
config_data! {
struct ConfigData {
+ /// Whether to insert #[must_use] when generating `as_` methods
+ /// for enum variants.
+ assist_emitMustUse: bool = "false",
/// Placeholder expression to use for missing expressions in assists.
assist_expressionFillDefault: ExprFillDefaultDef = "\"todo\"",
@@ -115,9 +118,11 @@ config_data! {
/// This option does not take effect until rust-analyzer is restarted.
cargo_sysroot: Option<String> = "\"discover\"",
/// Compilation target override (target triple).
+ // FIXME(@poliorcetics): move to multiple targets here too, but this will need more work
+ // than `checkOnSave_target`
cargo_target: Option<String> = "null",
/// Unsets `#[cfg(test)]` for the specified crates.
- cargo_unsetTest: Vec<String> = "[\"core\"]",
+ cargo_unsetTest: Vec<String> = "[\"core\"]",
/// Check all targets and tests (`--all-targets`).
checkOnSave_allTargets: bool = "true",
@@ -154,7 +159,7 @@ config_data! {
checkOnSave_noDefaultFeatures: Option<bool> = "null",
/// Override the command rust-analyzer uses instead of `cargo check` for
/// diagnostics on save. The command is required to output json and
- /// should therefor include `--message-format=json` or a similar option.
+ /// should therefore include `--message-format=json` or a similar option.
///
/// If you're changing this because you're using some tool wrapping
/// Cargo, you might also want to change
@@ -171,9 +176,13 @@ config_data! {
/// ```
/// .
checkOnSave_overrideCommand: Option<Vec<String>> = "null",
- /// Check for a specific target. Defaults to
- /// `#rust-analyzer.cargo.target#`.
- checkOnSave_target: Option<String> = "null",
+ /// Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty.
+ ///
+ /// Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets, e.g.
+ /// `["aarch64-apple-darwin", "x86_64-apple-darwin"]`.
+ ///
+ /// Aliased as `"checkOnSave.targets"`.
+ checkOnSave_target | checkOnSave_targets: CheckOnSaveTargets = "[]",
/// Toggles the additional completions that automatically add imports when completed.
/// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
@@ -258,6 +267,7 @@ config_data! {
files_excludeDirs: Vec<PathBuf> = "[]",
/// Controls file watching implementation.
files_watcher: FilesWatcherDef = "\"client\"",
+
/// Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords.
highlightRelated_breakPoints_enable: bool = "true",
/// Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`).
@@ -317,6 +327,8 @@ config_data! {
inlayHints_closingBraceHints_minLines: usize = "25",
/// Whether to show inlay type hints for return types of closures.
inlayHints_closureReturnTypeHints_enable: ClosureReturnTypeHintsDef = "\"never\"",
+ /// Whether to show inlay hints for type adjustments.
+ inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef = "\"never\"",
/// Whether to show inlay type hints for elided lifetimes in function signatures.
inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = "\"never\"",
/// Whether to prefer using parameter names as the name for elided lifetime hints if possible.
@@ -326,7 +338,8 @@ config_data! {
/// Whether to show function parameter name inlay hints at the call
/// site.
inlayHints_parameterHints_enable: bool = "true",
- /// Whether to show inlay type hints for compiler inserted reborrows.
+ /// Whether to show inlay hints for compiler inserted reborrows.
+ /// This setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.
inlayHints_reborrowHints_enable: ReborrowHintsDef = "\"never\"",
/// Whether to render leading colons for type hints, and trailing colons for parameter hints.
inlayHints_renderColons: bool = "true",
@@ -948,11 +961,11 @@ impl Config {
.is_some()
}
- pub fn offset_encoding(&self) -> OffsetEncoding {
+ pub fn position_encoding(&self) -> PositionEncoding {
if supports_utf8(&self.caps) {
- OffsetEncoding::Utf8
+ PositionEncoding::Utf8
} else {
- OffsetEncoding::Utf16
+ PositionEncoding::Utf16
}
}
@@ -1140,11 +1153,10 @@ impl Config {
}
Some(_) | None => FlycheckConfig::CargoCommand {
command: self.data.checkOnSave_command.clone(),
- target_triple: self
- .data
- .checkOnSave_target
- .clone()
- .or_else(|| self.data.cargo_target.clone()),
+ target_triples: match &self.data.checkOnSave_target.0[..] {
+ [] => self.data.cargo_target.clone().into_iter().collect(),
+ targets => targets.into(),
+ },
all_targets: self.data.checkOnSave_allTargets,
no_default_features: self
.data
@@ -1197,10 +1209,15 @@ impl Config {
hide_closure_initialization_hints: self
.data
.inlayHints_typeHints_hideClosureInitialization,
- reborrow_hints: match self.data.inlayHints_reborrowHints_enable {
- ReborrowHintsDef::Always => ide::ReborrowHints::Always,
- ReborrowHintsDef::Never => ide::ReborrowHints::Never,
- ReborrowHintsDef::Mutable => ide::ReborrowHints::MutableOnly,
+ adjustment_hints: match self.data.inlayHints_expressionAdjustmentHints_enable {
+ AdjustmentHintsDef::Always => ide::AdjustmentHints::Always,
+ AdjustmentHintsDef::Never => match self.data.inlayHints_reborrowHints_enable {
+ ReborrowHintsDef::Always | ReborrowHintsDef::Mutable => {
+ ide::AdjustmentHints::ReborrowOnly
+ }
+ ReborrowHintsDef::Never => ide::AdjustmentHints::Never,
+ },
+ AdjustmentHintsDef::Reborrow => ide::AdjustmentHints::ReborrowOnly,
},
binding_mode_hints: self.data.inlayHints_bindingModeHints_enable,
param_names_for_lifetime_elision_hints: self
@@ -1276,6 +1293,7 @@ impl Config {
allowed: None,
insert_use: self.insert_use_config(),
prefer_no_std: self.data.imports_prefer_no_std,
+ assist_emit_must_use: self.data.assist_emitMustUse,
}
}
@@ -1534,6 +1552,7 @@ mod de_unit_v {
named_unit_variant!(all);
named_unit_variant!(skip_trivial);
named_unit_variant!(mutable);
+ named_unit_variant!(reborrow);
named_unit_variant!(with_block);
}
@@ -1644,6 +1663,9 @@ enum InvocationStrategy {
}
#[derive(Deserialize, Debug, Clone)]
+struct CheckOnSaveTargets(#[serde(deserialize_with = "single_or_array")] Vec<String>);
+
+#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
enum InvocationLocation {
Root,
@@ -1684,6 +1706,17 @@ enum ReborrowHintsDef {
}
#[derive(Deserialize, Debug, Clone)]
+#[serde(untagged)]
+enum AdjustmentHintsDef {
+ #[serde(deserialize_with = "true_or_always")]
+ Always,
+ #[serde(deserialize_with = "false_or_never")]
+ Never,
+ #[serde(deserialize_with = "de_unit_v::reborrow")]
+ Reborrow,
+}
+
+#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
enum FilesWatcherDef {
Client,
@@ -1992,6 +2025,19 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
"Only show mutable reborrow hints."
]
},
+ "AdjustmentHintsDef" => set! {
+ "type": "string",
+ "enum": [
+ "always",
+ "never",
+ "reborrow"
+ ],
+ "enumDescriptions": [
+ "Always show all adjustment hints.",
+ "Never show adjustment hints.",
+ "Only show auto borrow and dereference adjustment hints."
+ ]
+ },
"CargoFeaturesDef" => set! {
"anyOf": [
{
@@ -2080,6 +2126,17 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
"The command will be executed in the project root."
],
},
+ "CheckOnSaveTargets" => set! {
+ "anyOf": [
+ {
+ "type": "string",
+ },
+ {
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ ],
+ },
_ => panic!("missing entry for {}: {}", ty, default),
}
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 74689fd87..beb23c54c 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,7 +8,7 @@ use stdx::format_to;
use vfs::{AbsPath, AbsPathBuf};
use crate::{
- global_state::GlobalStateSnapshot, line_index::OffsetEncoding, lsp_ext,
+ global_state::GlobalStateSnapshot, line_index::PositionEncoding, lsp_ext,
to_proto::url_from_abs_path,
};
@@ -66,17 +66,17 @@ fn location(
let uri = url_from_abs_path(&file_name);
let range = {
- let offset_encoding = snap.config.offset_encoding();
+ let position_encoding = snap.config.position_encoding();
lsp_types::Range::new(
- position(&offset_encoding, span, span.line_start, span.column_start),
- position(&offset_encoding, span, span.line_end, span.column_end),
+ position(&position_encoding, span, span.line_start, span.column_start),
+ position(&position_encoding, span, span.line_end, span.column_end),
)
};
lsp_types::Location::new(uri, range)
}
fn position(
- offset_encoding: &OffsetEncoding,
+ position_encoding: &PositionEncoding,
span: &DiagnosticSpan,
line_offset: usize,
column_offset: usize,
@@ -93,9 +93,9 @@ fn position(
};
}
let mut char_offset = 0;
- let len_func = match offset_encoding {
- OffsetEncoding::Utf8 => char::len_utf8,
- OffsetEncoding::Utf16 => char::len_utf16,
+ let len_func = match position_encoding {
+ PositionEncoding::Utf8 => char::len_utf8,
+ PositionEncoding::Utf16 => char::len_utf16,
};
for c in line.text.chars() {
char_offset += 1;
@@ -359,14 +359,15 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
.iter()
.flat_map(|primary_span| {
let primary_location = primary_location(config, workspace_root, primary_span, snap);
-
- let mut message = message.clone();
- if needs_primary_span_label {
- if let Some(primary_span_label) = &primary_span.label {
- format_to!(message, "\n{}", primary_span_label);
+ let message = {
+ let mut message = message.clone();
+ if needs_primary_span_label {
+ if let Some(primary_span_label) = &primary_span.label {
+ format_to!(message, "\n{}", primary_span_label);
+ }
}
- }
-
+ message
+ };
// Each primary diagnostic span may result in multiple LSP diagnostics.
let mut diagnostics = Vec::new();
@@ -417,7 +418,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
message: message.clone(),
related_information: Some(information_for_additional_diagnostic),
tags: if tags.is_empty() { None } else { Some(tags.clone()) },
- data: None,
+ data: Some(serde_json::json!({ "rendered": rd.rendered })),
};
diagnostics.push(MappedRustDiagnostic {
url: secondary_location.uri,
@@ -449,7 +450,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
}
},
tags: if tags.is_empty() { None } else { Some(tags.clone()) },
- data: None,
+ data: Some(serde_json::json!({ "rendered": rd.rendered })),
},
fix: None,
});
@@ -534,7 +535,8 @@ mod tests {
Config::new(workspace_root.to_path_buf(), ClientCapabilities::default()),
);
let snap = state.snapshot();
- let actual = map_rust_diagnostic_to_lsp(&config, &diagnostic, workspace_root, &snap);
+ let mut actual = map_rust_diagnostic_to_lsp(&config, &diagnostic, workspace_root, &snap);
+ actual.iter_mut().for_each(|diag| diag.diagnostic.data = None);
expect.assert_debug_eq(&actual)
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/from_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/from_proto.rs
index f2db9a273..dd433b0f4 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/from_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/from_proto.rs
@@ -8,7 +8,7 @@ use vfs::AbsPathBuf;
use crate::{
from_json,
global_state::GlobalStateSnapshot,
- line_index::{LineIndex, OffsetEncoding},
+ line_index::{LineIndex, PositionEncoding},
lsp_ext,
lsp_utils::invalid_params_error,
Result,
@@ -25,10 +25,10 @@ pub(crate) fn vfs_path(url: &lsp_types::Url) -> Result<vfs::VfsPath> {
pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> Result<TextSize> {
let line_col = match line_index.encoding {
- OffsetEncoding::Utf8 => {
+ PositionEncoding::Utf8 => {
LineCol { line: position.line as u32, col: position.character as u32 }
}
- OffsetEncoding::Utf16 => {
+ PositionEncoding::Utf16 => {
let line_col =
LineColUtf16 { line: position.line as u32, col: position.character as u32 };
line_index.index.to_utf8(line_col)
@@ -42,8 +42,10 @@ pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> R
pub(crate) fn text_range(line_index: &LineIndex, range: lsp_types::Range) -> Result<TextRange> {
let start = offset(line_index, range.start)?;
let end = offset(line_index, range.end)?;
- let text_range = TextRange::new(start, end);
- Ok(text_range)
+ match end < start {
+ true => Err(format_err!("Invalid Range").into()),
+ false => Ok(TextRange::new(start, end)),
+ }
}
pub(crate) fn file_id(snap: &GlobalStateSnapshot, url: &lsp_types::Url) -> Result<FileId> {
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 3fb06c31f..4e8bc8d64 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
@@ -100,7 +100,7 @@ pub(crate) struct GlobalState {
/// the user just adds comments or whitespace to Cargo.toml, we do not want
/// to invalidate any salsa caches.
pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
- pub(crate) fetch_workspaces_queue: OpQueue<Vec<anyhow::Result<ProjectWorkspace>>>,
+ pub(crate) fetch_workspaces_queue: OpQueue<Option<Vec<anyhow::Result<ProjectWorkspace>>>>,
pub(crate) fetch_build_data_queue:
OpQueue<(Arc<Vec<ProjectWorkspace>>, Vec<anyhow::Result<WorkspaceBuildScripts>>)>,
@@ -383,7 +383,7 @@ impl GlobalStateSnapshot {
pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancellable<LineIndex> {
let endings = self.vfs.read().1[&file_id];
let index = self.analysis.file_line_index(file_id)?;
- let res = LineIndex { index, endings, encoding: self.config.offset_encoding() };
+ let res = LineIndex { index, endings, encoding: self.config.position_encoding() };
Ok(res)
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs
index 34795a8eb..d190a9f4e 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers.rs
@@ -9,9 +9,9 @@ use std::{
use anyhow::Context;
use ide::{
- AnnotationConfig, AssistKind, AssistResolveStrategy, FileId, FilePosition, FileRange,
- HoverAction, HoverGotoTypeData, Query, RangeInfo, ReferenceCategory, Runnable, RunnableKind,
- SingleResolve, SourceChange, TextEdit,
+ AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, FileId, FilePosition,
+ FileRange, HoverAction, HoverGotoTypeData, Query, RangeInfo, ReferenceCategory, Runnable,
+ RunnableKind, SingleResolve, SourceChange, TextEdit,
};
use ide_db::SymbolKind;
use lsp_server::ErrorCode;
@@ -556,7 +556,7 @@ pub(crate) fn handle_will_rename_files(
if source_change.source_file_edits.is_empty() {
Ok(None)
} else {
- to_proto::workspace_edit(&snap, source_change).map(Some)
+ Ok(Some(to_proto::workspace_edit(&snap, source_change)?))
}
}
@@ -1313,7 +1313,7 @@ pub(crate) fn handle_ssr(
position,
selections,
)??;
- to_proto::workspace_edit(&snap, source_change)
+ to_proto::workspace_edit(&snap, source_change).map_err(Into::into)
}
pub(crate) fn publish_diagnostics(
@@ -1354,13 +1354,12 @@ pub(crate) fn handle_inlay_hints(
) -> Result<Option<Vec<InlayHint>>> {
let _p = profile::span("handle_inlay_hints");
let document_uri = &params.text_document.uri;
- let file_id = from_proto::file_id(&snap, document_uri)?;
- let line_index = snap.file_line_index(file_id)?;
- let range = from_proto::file_range(
+ let FileRange { file_id, range } = from_proto::file_range(
&snap,
TextDocumentIdentifier::new(document_uri.to_owned()),
params.range,
)?;
+ let line_index = snap.file_line_index(file_id)?;
let inlay_hints_config = snap.config.inlay_hints();
Ok(Some(
snap.analysis
@@ -1369,7 +1368,7 @@ pub(crate) fn handle_inlay_hints(
.map(|it| {
to_proto::inlay_hint(&snap, &line_index, inlay_hints_config.render_colons, it)
})
- .collect::<Result<Vec<_>>>()?,
+ .collect::<Cancellable<Vec<_>>>()?,
))
}
@@ -1426,7 +1425,7 @@ pub(crate) fn handle_call_hierarchy_prepare(
.into_iter()
.filter(|it| it.kind == Some(SymbolKind::Function))
.map(|it| to_proto::call_hierarchy_item(&snap, it))
- .collect::<Result<Vec<_>>>()?;
+ .collect::<Cancellable<Vec<_>>>()?;
Ok(Some(res))
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/line_index.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/line_index.rs
index c116414da..2945dba12 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/line_index.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/line_index.rs
@@ -7,7 +7,7 @@
use std::sync::Arc;
-pub enum OffsetEncoding {
+pub enum PositionEncoding {
Utf8,
Utf16,
}
@@ -15,7 +15,7 @@ pub enum OffsetEncoding {
pub(crate) struct LineIndex {
pub(crate) index: Arc<ide::LineIndex>,
pub(crate) endings: LineEndings,
- pub(crate) encoding: OffsetEncoding,
+ pub(crate) encoding: PositionEncoding,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -27,10 +27,6 @@ pub(crate) enum LineEndings {
impl LineEndings {
/// Replaces `\r\n` with `\n` in-place in `src`.
pub(crate) fn normalize(src: String) -> (String, LineEndings) {
- if !src.as_bytes().contains(&b'\r') {
- return (src, LineEndings::Unix);
- }
-
// We replace `\r\n` with `\n` in-place, which doesn't break utf-8 encoding.
// While we *can* call `as_mut_vec` and do surgery on the live string
// directly, let's rather steal the contents of `src`. This makes the code
@@ -39,10 +35,19 @@ impl LineEndings {
let mut buf = src.into_bytes();
let mut gap_len = 0;
let mut tail = buf.as_mut_slice();
+ let mut crlf_seen = false;
+
+ let find_crlf = |src: &[u8]| src.windows(2).position(|it| it == b"\r\n");
+
loop {
let idx = match find_crlf(&tail[gap_len..]) {
- None => tail.len(),
- Some(idx) => idx + gap_len,
+ None if crlf_seen => tail.len(),
+ // SAFETY: buf is unchanged and therefore still contains utf8 data
+ None => return (unsafe { String::from_utf8_unchecked(buf) }, LineEndings::Unix),
+ Some(idx) => {
+ crlf_seen = true;
+ idx + gap_len
+ }
};
tail.copy_within(gap_len..idx, 0);
tail = &mut tail[idx - gap_len..];
@@ -54,15 +59,48 @@ impl LineEndings {
// Account for removed `\r`.
// After `set_len`, `buf` is guaranteed to contain utf-8 again.
- let new_len = buf.len() - gap_len;
let src = unsafe {
+ let new_len = buf.len() - gap_len;
buf.set_len(new_len);
String::from_utf8_unchecked(buf)
};
- return (src, LineEndings::Dos);
+ (src, LineEndings::Dos)
+ }
+}
- fn find_crlf(src: &[u8]) -> Option<usize> {
- src.windows(2).position(|it| it == b"\r\n")
- }
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn unix() {
+ let src = "a\nb\nc\n\n\n\n";
+ let (res, endings) = LineEndings::normalize(src.into());
+ assert_eq!(endings, LineEndings::Unix);
+ assert_eq!(res, src);
+ }
+
+ #[test]
+ fn dos() {
+ let src = "\r\na\r\n\r\nb\r\nc\r\n\r\n\r\n\r\n";
+ let (res, endings) = LineEndings::normalize(src.into());
+ assert_eq!(endings, LineEndings::Dos);
+ assert_eq!(res, "\na\n\nb\nc\n\n\n\n");
+ }
+
+ #[test]
+ fn mixed() {
+ let src = "a\r\nb\r\nc\r\n\n\r\n\n";
+ let (res, endings) = LineEndings::normalize(src.into());
+ assert_eq!(endings, LineEndings::Dos);
+ assert_eq!(res, "a\nb\nc\n\n\n\n");
+ }
+
+ #[test]
+ fn none() {
+ let src = "abc";
+ let (res, endings) = LineEndings::normalize(src.into());
+ assert_eq!(endings, LineEndings::Unix);
+ assert_eq!(res, src);
}
}
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 e61c8b643..8cc5648f3 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
@@ -3,6 +3,7 @@
use std::{collections::HashMap, path::PathBuf};
use lsp_types::request::Request;
+use lsp_types::PositionEncodingKind;
use lsp_types::{
notification::Notification, CodeActionKind, DocumentOnTypeFormattingParams,
PartialResultParams, Position, Range, TextDocumentIdentifier, WorkDoneProgressParams,
@@ -455,7 +456,15 @@ pub(crate) enum CodeLensResolveData {
}
pub fn supports_utf8(caps: &lsp_types::ClientCapabilities) -> bool {
- caps.offset_encoding.as_deref().unwrap_or_default().iter().any(|it| it == "utf-8")
+ match &caps.general {
+ Some(general) => general
+ .position_encodings
+ .as_deref()
+ .unwrap_or_default()
+ .iter()
+ .any(|it| it == &PositionEncodingKind::UTF8),
+ _ => false,
+ }
}
pub enum MoveItem {}
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 b3cea64d4..0971dc36f 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
@@ -1,12 +1,12 @@
//! Utilities for LSP-related boilerplate code.
-use std::{ops::Range, sync::Arc};
+use std::{mem, ops::Range, sync::Arc};
use lsp_server::Notification;
use crate::{
from_proto,
global_state::GlobalState,
- line_index::{LineEndings, LineIndex, OffsetEncoding},
+ line_index::{LineEndings, LineIndex, PositionEncoding},
LspError,
};
@@ -133,14 +133,40 @@ impl GlobalState {
}
pub(crate) fn apply_document_changes(
- old_text: &mut String,
- content_changes: Vec<lsp_types::TextDocumentContentChangeEvent>,
-) {
+ file_contents: impl FnOnce() -> String,
+ mut content_changes: Vec<lsp_types::TextDocumentContentChangeEvent>,
+) -> String {
+ // Skip to the last full document change, as it invalidates all previous changes anyways.
+ let mut start = content_changes
+ .iter()
+ .rev()
+ .position(|change| change.range.is_none())
+ .map(|idx| content_changes.len() - idx - 1)
+ .unwrap_or(0);
+
+ let mut text: String = match content_changes.get_mut(start) {
+ // peek at the first content change as an optimization
+ Some(lsp_types::TextDocumentContentChangeEvent { range: None, text, .. }) => {
+ let text = mem::take(text);
+ start += 1;
+
+ // The only change is a full document update
+ if start == content_changes.len() {
+ return text;
+ }
+ text
+ }
+ Some(_) => file_contents(),
+ // we received no content changes
+ None => return file_contents(),
+ };
+
let mut line_index = LineIndex {
- index: Arc::new(ide::LineIndex::new(old_text)),
+ // the index will be overwritten in the bottom loop's first iteration
+ index: Arc::new(ide::LineIndex::new(&text)),
// We don't care about line endings or offset encoding here.
endings: LineEndings::Unix,
- encoding: OffsetEncoding::Utf16,
+ encoding: PositionEncoding::Utf16,
};
// The changes we got must be applied sequentially, but can cross lines so we
@@ -148,38 +174,20 @@ pub(crate) fn apply_document_changes(
// Some clients (e.g. Code) sort the ranges in reverse. As an optimization, we
// remember the last valid line in the index and only rebuild it if needed.
// The VFS will normalize the end of lines to `\n`.
- enum IndexValid {
- All,
- UpToLineExclusive(u32),
- }
-
- impl IndexValid {
- fn covers(&self, line: u32) -> bool {
- match *self {
- IndexValid::UpToLineExclusive(to) => to > line,
- _ => true,
- }
- }
- }
-
- let mut index_valid = IndexValid::All;
+ let mut index_valid = !0u32;
for change in content_changes {
- match change.range {
- Some(range) => {
- if !index_valid.covers(range.end.line) {
- line_index.index = Arc::new(ide::LineIndex::new(old_text));
- }
- index_valid = IndexValid::UpToLineExclusive(range.start.line);
- if let Ok(range) = from_proto::text_range(&line_index, range) {
- old_text.replace_range(Range::<usize>::from(range), &change.text);
- }
+ // The None case can't happen as we have handled it above already
+ if let Some(range) = change.range {
+ if index_valid <= range.end.line {
+ *Arc::make_mut(&mut line_index.index) = ide::LineIndex::new(&text);
}
- None => {
- *old_text = change.text;
- index_valid = IndexValid::UpToLineExclusive(0);
+ index_valid = range.start.line;
+ if let Ok(range) = from_proto::text_range(&line_index, range) {
+ text.replace_range(Range::<usize>::from(range), &change.text);
}
}
}
+ text
}
/// Checks that the edits inside the completion and the additional edits do not overlap.
@@ -242,11 +250,10 @@ mod tests {
};
}
- let mut text = String::new();
- apply_document_changes(&mut text, vec![]);
+ let text = apply_document_changes(|| String::new(), vec![]);
assert_eq!(text, "");
- apply_document_changes(
- &mut text,
+ let text = apply_document_changes(
+ || text,
vec![TextDocumentContentChangeEvent {
range: None,
range_length: None,
@@ -254,39 +261,39 @@ mod tests {
}],
);
assert_eq!(text, "the");
- apply_document_changes(&mut text, c![0, 3; 0, 3 => " quick"]);
+ let text = apply_document_changes(|| text, c![0, 3; 0, 3 => " quick"]);
assert_eq!(text, "the quick");
- apply_document_changes(&mut text, c![0, 0; 0, 4 => "", 0, 5; 0, 5 => " foxes"]);
+ let text = apply_document_changes(|| text, c![0, 0; 0, 4 => "", 0, 5; 0, 5 => " foxes"]);
assert_eq!(text, "quick foxes");
- apply_document_changes(&mut text, c![0, 11; 0, 11 => "\ndream"]);
+ let text = apply_document_changes(|| text, c![0, 11; 0, 11 => "\ndream"]);
assert_eq!(text, "quick foxes\ndream");
- apply_document_changes(&mut text, c![1, 0; 1, 0 => "have "]);
+ let text = apply_document_changes(|| text, c![1, 0; 1, 0 => "have "]);
assert_eq!(text, "quick foxes\nhave dream");
- apply_document_changes(
- &mut text,
+ let text = apply_document_changes(
+ || text,
c![0, 0; 0, 0 => "the ", 1, 4; 1, 4 => " quiet", 1, 16; 1, 16 => "s\n"],
);
assert_eq!(text, "the quick foxes\nhave quiet dreams\n");
- apply_document_changes(&mut text, c![0, 15; 0, 15 => "\n", 2, 17; 2, 17 => "\n"]);
+ let text = apply_document_changes(|| text, c![0, 15; 0, 15 => "\n", 2, 17; 2, 17 => "\n"]);
assert_eq!(text, "the quick foxes\n\nhave quiet dreams\n\n");
- apply_document_changes(
- &mut text,
+ let text = apply_document_changes(
+ || text,
c![1, 0; 1, 0 => "DREAM", 2, 0; 2, 0 => "they ", 3, 0; 3, 0 => "DON'T THEY?"],
);
assert_eq!(text, "the quick foxes\nDREAM\nthey have quiet dreams\nDON'T THEY?\n");
- apply_document_changes(&mut text, c![0, 10; 1, 5 => "", 2, 0; 2, 12 => ""]);
+ let text = apply_document_changes(|| text, c![0, 10; 1, 5 => "", 2, 0; 2, 12 => ""]);
assert_eq!(text, "the quick \nthey have quiet dreams\n");
- text = String::from("â¤ï¸");
- apply_document_changes(&mut text, c![0, 0; 0, 0 => "a"]);
+ let text = String::from("â¤ï¸");
+ let text = apply_document_changes(|| text, c![0, 0; 0, 0 => "a"]);
assert_eq!(text, "aâ¤ï¸");
- text = String::from("a\nb");
- apply_document_changes(&mut text, c![0, 1; 1, 0 => "\nțc", 0, 1; 1, 1 => "d"]);
+ let text = String::from("a\nb");
+ let text = apply_document_changes(|| text, c![0, 1; 1, 0 => "\nțc", 0, 1; 1, 1 => "d"]);
assert_eq!(text, "adcb");
- text = String::from("a\nb");
- apply_document_changes(&mut text, c![0, 1; 1, 0 => "È›\nc", 0, 2; 0, 2 => "c"]);
+ let text = String::from("a\nb");
+ let text = apply_document_changes(|| text, c![0, 1; 1, 0 => "È›\nc", 0, 2; 0, 2 => "c"]);
assert_eq!(text, "ațc\ncb");
}
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 2c928a580..274588ce0 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
@@ -451,7 +451,7 @@ impl GlobalState {
ProjectWorkspaceProgress::Begin => (Progress::Begin, None),
ProjectWorkspaceProgress::Report(msg) => (Progress::Report, Some(msg)),
ProjectWorkspaceProgress::End(workspaces) => {
- self.fetch_workspaces_queue.op_completed(workspaces);
+ self.fetch_workspaces_queue.op_completed(Some(workspaces));
let old = Arc::clone(&self.workspaces);
self.switch_workspaces("fetched workspace".to_string());
@@ -607,30 +607,34 @@ impl GlobalState {
/// Handles a request.
fn on_request(&mut self, req: Request) {
- if self.shutdown_requested {
- self.respond(lsp_server::Response::new_err(
- req.id,
- lsp_server::ErrorCode::InvalidRequest as i32,
- "Shutdown already requested.".to_owned(),
- ));
- return;
- }
+ let mut dispatcher = RequestDispatcher { req: Some(req), global_state: self };
+ dispatcher.on_sync_mut::<lsp_types::request::Shutdown>(|s, ()| {
+ s.shutdown_requested = true;
+ Ok(())
+ });
+
+ if let RequestDispatcher { req: Some(req), global_state: this } = &mut dispatcher {
+ if this.shutdown_requested {
+ this.respond(lsp_server::Response::new_err(
+ req.id.clone(),
+ lsp_server::ErrorCode::InvalidRequest as i32,
+ "Shutdown already requested.".to_owned(),
+ ));
+ return;
+ }
- // Avoid flashing a bunch of unresolved references during initial load.
- if self.workspaces.is_empty() && !self.is_quiescent() {
- self.respond(lsp_server::Response::new_err(
- req.id,
- lsp_server::ErrorCode::ContentModified as i32,
- "waiting for cargo metadata or cargo check".to_owned(),
- ));
- return;
+ // Avoid flashing a bunch of unresolved references during initial load.
+ if this.workspaces.is_empty() && !this.is_quiescent() {
+ this.respond(lsp_server::Response::new_err(
+ req.id.clone(),
+ lsp_server::ErrorCode::ContentModified as i32,
+ "waiting for cargo metadata or cargo check".to_owned(),
+ ));
+ return;
+ }
}
- RequestDispatcher { req: Some(req), global_state: self }
- .on_sync_mut::<lsp_types::request::Shutdown>(|s, ()| {
- s.shutdown_requested = true;
- Ok(())
- })
+ dispatcher
.on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload)
.on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage)
.on_sync_mut::<lsp_ext::ShuffleCrateGraph>(handlers::handle_shuffle_crate_graph)
@@ -755,8 +759,10 @@ impl GlobalState {
let vfs = &mut this.vfs.write().0;
let file_id = vfs.file_id(&path).unwrap();
- let mut text = String::from_utf8(vfs.file_contents(file_id).to_vec()).unwrap();
- apply_document_changes(&mut text, params.content_changes);
+ let text = apply_document_changes(
+ || std::str::from_utf8(vfs.file_contents(file_id)).unwrap().into(),
+ params.content_changes,
+ );
vfs.set_file_contents(path, Some(text.into_bytes()));
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/mem_docs.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/mem_docs.rs
index f86a0f66a..45a1dab97 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/mem_docs.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/mem_docs.rs
@@ -7,7 +7,7 @@ use vfs::VfsPath;
/// Holds the set of in-memory documents.
///
-/// For these document, there true contents is maintained by the client. It
+/// For these document, their true contents is maintained by the client. It
/// might be different from what's on disk.
#[derive(Default, Clone)]
pub(crate) struct MemDocs {
@@ -19,6 +19,7 @@ impl MemDocs {
pub(crate) fn contains(&self, path: &VfsPath) -> bool {
self.mem_docs.contains_key(path)
}
+
pub(crate) fn insert(&mut self, path: VfsPath, data: DocumentData) -> Result<(), ()> {
self.added_or_removed = true;
match self.mem_docs.insert(path, data) {
@@ -26,6 +27,7 @@ impl MemDocs {
None => Ok(()),
}
}
+
pub(crate) fn remove(&mut self, path: &VfsPath) -> Result<(), ()> {
self.added_or_removed = true;
match self.mem_docs.remove(path) {
@@ -33,17 +35,21 @@ impl MemDocs {
None => Err(()),
}
}
+
pub(crate) fn get(&self, path: &VfsPath) -> Option<&DocumentData> {
self.mem_docs.get(path)
}
+
pub(crate) fn get_mut(&mut self, path: &VfsPath) -> Option<&mut DocumentData> {
// NB: don't set `self.added_or_removed` here, as that purposefully only
// tracks changes to the key set.
self.mem_docs.get_mut(path)
}
+
pub(crate) fn iter(&self) -> impl Iterator<Item = &VfsPath> {
self.mem_docs.keys()
}
+
pub(crate) fn take_changes(&mut self) -> bool {
mem::replace(&mut self.added_or_removed, false)
}
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 e1f651786..fcfe4be0b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -106,6 +106,14 @@ impl GlobalState {
status.health = lsp_ext::Health::Error;
status.message = Some(error)
}
+
+ if self.config.linked_projects().is_empty()
+ && self.config.detached_files().is_empty()
+ && self.config.notifications().cargo_toml_not_found
+ {
+ status.health = lsp_ext::Health::Warning;
+ status.message = Some("Workspace reload required".to_string())
+ }
status
}
@@ -198,12 +206,9 @@ impl GlobalState {
self.show_and_log_error("failed to run build scripts".to_string(), Some(error));
}
- let workspaces = self
- .fetch_workspaces_queue
- .last_op_result()
- .iter()
- .filter_map(|res| res.as_ref().ok().cloned())
- .collect::<Vec<_>>();
+ let Some(workspaces) = self.fetch_workspaces_queue.last_op_result() else { return; };
+ let workspaces =
+ workspaces.iter().filter_map(|res| res.as_ref().ok().cloned()).collect::<Vec<_>>();
fn eq_ignore_build_data<'a>(
left: &'a ProjectWorkspace,
@@ -300,9 +305,6 @@ impl GlobalState {
let files_config = self.config.files();
let project_folders = ProjectFolders::new(&self.workspaces, &files_config.exclude);
- let standalone_server_name =
- format!("rust-analyzer-proc-macro-srv{}", std::env::consts::EXE_SUFFIX);
-
if self.proc_macro_clients.is_empty() {
if let Some((path, path_manually_set)) = self.config.proc_macro_srv() {
tracing::info!("Spawning proc-macro servers");
@@ -310,40 +312,17 @@ impl GlobalState {
.workspaces
.iter()
.map(|ws| {
- let (path, args) = if path_manually_set {
+ let (path, args): (_, &[_]) = if path_manually_set {
tracing::debug!(
"Pro-macro server path explicitly set: {}",
path.display()
);
- (path.clone(), vec![])
+ (path.clone(), &[])
} else {
- let mut sysroot_server = None;
- if let ProjectWorkspace::Cargo { sysroot, .. }
- | ProjectWorkspace::Json { sysroot, .. } = ws
- {
- if let Some(sysroot) = sysroot.as_ref() {
- let server_path = sysroot
- .root()
- .join("libexec")
- .join(&standalone_server_name);
- if std::fs::metadata(&server_path).is_ok() {
- tracing::debug!(
- "Sysroot proc-macro server exists at {}",
- server_path.display()
- );
- sysroot_server = Some(server_path);
- } else {
- tracing::debug!(
- "Sysroot proc-macro server does not exist at {}",
- server_path.display()
- );
- }
- }
+ match ws.find_sysroot_proc_macro_srv() {
+ Some(server_path) => (server_path, &[]),
+ None => (path.clone(), &["proc-macro"]),
}
- sysroot_server.map_or_else(
- || (path.clone(), vec!["proc-macro".to_owned()]),
- |path| (path, vec![]),
- )
};
tracing::info!(?args, "Using proc-macro server at {}", path.display(),);
@@ -427,9 +406,14 @@ impl GlobalState {
fn fetch_workspace_error(&self) -> Result<(), String> {
let mut buf = String::new();
- for ws in self.fetch_workspaces_queue.last_op_result() {
- if let Err(err) = ws {
- stdx::format_to!(buf, "rust-analyzer failed to load workspace: {:#}\n", err);
+ let Some(last_op_result) = self.fetch_workspaces_queue.last_op_result() else { return Ok(()) };
+ if last_op_result.is_empty() {
+ stdx::format_to!(buf, "rust-analyzer failed to discover workspace");
+ } else {
+ for ws in last_op_result {
+ if let Err(err) = ws {
+ stdx::format_to!(buf, "rust-analyzer failed to load workspace: {:#}\n", err);
+ }
}
}
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs
index 5936454a7..81cc1952b 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/to_proto.rs
@@ -21,17 +21,17 @@ use crate::{
cargo_target_spec::CargoTargetSpec,
config::{CallInfoConfig, Config},
global_state::GlobalStateSnapshot,
- line_index::{LineEndings, LineIndex, OffsetEncoding},
+ line_index::{LineEndings, LineIndex, PositionEncoding},
lsp_ext,
lsp_utils::invalid_params_error,
- semantic_tokens, Result,
+ semantic_tokens,
};
pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position {
let line_col = line_index.index.line_col(offset);
match line_index.encoding {
- OffsetEncoding::Utf8 => lsp_types::Position::new(line_col.line, line_col.col),
- OffsetEncoding::Utf16 => {
+ PositionEncoding::Utf8 => lsp_types::Position::new(line_col.line, line_col.col),
+ PositionEncoding::Utf16 => {
let line_col = line_index.index.to_utf16(line_col);
lsp_types::Position::new(line_col.line, line_col.col)
}
@@ -429,7 +429,7 @@ pub(crate) fn inlay_hint(
line_index: &LineIndex,
render_colons: bool,
mut inlay_hint: InlayHint,
-) -> Result<lsp_types::InlayHint> {
+) -> Cancellable<lsp_types::InlayHint> {
match inlay_hint.kind {
InlayKind::ParameterHint if render_colons => inlay_hint.label.append_str(":"),
InlayKind::TypeHint if render_colons => inlay_hint.label.prepend_str(": "),
@@ -440,32 +440,35 @@ pub(crate) fn inlay_hint(
Ok(lsp_types::InlayHint {
position: match inlay_hint.kind {
// before annotated thing
- InlayKind::ParameterHint
- | InlayKind::ImplicitReborrowHint
- | InlayKind::BindingModeHint => position(line_index, inlay_hint.range.start()),
+ InlayKind::ParameterHint | InlayKind::AdjustmentHint | InlayKind::BindingModeHint => {
+ position(line_index, inlay_hint.range.start())
+ }
// after annotated thing
InlayKind::ClosureReturnTypeHint
| InlayKind::TypeHint
| InlayKind::ChainingHint
| InlayKind::GenericParamListHint
+ | InlayKind::AdjustmentHintClosingParenthesis
| InlayKind::LifetimeHint
| InlayKind::ClosingBraceHint => position(line_index, inlay_hint.range.end()),
},
padding_left: Some(match inlay_hint.kind {
InlayKind::TypeHint => !render_colons,
InlayKind::ChainingHint | InlayKind::ClosingBraceHint => true,
- InlayKind::BindingModeHint
+ InlayKind::AdjustmentHintClosingParenthesis
+ | InlayKind::BindingModeHint
| InlayKind::ClosureReturnTypeHint
| InlayKind::GenericParamListHint
- | InlayKind::ImplicitReborrowHint
+ | InlayKind::AdjustmentHint
| InlayKind::LifetimeHint
| InlayKind::ParameterHint => false,
}),
padding_right: Some(match inlay_hint.kind {
- InlayKind::ChainingHint
+ InlayKind::AdjustmentHintClosingParenthesis
+ | InlayKind::ChainingHint
| InlayKind::ClosureReturnTypeHint
| InlayKind::GenericParamListHint
- | InlayKind::ImplicitReborrowHint
+ | InlayKind::AdjustmentHint
| InlayKind::TypeHint
| InlayKind::ClosingBraceHint => false,
InlayKind::BindingModeHint => inlay_hint.label.as_simple_str() != Some("&"),
@@ -476,10 +479,11 @@ pub(crate) fn inlay_hint(
InlayKind::ClosureReturnTypeHint | InlayKind::TypeHint | InlayKind::ChainingHint => {
Some(lsp_types::InlayHintKind::TYPE)
}
- InlayKind::BindingModeHint
+ InlayKind::AdjustmentHintClosingParenthesis
+ | InlayKind::BindingModeHint
| InlayKind::GenericParamListHint
| InlayKind::LifetimeHint
- | InlayKind::ImplicitReborrowHint
+ | InlayKind::AdjustmentHint
| InlayKind::ClosingBraceHint => None,
},
text_edits: None,
@@ -518,7 +522,7 @@ pub(crate) fn inlay_hint(
fn inlay_hint_label(
snap: &GlobalStateSnapshot,
label: InlayHintLabel,
-) -> Result<lsp_types::InlayHintLabel> {
+) -> Cancellable<lsp_types::InlayHintLabel> {
Ok(match label.as_simple_str() {
Some(s) => lsp_types::InlayHintLabel::String(s.into()),
None => lsp_types::InlayHintLabel::LabelParts(
@@ -536,7 +540,7 @@ fn inlay_hint_label(
command: None,
})
})
- .collect::<Result<Vec<_>>>()?,
+ .collect::<Cancellable<Vec<_>>>()?,
),
})
}
@@ -794,7 +798,7 @@ pub(crate) fn optional_versioned_text_document_identifier(
pub(crate) fn location(
snap: &GlobalStateSnapshot,
frange: FileRange,
-) -> Result<lsp_types::Location> {
+) -> Cancellable<lsp_types::Location> {
let url = url(snap, frange.file_id);
let line_index = snap.file_line_index(frange.file_id)?;
let range = range(&line_index, frange.range);
@@ -806,7 +810,7 @@ pub(crate) fn location(
pub(crate) fn location_from_nav(
snap: &GlobalStateSnapshot,
nav: NavigationTarget,
-) -> Result<lsp_types::Location> {
+) -> Cancellable<lsp_types::Location> {
let url = url(snap, nav.file_id);
let line_index = snap.file_line_index(nav.file_id)?;
let range = range(&line_index, nav.full_range);
@@ -818,7 +822,7 @@ pub(crate) fn location_link(
snap: &GlobalStateSnapshot,
src: Option<FileRange>,
target: NavigationTarget,
-) -> Result<lsp_types::LocationLink> {
+) -> Cancellable<lsp_types::LocationLink> {
let origin_selection_range = match src {
Some(src) => {
let line_index = snap.file_line_index(src.file_id)?;
@@ -840,7 +844,7 @@ pub(crate) fn location_link(
fn location_info(
snap: &GlobalStateSnapshot,
target: NavigationTarget,
-) -> Result<(lsp_types::Url, lsp_types::Range, lsp_types::Range)> {
+) -> Cancellable<(lsp_types::Url, lsp_types::Range, lsp_types::Range)> {
let line_index = snap.file_line_index(target.file_id)?;
let target_uri = url(snap, target.file_id);
@@ -854,12 +858,12 @@ pub(crate) fn goto_definition_response(
snap: &GlobalStateSnapshot,
src: Option<FileRange>,
targets: Vec<NavigationTarget>,
-) -> Result<lsp_types::GotoDefinitionResponse> {
+) -> Cancellable<lsp_types::GotoDefinitionResponse> {
if snap.config.location_link() {
let links = targets
.into_iter()
.map(|nav| location_link(snap, src, nav))
- .collect::<Result<Vec<_>>>()?;
+ .collect::<Cancellable<Vec<_>>>()?;
Ok(links.into())
} else {
let locations = targets
@@ -867,7 +871,7 @@ pub(crate) fn goto_definition_response(
.map(|nav| {
location(snap, FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() })
})
- .collect::<Result<Vec<_>>>()?;
+ .collect::<Cancellable<Vec<_>>>()?;
Ok(locations.into())
}
}
@@ -881,7 +885,7 @@ pub(crate) fn snippet_text_document_edit(
is_snippet: bool,
file_id: FileId,
edit: TextEdit,
-) -> Result<lsp_ext::SnippetTextDocumentEdit> {
+) -> Cancellable<lsp_ext::SnippetTextDocumentEdit> {
let text_document = optional_versioned_text_document_identifier(snap, file_id);
let line_index = snap.file_line_index(file_id)?;
let mut edits: Vec<_> =
@@ -958,7 +962,7 @@ pub(crate) fn snippet_text_document_ops(
pub(crate) fn snippet_workspace_edit(
snap: &GlobalStateSnapshot,
source_change: SourceChange,
-) -> Result<lsp_ext::SnippetWorkspaceEdit> {
+) -> Cancellable<lsp_ext::SnippetWorkspaceEdit> {
let mut document_changes: Vec<lsp_ext::SnippetDocumentChangeOperation> = Vec::new();
for op in source_change.file_system_edits {
@@ -995,7 +999,7 @@ pub(crate) fn snippet_workspace_edit(
pub(crate) fn workspace_edit(
snap: &GlobalStateSnapshot,
source_change: SourceChange,
-) -> Result<lsp_types::WorkspaceEdit> {
+) -> Cancellable<lsp_types::WorkspaceEdit> {
assert!(!source_change.is_snippet);
snippet_workspace_edit(snap, source_change).map(|it| it.into())
}
@@ -1048,7 +1052,7 @@ impl From<lsp_ext::SnippetTextEdit>
pub(crate) fn call_hierarchy_item(
snap: &GlobalStateSnapshot,
target: NavigationTarget,
-) -> Result<lsp_types::CallHierarchyItem> {
+) -> Cancellable<lsp_types::CallHierarchyItem> {
let name = target.name.to_string();
let detail = target.description.clone();
let kind = target.kind.map(symbol_kind).unwrap_or(lsp_types::SymbolKind::FUNCTION);
@@ -1080,7 +1084,7 @@ pub(crate) fn code_action(
snap: &GlobalStateSnapshot,
assist: Assist,
resolve_data: Option<(usize, lsp_types::CodeActionParams)>,
-) -> Result<lsp_ext::CodeAction> {
+) -> Cancellable<lsp_ext::CodeAction> {
let mut res = lsp_ext::CodeAction {
title: assist.label.to_string(),
group: assist.group.filter(|_| snap.config.code_action_group()).map(|gr| gr.0),
@@ -1113,13 +1117,13 @@ pub(crate) fn code_action(
pub(crate) fn runnable(
snap: &GlobalStateSnapshot,
runnable: Runnable,
-) -> Result<lsp_ext::Runnable> {
+) -> Cancellable<lsp_ext::Runnable> {
let config = snap.config.runnables();
let spec = CargoTargetSpec::for_file(snap, runnable.nav.file_id)?;
let workspace_root = spec.as_ref().map(|it| it.workspace_root.clone());
let target = spec.as_ref().map(|s| s.target.clone());
let (cargo_args, executable_args) =
- CargoTargetSpec::runnable_args(snap, spec, &runnable.kind, &runnable.cfg)?;
+ CargoTargetSpec::runnable_args(snap, spec, &runnable.kind, &runnable.cfg);
let label = runnable.label(target);
let location = location_link(snap, None, runnable.nav)?;
@@ -1142,7 +1146,7 @@ pub(crate) fn code_lens(
acc: &mut Vec<lsp_types::CodeLens>,
snap: &GlobalStateSnapshot,
annotation: Annotation,
-) -> Result<()> {
+) -> Cancellable<()> {
let client_commands_config = snap.config.client_commands();
match annotation.kind {
AnnotationKind::Runnable(run) => {
@@ -1394,7 +1398,7 @@ fn main() {
let line_index = LineIndex {
index: Arc::new(ide::LineIndex::new(text)),
endings: LineEndings::Unix,
- encoding: OffsetEncoding::Utf16,
+ encoding: PositionEncoding::Utf16,
};
let converted: Vec<lsp_types::FoldingRange> =
folds.into_iter().map(|it| folding_range(text, &line_index, true, it)).collect();
diff --git a/src/tools/rust-analyzer/crates/sourcegen/Cargo.toml b/src/tools/rust-analyzer/crates/sourcegen/Cargo.toml
index e75867e2d..593dc4e55 100644
--- a/src/tools/rust-analyzer/crates/sourcegen/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/sourcegen/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/stdx/Cargo.toml b/src/tools/rust-analyzer/crates/stdx/Cargo.toml
index e0657ab0f..f7b7d0964 100644
--- a/src/tools/rust-analyzer/crates/stdx/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/stdx/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
@@ -16,7 +16,7 @@ always-assert = { version = "0.1.2", features = ["log"] }
# Think twice before adding anything here
[target.'cfg(windows)'.dependencies]
-miow = "0.4.0"
+miow = "0.5.0"
winapi = { version = "0.3.9", features = ["winerror"] }
[features]
diff --git a/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
index 1ef903371..00743cca5 100644
--- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
@@ -5,7 +5,7 @@ description = "Comment and whitespace preserving parser for the Rust language"
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/rust-analyzer"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml
index ba2f515b0..f295c4006 100644
--- a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml
@@ -4,7 +4,7 @@ name = "syntax-fuzz"
version = "0.0.1"
publish = false
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[package.metadata]
cargo-fuzz = true
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram
index 894795435..0a0cb0290 100644
--- a/src/tools/rust-analyzer/crates/syntax/rust.ungram
+++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -51,7 +51,7 @@ TypeArg =
Type
AssocTypeArg =
- NameRef GenericParamList? (':' TypeBoundList | ('=' Type | ConstArg))
+ NameRef GenericArgList? (':' TypeBoundList | ('=' Type | ConstArg))
LifetimeArg =
Lifetime
@@ -239,8 +239,11 @@ Static =
Trait =
Attr* Visibility?
'unsafe'? 'auto'?
- 'trait' Name GenericParamList? (':' TypeBoundList?)? WhereClause?
- AssocItemList
+ 'trait' Name GenericParamList?
+ (
+ (':' TypeBoundList?)? WhereClause? AssocItemList
+ | '=' TypeBoundList? WhereClause? ';'
+ )
AssocItemList =
'{' Attr* AssocItem* '}'
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 449402e5f..2ea715f47 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
@@ -120,7 +120,7 @@ pub struct AssocTypeArg {
impl ast::HasTypeBounds for AssocTypeArg {}
impl AssocTypeArg {
pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
- pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
+ pub fn generic_arg_list(&self) -> Option<GenericArgList> { support::child(&self.syntax) }
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
pub fn const_arg(&self) -> Option<ConstArg> { support::child(&self.syntax) }
@@ -143,16 +143,6 @@ impl ConstArg {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct GenericParamList {
- pub(crate) syntax: SyntaxNode,
-}
-impl GenericParamList {
- pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
- pub fn generic_params(&self) -> AstChildren<GenericParam> { support::children(&self.syntax) }
- pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TypeBoundList {
pub(crate) syntax: SyntaxNode,
}
@@ -417,6 +407,8 @@ impl Trait {
pub fn auto_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![auto]) }
pub fn trait_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![trait]) }
pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) }
+ pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+ pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -528,6 +520,16 @@ impl Abi {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct GenericParamList {
+ pub(crate) syntax: SyntaxNode,
+}
+impl GenericParamList {
+ pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
+ pub fn generic_params(&self) -> AstChildren<GenericParam> { support::children(&self.syntax) }
+ pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct WhereClause {
pub(crate) syntax: SyntaxNode,
}
@@ -1834,17 +1836,6 @@ impl AstNode for ConstArg {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
-impl AstNode for GenericParamList {
- fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_PARAM_LIST }
- 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 TypeBoundList {
fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND_LIST }
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2153,6 +2144,17 @@ impl AstNode for Abi {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
+impl AstNode for GenericParamList {
+ fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_PARAM_LIST }
+ 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 WhereClause {
fn can_cast(kind: SyntaxKind) -> bool { kind == WHERE_CLAUSE }
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -4263,11 +4265,6 @@ impl std::fmt::Display for ConstArg {
std::fmt::Display::fmt(self.syntax(), f)
}
}
-impl std::fmt::Display for GenericParamList {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- std::fmt::Display::fmt(self.syntax(), f)
- }
-}
impl std::fmt::Display for TypeBoundList {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
@@ -4408,6 +4405,11 @@ impl std::fmt::Display for Abi {
std::fmt::Display::fmt(self.syntax(), f)
}
}
+impl std::fmt::Display for GenericParamList {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.syntax(), f)
+ }
+}
impl std::fmt::Display for WhereClause {
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 4057a75e7..8c26009ad 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -334,6 +334,10 @@ pub fn block_expr(
ast_from_text(&format!("fn f() {buf}"))
}
+pub fn tail_only_block_expr(tail_expr: ast::Expr) -> ast::BlockExpr {
+ ast_from_text(&format!("fn f() {{ {tail_expr} }}"))
+}
+
/// Ideally this function wouldn't exist since it involves manual indenting.
/// It differs from `make::block_expr` by also supporting comments.
///
@@ -656,6 +660,22 @@ pub fn let_stmt(
};
ast_from_text(&format!("fn f() {{ {text} }}"))
}
+
+pub fn let_else_stmt(
+ pattern: ast::Pat,
+ ty: Option<ast::Type>,
+ expr: ast::Expr,
+ diverging: ast::BlockExpr,
+) -> ast::LetStmt {
+ let mut text = String::new();
+ format_to!(text, "let {pattern}");
+ if let Some(ty) = ty {
+ format_to!(text, ": {ty}");
+ }
+ format_to!(text, " = {expr} else {diverging};");
+ ast_from_text(&format!("fn f() {{ {text} }}"))
+}
+
pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt {
let semi = if expr.is_block_like() { "" } else { ";" };
ast_from_text(&format!("fn f() {{ {expr}{semi} (); }}"))
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
index ba72e6442..8990f7a7d 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
@@ -209,17 +209,19 @@ impl ast::String {
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
let mut buf = String::new();
- let mut text_iter = text.chars();
+ let mut prev_end = 0;
let mut has_error = false;
unescape_literal(text, Mode::Str, &mut |char_range, unescaped_char| match (
unescaped_char,
buf.capacity() == 0,
) {
(Ok(c), false) => buf.push(c),
- (Ok(c), true) if char_range.len() == 1 && Some(c) == text_iter.next() => (),
+ (Ok(_), true) if char_range.len() == 1 && char_range.start == prev_end => {
+ prev_end = char_range.end
+ }
(Ok(c), true) => {
buf.reserve_exact(text.len());
- buf.push_str(&text[..char_range.start]);
+ buf.push_str(&text[..prev_end]);
buf.push(c);
}
(Err(_), _) => has_error = true,
@@ -252,17 +254,19 @@ impl ast::ByteString {
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
let mut buf: Vec<u8> = Vec::new();
- let mut text_iter = text.chars();
+ let mut prev_end = 0;
let mut has_error = false;
unescape_literal(text, Mode::ByteStr, &mut |char_range, unescaped_char| match (
unescaped_char,
buf.capacity() == 0,
) {
(Ok(c), false) => buf.push(c as u8),
- (Ok(c), true) if char_range.len() == 1 && Some(c) == text_iter.next() => (),
+ (Ok(_), true) if char_range.len() == 1 && char_range.start == prev_end => {
+ prev_end = char_range.end
+ }
(Ok(c), true) => {
buf.reserve_exact(text.len());
- buf.extend_from_slice(text[..char_range.start].as_bytes());
+ buf.extend_from_slice(text[..prev_end].as_bytes());
buf.push(c as u8);
}
(Err(_), _) => has_error = true,
@@ -445,6 +449,36 @@ mod tests {
check_string_value(r"\foobar", None);
check_string_value(r"\nfoobar", "\nfoobar");
check_string_value(r"C:\\Windows\\System32\\", "C:\\Windows\\System32\\");
+ check_string_value(r"\x61bcde", "abcde");
+ check_string_value(
+ r"a\
+bcde", "abcde",
+ );
+ }
+
+ fn check_byte_string_value<'a, const N: usize>(
+ lit: &str,
+ expected: impl Into<Option<&'a [u8; N]>>,
+ ) {
+ assert_eq!(
+ ast::ByteString { syntax: make::tokens::literal(&format!("b\"{}\"", lit)) }
+ .value()
+ .as_deref(),
+ expected.into().map(|value| &value[..])
+ );
+ }
+
+ #[test]
+ fn test_byte_string_escape() {
+ check_byte_string_value(r"foobar", b"foobar");
+ check_byte_string_value(r"\foobar", None::<&[u8; 0]>);
+ check_byte_string_value(r"\nfoobar", b"\nfoobar");
+ check_byte_string_value(r"C:\\Windows\\System32\\", b"C:\\Windows\\System32\\");
+ check_byte_string_value(r"\x61bcde", b"abcde");
+ check_byte_string_value(
+ r"a\
+bcde", b"abcde",
+ );
}
#[test]
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 70b54843d..712ef5f63 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
@@ -86,7 +86,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
.traits
.iter()
.filter(|trait_name| {
- // Loops have two expressions so this might collide, therefor manual impl it
+ // Loops have two expressions so this might collide, therefore manual impl it
node.name != "ForExpr" && node.name != "WhileExpr"
|| trait_name.as_str() != "HasLoopBody"
})
diff --git a/src/tools/rust-analyzer/crates/syntax/src/validation.rs b/src/tools/rust-analyzer/crates/syntax/src/validation.rs
index b9f2b5132..1eea23464 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/validation.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/validation.rs
@@ -5,9 +5,7 @@
mod block;
use rowan::Direction;
-use rustc_lexer::unescape::{
- self, unescape_byte, unescape_byte_literal, unescape_char, unescape_literal, Mode,
-};
+use rustc_lexer::unescape::{self, unescape_byte, unescape_char, unescape_literal, Mode};
use crate::{
algo,
@@ -143,7 +141,7 @@ fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
ast::LiteralKind::ByteString(s) => {
if !s.is_raw() {
if let Some(without_quotes) = unquote(text, 2, '"') {
- unescape_byte_literal(without_quotes, Mode::ByteStr, &mut |range, char| {
+ unescape_literal(without_quotes, Mode::ByteStr, &mut |range, char| {
if let Err(err) = char {
push_err(2, (range.start, err));
}
diff --git a/src/tools/rust-analyzer/crates/test-utils/Cargo.toml b/src/tools/rust-analyzer/crates/test-utils/Cargo.toml
index cceafe04e..1047373b1 100644
--- a/src/tools/rust-analyzer/crates/test-utils/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/test-utils/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/text-edit/Cargo.toml b/src/tools/rust-analyzer/crates/text-edit/Cargo.toml
index 7a90d64a9..8df7e1af6 100644
--- a/src/tools/rust-analyzer/crates/text-edit/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/text-edit/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/toolchain/Cargo.toml b/src/tools/rust-analyzer/crates/toolchain/Cargo.toml
index 3e0f31f19..a6a3ae742 100644
--- a/src/tools/rust-analyzer/crates/toolchain/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/toolchain/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/tt/Cargo.toml b/src/tools/rust-analyzer/crates/tt/Cargo.toml
index 52dfb8608..4f2103f3a 100644
--- a/src/tools/rust-analyzer/crates/tt/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/tt/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
index df5dc24e2..061f3c157 100644
--- a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/crates/vfs/Cargo.toml b/src/tools/rust-analyzer/crates/vfs/Cargo.toml
index d7549a284..e55bf6f29 100644
--- a/src/tools/rust-analyzer/crates/vfs/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/vfs/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
description = "TBD"
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[lib]
doctest = false
diff --git a/src/tools/rust-analyzer/docs/dev/architecture.md b/src/tools/rust-analyzer/docs/dev/architecture.md
index c173a239f..a07cf036e 100644
--- a/src/tools/rust-analyzer/docs/dev/architecture.md
+++ b/src/tools/rust-analyzer/docs/dev/architecture.md
@@ -479,7 +479,9 @@ It is not cheap enough to enable in prod, and this is a bug which should be fixe
### Configurability
rust-analyzer strives to be as configurable as possible while offering reasonable defaults where no configuration exists yet.
+The rule of thumb is to enable most features by default unless they are buggy or degrade performance too much.
There will always be features that some people find more annoying than helpful, so giving the users the ability to tweak or disable these is a big part of offering a good user experience.
+Enabling them by default is a matter of discoverability, as many users don't know about some features even though they are presented in the manual.
Mind the code--architecture gap: at the moment, we are using fewer feature flags than we really should.
### Serialization
@@ -490,8 +492,8 @@ If a type is serializable, then it is a part of some IPC boundary.
You often don't control the other side of this boundary, so changing serializable types is hard.
For this reason, the types in `ide`, `base_db` and below are not serializable by design.
-If such types need to cross an IPC boundary, then the client of rust-analyzer needs to provide custom, client-specific serialization format.
+If such types need to cross an IPC boundary, then the client of rust-analyzer needs to provide a custom, client-specific serialization format.
This isolates backwards compatibility and migration concerns to a specific client.
-For example, `rust-project.json` is it's own format -- it doesn't include `CrateGraph` as is.
+For example, `rust-project.json` is its own format -- it doesn't include `CrateGraph` as is.
Instead, it creates a `CrateGraph` by calling appropriate constructing functions.
diff --git a/src/tools/rust-analyzer/docs/dev/guide.md b/src/tools/rust-analyzer/docs/dev/guide.md
index 52a13da31..56a68ef04 100644
--- a/src/tools/rust-analyzer/docs/dev/guide.md
+++ b/src/tools/rust-analyzer/docs/dev/guide.md
@@ -338,7 +338,7 @@ The algorithm for building a tree of modules is to start with a crate root
declarations and recursively process child modules. This is handled by the
[`module_tree_query`], with two slight variations.
-[`module_tree_query`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/module_tree.rs#L116-L123
+[`module_tree_query`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/module_tree.rs#L115-L133
First, rust-analyzer builds a module tree for all crates in a source root
simultaneously. The main reason for this is historical (`module_tree` predates
@@ -361,7 +361,7 @@ the same, we don't have to re-execute [`module_tree_query`]. In fact, we only
need to re-execute it when we add/remove new files or when we change mod
declarations.
-[`submodules_query`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/module_tree.rs#L41
+[`submodules_query`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/module_tree.rs#L41
We store the resulting modules in a `Vec`-based indexed arena. The indices in
the arena becomes module IDs. And this brings us to the next topic:
@@ -389,8 +389,8 @@ integers which can "intern" a location and return an integer ID back. The salsa
database we use includes a couple of [interners]. How to "garbage collect"
unused locations is an open question.
-[`LocationInterner`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/base_db/src/loc2id.rs#L65-L71
-[interners]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/db.rs#L22-L23
+[`LocationInterner`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_db/src/loc2id.rs#L65-L71
+[interners]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/db.rs#L22-L23
For example, we use `LocationInterner` to assign IDs to definitions of functions,
structs, enums, etc. The location, [`DefLoc`] contains two bits of information:
@@ -404,7 +404,7 @@ using offsets, text ranges or syntax trees as keys and values for queries. What
we do instead is we store "index" of the item among all of the items of a file
(so, a positional based ID, but localized to a single file).
-[`DefLoc`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/ids.rs#L127-L139
+[`DefLoc`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/ids.rs#L129-L139
One thing we've glossed over for the time being is support for macros. We have
only proof of concept handling of macros at the moment, but they are extremely
@@ -437,7 +437,7 @@ terms of `HirFileId`! This does not recur infinitely though: any chain of
`HirFileId`s bottoms out in `HirFileId::FileId`, that is, some source file
actually written by the user.
-[`HirFileId`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/ids.rs#L18-L125
+[`HirFileId`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/ids.rs#L31-L93
Now that we understand how to identify a definition, in a source or in a
macro-generated file, we can discuss name resolution a bit.
@@ -451,14 +451,13 @@ each module into a position-independent representation which does not change if
we modify bodies of the items. After that we [loop] resolving all imports until
we've reached a fixed point.
-[lower]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L113-L117
-[loop]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres.rs#L186-L196
-
+[lower]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L113-L147
+[loop]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres.rs#L186-L196
And, given all our preparation with IDs and a position-independent representation,
it is satisfying to [test] that typing inside function body does not invalidate
name resolution results.
-[test]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/tests.rs#L376
+[test]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/tests.rs#L376
An interesting fact about name resolution is that it "erases" all of the
intermediate paths from the imports: in the end, we know which items are defined
@@ -493,10 +492,10 @@ there's an intermediate [projection query] which returns only the first
position-independent part of the lowering. The result of this query is stable.
Naturally, name resolution [uses] this stable projection query.
-[imports]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L52-L59
-[`SourceMap`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L52-L59
-[projection query]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/nameres/lower.rs#L97-L103
-[uses]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/query_definitions.rs#L49
+[imports]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L52-L59
+[`SourceMap`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L52-L59
+[projection query]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/nameres/lower.rs#L97-L103
+[uses]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/query_definitions.rs#L49
## Type inference
@@ -518,10 +517,10 @@ construct a mapping from `ExprId`s to types.
[@flodiebold]: https://github.com/flodiebold
[#327]: https://github.com/rust-lang/rust-analyzer/pull/327
-[lower the AST]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/expr.rs
-[positional ID]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/expr.rs#L13-L15
-[a source map]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/expr.rs#L41-L44
-[type inference]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/hir/src/ty.rs#L1208-L1223
+[lower the AST]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/expr.rs
+[positional ID]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/expr.rs#L13-L15
+[a source map]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/expr.rs#L41-L44
+[type inference]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_hir/src/ty.rs#L1208-L1223
## Tying it all together: completion
@@ -563,10 +562,11 @@ the type to completion.
[catch]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_lsp_server/src/main_loop.rs#L436-L442
[the handler]: https://salsa.zulipchat.com/#narrow/stream/181542-rfcs.2Fsalsa-query-group/topic/design.20next.20steps
[ask analysis for completion]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/lib.rs#L439-L444
-[completion implementation]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion.rs#L46-L62
-[`CompletionContext`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L14-L37
-["IntelliJ Trick"]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L72-L75
-[find an ancestor `fn` node]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L116-L120
-[semantic model]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/completion_context.rs#L123
-[series of independent completion routines]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion.rs#L52-L59
-[`complete_dot`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/completion/complete_dot.rs#L6-L22
+[ask analysis for completion]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L439-L444
+[completion implementation]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion.rs#L46-L62
+[`CompletionContext`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L14-L37
+["IntelliJ Trick"]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L72-L75
+[find an ancestor `fn` node]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L116-L120
+[semantic model]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/completion_context.rs#L123
+[series of independent completion routines]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion.rs#L52-L59
+[`complete_dot`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/completion/complete_dot.rs#L6-L22
diff --git a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
index 6d2c7d7b0..fe316fcae 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: 7b710095d773b978
+lsp_ext.rs hash: 62068e53ac202dc8
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:
@@ -19,12 +19,6 @@ Requests, which are likely to always remain specific to `rust-analyzer` are unde
If you want to be notified about the changes to this document, subscribe to [#4604](https://github.com/rust-lang/rust-analyzer/issues/4604).
-## UTF-8 offsets
-
-rust-analyzer supports clangd's extension for opting into UTF-8 as the coordinate space for offsets (by default, LSP uses UTF-16 offsets).
-
-https://clangd.llvm.org/extensions.html#utf-8-offsets
-
## Configuration in `initializationOptions`
**Upstream Issue:** https://github.com/microsoft/language-server-protocol/issues/567
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
index 502833de7..57f950034 100644
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc
@@ -1,3 +1,9 @@
+[[rust-analyzer.assist.emitMustUse]]rust-analyzer.assist.emitMustUse (default: `false`)::
++
+--
+Whether to insert #[must_use] when generating `as_` methods
+for enum variants.
+--
[[rust-analyzer.assist.expressionFillDefault]]rust-analyzer.assist.expressionFillDefault (default: `"todo"`)::
+
--
@@ -167,7 +173,7 @@ Whether to pass `--no-default-features` to Cargo. Defaults to
--
Override the command rust-analyzer uses instead of `cargo check` for
diagnostics on save. The command is required to output json and
-should therefor include `--message-format=json` or a similar option.
+should therefore include `--message-format=json` or a similar option.
If you're changing this because you're using some tool wrapping
Cargo, you might also want to change
@@ -184,11 +190,15 @@ cargo check --workspace --message-format=json --all-targets
```
.
--
-[[rust-analyzer.checkOnSave.target]]rust-analyzer.checkOnSave.target (default: `null`)::
+[[rust-analyzer.checkOnSave.target]]rust-analyzer.checkOnSave.target (default: `[]`)::
+
--
-Check for a specific target. Defaults to
-`#rust-analyzer.cargo.target#`.
+Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty.
+
+Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets, e.g.
+`["aarch64-apple-darwin", "x86_64-apple-darwin"]`.
+
+Aliased as `"checkOnSave.targets"`.
--
[[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`)::
+
@@ -444,6 +454,11 @@ to always show them).
--
Whether to show inlay type hints for return types of closures.
--
+[[rust-analyzer.inlayHints.expressionAdjustmentHints.enable]]rust-analyzer.inlayHints.expressionAdjustmentHints.enable (default: `"never"`)::
++
+--
+Whether to show inlay hints for type adjustments.
+--
[[rust-analyzer.inlayHints.lifetimeElisionHints.enable]]rust-analyzer.inlayHints.lifetimeElisionHints.enable (default: `"never"`)::
+
--
@@ -468,7 +483,8 @@ site.
[[rust-analyzer.inlayHints.reborrowHints.enable]]rust-analyzer.inlayHints.reborrowHints.enable (default: `"never"`)::
+
--
-Whether to show inlay type hints for compiler inserted reborrows.
+Whether to show inlay hints for compiler inserted reborrows.
+This setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#.
--
[[rust-analyzer.inlayHints.renderColons]]rust-analyzer.inlayHints.renderColons (default: `true`)::
+
diff --git a/src/tools/rust-analyzer/docs/user/manual.adoc b/src/tools/rust-analyzer/docs/user/manual.adoc
index c30838e5f..1a4c70575 100644
--- a/src/tools/rust-analyzer/docs/user/manual.adoc
+++ b/src/tools/rust-analyzer/docs/user/manual.adoc
@@ -367,7 +367,7 @@ if executable('rust-analyzer')
endif
----
-There is no dedicated UI for the server configuration, so you would need to send any options as a value of the `initialization_options` field, as described in the <<_configuration,Configuration>> section.
+There is no dedicated UI for the server configuration, so you would need to send any options as a value of the `initialization_options` field, as described in the <<configuration,Configuration>> section.
Here is an example of how to enable the proc-macro support:
[source,vim]
@@ -487,6 +487,12 @@ https://docs.helix-editor.com/[Helix] supports LSP by default.
However, it won't install `rust-analyzer` automatically.
You can follow instructions for installing <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
+=== Crates
+
+There is a package named `ra_ap_rust_analyzer` available on https://crates.io/crates/ra_ap_rust-analyzer[crates.io], for someone who wants to use it programmatically.
+
+For more details, see https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/publish.yml[the publish workflow].
+
== Troubleshooting
Start with looking at the rust-analyzer version.
diff --git a/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml b/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml
index 5922bbfdb..9bba9e87e 100644
--- a/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml
+++ b/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml
@@ -13,4 +13,4 @@ serde = { version = "1.0.144", features = ["derive"] }
crossbeam-channel = "0.5.6"
[dev-dependencies]
-lsp-types = "0.93.1"
+lsp-types = "=0.93.2"
diff --git a/src/tools/rust-analyzer/triagebot.toml b/src/tools/rust-analyzer/triagebot.toml
index fa0824ac5..a910e012b 100644
--- a/src/tools/rust-analyzer/triagebot.toml
+++ b/src/tools/rust-analyzer/triagebot.toml
@@ -1 +1,11 @@
[assign]
+
+[shortcut]
+
+[relabel]
+allow-unauthenticated = [
+ "S-*",
+]
+
+[autolabel."S-waiting-on-review"]
+new_pr = true
diff --git a/src/tools/rust-analyzer/xtask/Cargo.toml b/src/tools/rust-analyzer/xtask/Cargo.toml
index 0be0bf920..95e27beab 100644
--- a/src/tools/rust-analyzer/xtask/Cargo.toml
+++ b/src/tools/rust-analyzer/xtask/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
publish = false
license = "MIT OR Apache-2.0"
edition = "2021"
-rust-version = "1.57"
+rust-version = "1.65"
[dependencies]
anyhow = "1.0.62"
diff --git a/src/tools/rust-installer/install-template.sh b/src/tools/rust-installer/install-template.sh
index e68be8911..7790541a4 100644
--- a/src/tools/rust-installer/install-template.sh
+++ b/src/tools/rust-installer/install-template.sh
@@ -921,9 +921,27 @@ fi
if [ -n "$CFG_WITHOUT" ]; then
without_components="$(echo "$CFG_WITHOUT" | sed "s/,/ /g")"
- for without_component in $without_components; do
- components="$(echo "$components" | sed "s/$without_component//" | sed "s/$without_component//")"
+
+ # This does **not** check that all components in without_components are
+ # actually present in the list of available components.
+ #
+ # Currently that's considered good as it makes it easier to be compatible
+ # with multiple Rust versions (which may change the exact list of
+ # components) when writing install scripts.
+ new_comp=""
+ for component in $components; do
+ found=false
+ for my_component in $without_components; do
+ if [ "$component" = "$my_component" ]; then
+ found=true
+ fi
+ done
+ if [ "$found" = false ]; then
+ # If we didn't find the component in without, then add it to new list.
+ new_comp="$new_comp $component"
+ fi
done
+ components="$new_comp"
fi
if [ -z "$components" ]; then
diff --git a/src/tools/rust-installer/triagebot.toml b/src/tools/rust-installer/triagebot.toml
index fa0824ac5..493500449 100644
--- a/src/tools/rust-installer/triagebot.toml
+++ b/src/tools/rust-installer/triagebot.toml
@@ -1 +1,4 @@
[assign]
+
+[assign.owners]
+"*" = ["@Mark-Simulacrum"]
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index 80bb3b5d6..a5f0c0f32 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -75,6 +75,8 @@ features = [
bstr = { version = "0.2.17", features = ["default"] }
clap = { version = "3.1.1", features = ["derive", "clap_derive"]}
curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true }
+# Ensure `extra_traits` of libc, which is used transitively by Cargo.
+libc = { version = "0.2", features = ["extra_traits"] }
# Ensure default features of libz-sys, which are disabled in some scenarios.
libz-sys = { version = "1.1.2" }
# Ensure default features of regex, which are disabled in some scenarios.
@@ -82,6 +84,8 @@ regex = { version = "1.5.6" }
serde_json = { version = "1.0.31", features = ["raw_value", "unbounded_depth"] }
syn = { version = "1", features = ['full', 'visit'] }
url = { version = "2.0", features = ['serde'] }
+# Ensure default features of rand, which are disabled in some scenarios.
+rand = { version = "0.8.5" }
[target.'cfg(not(windows))'.dependencies]
openssl = { version = "0.10.35", optional = true }
diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js
index 70d5f9447..d40d9a3cb 100644
--- a/src/tools/rustdoc-gui/tester.js
+++ b/src/tools/rustdoc-gui/tester.js
@@ -149,6 +149,7 @@ async function main(argv) {
// This is more convenient that setting fields one by one.
let args = [
"--variable", "DOC_PATH", opts["doc_folder"], "--enable-fail-on-js-error",
+ "--allow-file-access-from-files",
];
if (opts["debug"]) {
debug = true;
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index df3185758..3da4fed33 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -307,10 +307,13 @@ function runChecks(testFile, doSearch, parseQuery) {
* `parseQuery` function exported from the search module.
*/
function loadSearchJS(doc_folder, resource_suffix) {
- const searchJs = path.join(doc_folder, "search" + resource_suffix + ".js");
const searchIndexJs = path.join(doc_folder, "search-index" + resource_suffix + ".js");
const searchIndex = require(searchIndexJs);
- const searchModule = require(searchJs);
+
+ const staticFiles = path.join(doc_folder, "static.files");
+ const searchJs = fs.readdirSync(staticFiles).find(
+ f => f.match(/search.*\.js$/));
+ const searchModule = require(path.join(staticFiles, searchJs));
const searchWords = searchModule.initSearch(searchIndex.searchIndex);
return {
diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs
index f5c1ee5fd..2ac703b95 100644
--- a/src/tools/rustfmt/src/attr.rs
+++ b/src/tools/rustfmt/src/attr.rs
@@ -260,7 +260,7 @@ impl Rewrite for ast::NestedMetaItem {
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
match self {
ast::NestedMetaItem::MetaItem(ref meta_item) => meta_item.rewrite(context, shape),
- ast::NestedMetaItem::Literal(ref l) => rewrite_literal(context, l, shape),
+ ast::NestedMetaItem::Lit(ref l) => rewrite_literal(context, l.token_lit, l.span, shape),
}
}
}
@@ -288,10 +288,10 @@ impl Rewrite for ast::MetaItem {
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
Some(match self.kind {
ast::MetaItemKind::Word => {
- rewrite_path(context, PathContext::Type, None, &self.path, shape)?
+ rewrite_path(context, PathContext::Type, &None, &self.path, shape)?
}
ast::MetaItemKind::List(ref list) => {
- let path = rewrite_path(context, PathContext::Type, None, &self.path, shape)?;
+ let path = rewrite_path(context, PathContext::Type, &None, &self.path, shape)?;
let has_trailing_comma = crate::expr::span_ends_with_comma(context, self.span);
overflow::rewrite_with_parens(
context,
@@ -309,7 +309,7 @@ impl Rewrite for ast::MetaItem {
)?
}
ast::MetaItemKind::NameValue(ref literal) => {
- let path = rewrite_path(context, PathContext::Type, None, &self.path, shape)?;
+ let path = rewrite_path(context, PathContext::Type, &None, &self.path, shape)?;
// 3 = ` = `
let lit_shape = shape.shrink_left(path.len() + 3)?;
// `rewrite_literal` returns `None` when `literal` exceeds max
@@ -318,7 +318,7 @@ impl Rewrite for ast::MetaItem {
// we might be better off ignoring the fact that the attribute
// is longer than the max width and continue on formatting.
// See #2479 for example.
- let value = rewrite_literal(context, literal, lit_shape)
+ let value = rewrite_literal(context, literal.token_lit, literal.span, lit_shape)
.unwrap_or_else(|| context.snippet(literal.span).to_owned());
format!("{} = {}", path, value)
}
@@ -525,14 +525,19 @@ pub(crate) trait MetaVisitor<'ast> {
fn visit_meta_word(&mut self, _meta_item: &'ast ast::MetaItem) {}
- fn visit_meta_name_value(&mut self, _meta_item: &'ast ast::MetaItem, _lit: &'ast ast::Lit) {}
+ fn visit_meta_name_value(
+ &mut self,
+ _meta_item: &'ast ast::MetaItem,
+ _lit: &'ast ast::MetaItemLit,
+ ) {
+ }
fn visit_nested_meta_item(&mut self, nm: &'ast ast::NestedMetaItem) {
match nm {
ast::NestedMetaItem::MetaItem(ref meta_item) => self.visit_meta_item(meta_item),
- ast::NestedMetaItem::Literal(ref lit) => self.visit_literal(lit),
+ ast::NestedMetaItem::Lit(ref lit) => self.visit_meta_item_lit(lit),
}
}
- fn visit_literal(&mut self, _lit: &'ast ast::Lit) {}
+ fn visit_meta_item_lit(&mut self, _lit: &'ast ast::MetaItemLit) {}
}
diff --git a/src/tools/rustfmt/src/chains.rs b/src/tools/rustfmt/src/chains.rs
index fcc02eca4..a1a73cf4b 100644
--- a/src/tools/rustfmt/src/chains.rs
+++ b/src/tools/rustfmt/src/chains.rs
@@ -145,8 +145,8 @@ impl ChainItemKind {
fn from_ast(context: &RewriteContext<'_>, expr: &ast::Expr) -> (ChainItemKind, Span) {
let (kind, span) = match expr.kind {
- ast::ExprKind::MethodCall(ref segment, ref receiver, ref expressions, _) => {
- let types = if let Some(ref generic_args) = segment.args {
+ ast::ExprKind::MethodCall(ref call) => {
+ let types = if let Some(ref generic_args) = call.seg.args {
if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
data.args
.iter()
@@ -163,8 +163,8 @@ impl ChainItemKind {
} else {
vec![]
};
- let span = mk_sp(receiver.span.hi(), expr.span.hi());
- let kind = ChainItemKind::MethodCall(segment.clone(), types, expressions.clone());
+ let span = mk_sp(call.receiver.span.hi(), expr.span.hi());
+ let kind = ChainItemKind::MethodCall(call.seg.clone(), types, call.args.clone());
(kind, span)
}
ast::ExprKind::Field(ref nested, field) => {
@@ -400,9 +400,7 @@ impl Chain {
// is a try! macro, we'll convert it to shorthand when the option is set.
fn pop_expr_chain(expr: &ast::Expr, context: &RewriteContext<'_>) -> Option<ast::Expr> {
match expr.kind {
- ast::ExprKind::MethodCall(_, ref receiver, _, _) => {
- Some(Self::convert_try(&receiver, context))
- }
+ ast::ExprKind::MethodCall(ref call) => Some(Self::convert_try(&call.receiver, context)),
ast::ExprKind::Field(ref subexpr, _)
| ast::ExprKind::Try(ref subexpr)
| ast::ExprKind::Await(ref subexpr) => Some(Self::convert_try(subexpr, context)),
diff --git a/src/tools/rustfmt/src/closures.rs b/src/tools/rustfmt/src/closures.rs
index 88a6bebb6..244d4427c 100644
--- a/src/tools/rustfmt/src/closures.rs
+++ b/src/tools/rustfmt/src/closures.rs
@@ -326,16 +326,17 @@ pub(crate) fn rewrite_last_closure(
expr: &ast::Expr,
shape: Shape,
) -> Option<String> {
- if let ast::ExprKind::Closure(
- ref binder,
- capture,
- ref is_async,
- movability,
- ref fn_decl,
- ref body,
- _,
- ) = expr.kind
- {
+ if let ast::ExprKind::Closure(ref closure) = expr.kind {
+ let ast::Closure {
+ ref binder,
+ capture_clause,
+ ref asyncness,
+ movability,
+ ref fn_decl,
+ ref body,
+ fn_decl_span: _,
+ fn_arg_span: _,
+ } = **closure;
let body = match body.kind {
ast::ExprKind::Block(ref block, _)
if !is_unsafe_block(block)
@@ -347,7 +348,15 @@ pub(crate) fn rewrite_last_closure(
_ => body,
};
let (prefix, extra_offset) = rewrite_closure_fn_decl(
- binder, capture, is_async, movability, fn_decl, body, expr.span, context, shape,
+ binder,
+ capture_clause,
+ asyncness,
+ movability,
+ fn_decl,
+ body,
+ expr.span,
+ context,
+ shape,
)?;
// If the closure goes multi line before its body, do not overflow the closure.
if prefix.contains('\n') {
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index 3105882e2..414e76769 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -3,7 +3,7 @@ use std::cmp::min;
use itertools::Itertools;
use rustc_ast::token::{Delimiter, LitKind};
-use rustc_ast::{ast, ptr};
+use rustc_ast::{ast, ptr, token};
use rustc_span::{BytePos, Span};
use crate::chains::rewrite_chain;
@@ -75,12 +75,12 @@ pub(crate) fn format_expr(
choose_separator_tactic(context, expr.span),
None,
),
- ast::ExprKind::Lit(ref l) => {
- if let Some(expr_rw) = rewrite_literal(context, l, shape) {
+ ast::ExprKind::Lit(token_lit) => {
+ if let Some(expr_rw) = rewrite_literal(context, token_lit, expr.span, shape) {
Some(expr_rw)
} else {
- if let LitKind::StrRaw(_) = l.token_lit.kind {
- Some(context.snippet(l.span).trim().into())
+ if let LitKind::StrRaw(_) = token_lit.kind {
+ Some(context.snippet(expr.span).trim().into())
} else {
None
}
@@ -116,7 +116,7 @@ pub(crate) fn format_expr(
rewrite_struct_lit(
context,
path,
- qself.as_ref(),
+ qself,
fields,
rest,
&expr.attrs,
@@ -169,7 +169,7 @@ pub(crate) fn format_expr(
rewrite_match(context, cond, arms, shape, expr.span, &expr.attrs)
}
ast::ExprKind::Path(ref qself, ref path) => {
- rewrite_path(context, PathContext::Expr, qself.as_ref(), path, shape)
+ rewrite_path(context, PathContext::Expr, qself, path, shape)
}
ast::ExprKind::Assign(ref lhs, ref rhs, _) => {
rewrite_assignment(context, lhs, rhs, None, shape)
@@ -203,16 +203,16 @@ pub(crate) fn format_expr(
Some("yield".to_string())
}
}
- ast::ExprKind::Closure(
- ref binder,
- capture,
- ref is_async,
- movability,
- ref fn_decl,
- ref body,
- _,
- ) => closures::rewrite_closure(
- binder, capture, is_async, movability, fn_decl, body, expr.span, context, shape,
+ ast::ExprKind::Closure(ref cl) => closures::rewrite_closure(
+ &cl.binder,
+ cl.capture_clause,
+ &cl.asyncness,
+ cl.movability,
+ &cl.fn_decl,
+ &cl.body,
+ expr.span,
+ context,
+ shape,
),
ast::ExprKind::Try(..)
| ast::ExprKind::Field(..)
@@ -274,9 +274,9 @@ pub(crate) fn format_expr(
fn needs_space_before_range(context: &RewriteContext<'_>, lhs: &ast::Expr) -> bool {
match lhs.kind {
- ast::ExprKind::Lit(ref lit) => match lit.kind {
- ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
- context.snippet(lit.span).ends_with('.')
+ ast::ExprKind::Lit(token_lit) => match token_lit.kind {
+ token::LitKind::Float if token_lit.suffix.is_none() => {
+ context.snippet(lhs.span).ends_with('.')
}
_ => false,
},
@@ -399,6 +399,7 @@ pub(crate) fn format_expr(
}
}
ast::ExprKind::Underscore => Some("_".to_owned()),
+ ast::ExprKind::IncludedBytes(..) => unreachable!(),
ast::ExprKind::Err => None,
};
@@ -659,7 +660,7 @@ fn to_control_flow(expr: &ast::Expr, expr_type: ExprType) -> Option<ControlFlow<
ast::ExprKind::ForLoop(ref pat, ref cond, ref block, label) => {
Some(ControlFlow::new_for(pat, cond, block, label, expr.span))
}
- ast::ExprKind::Loop(ref block, label) => {
+ ast::ExprKind::Loop(ref block, label, _) => {
Some(ControlFlow::new_loop(block, label, expr.span))
}
ast::ExprKind::While(ref cond, ref block, label) => {
@@ -1184,14 +1185,15 @@ pub(crate) fn is_unsafe_block(block: &ast::Block) -> bool {
pub(crate) fn rewrite_literal(
context: &RewriteContext<'_>,
- l: &ast::Lit,
+ token_lit: token::Lit,
+ span: Span,
shape: Shape,
) -> Option<String> {
- match l.kind {
- ast::LitKind::Str(_, ast::StrStyle::Cooked) => rewrite_string_lit(context, l.span, shape),
- ast::LitKind::Int(..) => rewrite_int_lit(context, l, shape),
+ match token_lit.kind {
+ token::LitKind::Str => rewrite_string_lit(context, span, shape),
+ token::LitKind::Integer => rewrite_int_lit(context, token_lit, span, shape),
_ => wrap_str(
- context.snippet(l.span).to_owned(),
+ context.snippet(span).to_owned(),
context.config.max_width(),
shape,
),
@@ -1224,9 +1226,13 @@ fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) ->
)
}
-fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) -> Option<String> {
- let span = lit.span;
- let symbol = lit.token_lit.symbol.as_str();
+fn rewrite_int_lit(
+ context: &RewriteContext<'_>,
+ token_lit: token::Lit,
+ span: Span,
+ shape: Shape,
+) -> Option<String> {
+ let symbol = token_lit.symbol.as_str();
if let Some(symbol_stripped) = symbol.strip_prefix("0x") {
let hex_lit = match context.config.hex_literal_case() {
@@ -1239,9 +1245,7 @@ fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) -
format!(
"0x{}{}",
hex_lit,
- lit.token_lit
- .suffix
- .map_or(String::new(), |s| s.to_string())
+ token_lit.suffix.map_or(String::new(), |s| s.to_string())
),
context.config.max_width(),
shape,
@@ -1337,7 +1341,7 @@ pub(crate) fn can_be_overflowed_expr(
}
ast::ExprKind::MacCall(ref mac) => {
match (
- rustc_ast::ast::MacDelimiter::from_token(mac.args.delim().unwrap()),
+ rustc_ast::ast::MacDelimiter::from_token(mac.args.delim.to_token()),
context.config.overflow_delimited_expr(),
) {
(Some(ast::MacDelimiter::Bracket), true)
@@ -1533,7 +1537,7 @@ fn struct_lit_can_be_aligned(fields: &[ast::ExprField], has_base: bool) -> bool
fn rewrite_struct_lit<'a>(
context: &RewriteContext<'_>,
path: &ast::Path,
- qself: Option<&ast::QSelf>,
+ qself: &Option<ptr::P<ast::QSelf>>,
fields: &'a [ast::ExprField],
struct_rest: &ast::StructRest,
attrs: &[ast::Attribute],
diff --git a/src/tools/rustfmt/src/imports.rs b/src/tools/rustfmt/src/imports.rs
index b6530c692..d9dc8d004 100644
--- a/src/tools/rustfmt/src/imports.rs
+++ b/src/tools/rustfmt/src/imports.rs
@@ -490,7 +490,7 @@ impl UseTree {
);
result.path.push(UseSegment { kind, version });
}
- UseTreeKind::Simple(ref rename, ..) => {
+ UseTreeKind::Simple(ref rename) => {
// If the path has leading double colons and is composed of only 2 segments, then we
// bypass the call to path_to_imported_ident which would get only the ident and
// lose the path root, e.g., `that` in `::that`.
diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs
index 3a641fab5..df9493880 100644
--- a/src/tools/rustfmt/src/macros.rs
+++ b/src/tools/rustfmt/src/macros.rs
@@ -208,7 +208,7 @@ fn rewrite_macro_inner(
original_style
};
- let ts = mac.args.inner_tokens();
+ let ts = mac.args.tokens.clone();
let has_comment = contains_comment(context.snippet(mac.span()));
if ts.is_empty() && !has_comment {
return match style {
@@ -392,7 +392,7 @@ pub(crate) fn rewrite_macro_def(
return snippet;
}
- let ts = def.body.inner_tokens();
+ let ts = def.body.tokens.clone();
let mut parser = MacroParser::new(ts.into_trees());
let parsed_def = match parser.parse() {
Some(def) => def,
@@ -1087,7 +1087,7 @@ pub(crate) fn convert_try_mac(
) -> Option<ast::Expr> {
let path = &pprust::path_to_string(&mac.path);
if path == "try" || path == "r#try" {
- let ts = mac.args.inner_tokens();
+ let ts = mac.args.tokens.clone();
Some(ast::Expr {
id: ast::NodeId::root(), // dummy value
diff --git a/src/tools/rustfmt/src/modules/visitor.rs b/src/tools/rustfmt/src/modules/visitor.rs
index ea67977c1..484316933 100644
--- a/src/tools/rustfmt/src/modules/visitor.rs
+++ b/src/tools/rustfmt/src/modules/visitor.rs
@@ -84,15 +84,19 @@ impl PathVisitor {
}
impl<'ast> MetaVisitor<'ast> for PathVisitor {
- fn visit_meta_name_value(&mut self, meta_item: &'ast ast::MetaItem, lit: &'ast ast::Lit) {
+ fn visit_meta_name_value(
+ &mut self,
+ meta_item: &'ast ast::MetaItem,
+ lit: &'ast ast::MetaItemLit,
+ ) {
if meta_item.has_name(Symbol::intern("path")) && lit.kind.is_str() {
- self.paths.push(lit_to_str(lit));
+ self.paths.push(meta_item_lit_to_str(lit));
}
}
}
#[cfg(not(windows))]
-fn lit_to_str(lit: &ast::Lit) -> String {
+fn meta_item_lit_to_str(lit: &ast::MetaItemLit) -> String {
match lit.kind {
ast::LitKind::Str(symbol, ..) => symbol.to_string(),
_ => unreachable!(),
@@ -100,7 +104,7 @@ fn lit_to_str(lit: &ast::Lit) -> String {
}
#[cfg(windows)]
-fn lit_to_str(lit: &ast::Lit) -> String {
+fn meta_item_lit_to_str(lit: &ast::MetaItemLit) -> String {
match lit.kind {
ast::LitKind::Str(symbol, ..) => symbol.as_str().replace("/", "\\"),
_ => unreachable!(),
diff --git a/src/tools/rustfmt/src/overflow.rs b/src/tools/rustfmt/src/overflow.rs
index 6bf8cd0c7..af0b95430 100644
--- a/src/tools/rustfmt/src/overflow.rs
+++ b/src/tools/rustfmt/src/overflow.rs
@@ -125,7 +125,7 @@ impl<'a> OverflowableItem<'a> {
OverflowableItem::MacroArg(MacroArg::Keyword(..)) => true,
OverflowableItem::MacroArg(MacroArg::Expr(expr)) => is_simple_expr(expr),
OverflowableItem::NestedMetaItem(nested_meta_item) => match nested_meta_item {
- ast::NestedMetaItem::Literal(..) => true,
+ ast::NestedMetaItem::Lit(..) => true,
ast::NestedMetaItem::MetaItem(ref meta_item) => {
matches!(meta_item.kind, ast::MetaItemKind::Word)
}
@@ -169,7 +169,7 @@ impl<'a> OverflowableItem<'a> {
},
OverflowableItem::NestedMetaItem(nested_meta_item) if len == 1 => {
match nested_meta_item {
- ast::NestedMetaItem::Literal(..) => false,
+ ast::NestedMetaItem::Lit(..) => false,
ast::NestedMetaItem::MetaItem(..) => true,
}
}
diff --git a/src/tools/rustfmt/src/parse/macros/asm.rs b/src/tools/rustfmt/src/parse/macros/asm.rs
index cc9fb5072..01edfab36 100644
--- a/src/tools/rustfmt/src/parse/macros/asm.rs
+++ b/src/tools/rustfmt/src/parse/macros/asm.rs
@@ -5,7 +5,7 @@ use crate::rewrite::RewriteContext;
#[allow(dead_code)]
pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option<AsmArgs> {
- let ts = mac.args.inner_tokens();
+ let ts = mac.args.tokens.clone();
let mut parser = super::build_parser(context, ts);
parse_asm_args(&mut parser, context.parse_sess.inner(), mac.span(), false).ok()
}
diff --git a/src/tools/rustfmt/src/parse/macros/cfg_if.rs b/src/tools/rustfmt/src/parse/macros/cfg_if.rs
index 09b3e32df..ace1a76b3 100644
--- a/src/tools/rustfmt/src/parse/macros/cfg_if.rs
+++ b/src/tools/rustfmt/src/parse/macros/cfg_if.rs
@@ -23,7 +23,7 @@ fn parse_cfg_if_inner<'a>(
sess: &'a ParseSess,
mac: &'a ast::MacCall,
) -> Result<Vec<ast::Item>, &'static str> {
- let ts = mac.args.inner_tokens();
+ let ts = mac.args.tokens.clone();
let mut parser = build_stream_parser(sess.inner(), ts);
let mut items = vec![];
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 6efeee98f..6bfec79cd 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -134,6 +134,7 @@ fn default_handler(
false,
None,
false,
+ false,
))
};
Handler::with_emitter(
diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs
index e2fe92b28..3f3351725 100644
--- a/src/tools/rustfmt/src/patterns.rs
+++ b/src/tools/rustfmt/src/patterns.rs
@@ -227,11 +227,10 @@ impl Rewrite for Pat {
}
PatKind::Tuple(ref items) => rewrite_tuple_pat(items, None, self.span, context, shape),
PatKind::Path(ref q_self, ref path) => {
- rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)
+ rewrite_path(context, PathContext::Expr, q_self, path, shape)
}
PatKind::TupleStruct(ref q_self, ref path, ref pat_vec) => {
- let path_str =
- rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)?;
+ let path_str = rewrite_path(context, PathContext::Expr, q_self, path, shape)?;
rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape)
}
PatKind::Lit(ref expr) => expr.rewrite(context, shape),
@@ -271,7 +270,7 @@ impl Rewrite for Pat {
}
fn rewrite_struct_pat(
- qself: &Option<ast::QSelf>,
+ qself: &Option<ptr::P<ast::QSelf>>,
path: &ast::Path,
fields: &[ast::PatField],
ellipsis: bool,
@@ -281,7 +280,7 @@ fn rewrite_struct_pat(
) -> Option<String> {
// 2 = ` {`
let path_shape = shape.sub_width(2)?;
- let path_str = rewrite_path(context, PathContext::Expr, qself.as_ref(), path, path_shape)?;
+ let path_str = rewrite_path(context, PathContext::Expr, qself, path, path_shape)?;
if fields.is_empty() && !ellipsis {
return Some(format!("{} {{}}", path_str));
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 2627886db..d5177a205 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -38,11 +38,11 @@ pub(crate) enum PathContext {
pub(crate) fn rewrite_path(
context: &RewriteContext<'_>,
path_context: PathContext,
- qself: Option<&ast::QSelf>,
+ qself: &Option<ptr::P<ast::QSelf>>,
path: &ast::Path,
shape: Shape,
) -> Option<String> {
- let skip_count = qself.map_or(0, |x| x.position);
+ let skip_count = qself.as_ref().map_or(0, |x| x.position);
let mut result = if path.is_global() && qself.is_none() && path_context != PathContext::Import {
"::".to_owned()
@@ -655,7 +655,7 @@ impl Rewrite for ast::PolyTraitRef {
impl Rewrite for ast::TraitRef {
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
- rewrite_path(context, PathContext::Type, None, &self.path, shape)
+ rewrite_path(context, PathContext::Type, &None, &self.path, shape)
}
}
@@ -800,7 +800,7 @@ impl Rewrite for ast::Ty {
rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1)
}
ast::TyKind::Path(ref q_self, ref path) => {
- rewrite_path(context, PathContext::Type, q_self.as_ref(), path, shape)
+ rewrite_path(context, PathContext::Type, q_self, path, shape)
}
ast::TyKind::Array(ref ty, ref repeats) => rewrite_pair(
&**ty,
diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs
index cd8528556..3e884419f 100644
--- a/src/tools/rustfmt/src/utils.rs
+++ b/src/tools/rustfmt/src/utils.rs
@@ -263,7 +263,7 @@ fn is_skip(meta_item: &MetaItem) -> bool {
fn is_skip_nested(meta_item: &NestedMetaItem) -> bool {
match meta_item {
NestedMetaItem::MetaItem(ref mi) => is_skip(mi),
- NestedMetaItem::Literal(_) => false,
+ NestedMetaItem::Lit(_) => false,
}
}
@@ -479,9 +479,9 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
| ast::ExprKind::Binary(_, _, ref expr)
| ast::ExprKind::Index(_, ref expr)
| ast::ExprKind::Unary(_, ref expr)
- | ast::ExprKind::Closure(_, _, _, _, _, ref expr, _)
| ast::ExprKind::Try(ref expr)
| ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),
+ ast::ExprKind::Closure(ref closure) => is_block_expr(context, &closure.body, repr),
// This can only be a string lit
ast::ExprKind::Lit(_) => {
repr.contains('\n') && trimmed_last_line_width(repr) <= context.config.tab_spaces()
@@ -496,6 +496,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
| ast::ExprKind::Continue(..)
| ast::ExprKind::Err
| ast::ExprKind::Field(..)
+ | ast::ExprKind::IncludedBytes(..)
| ast::ExprKind::InlineAsm(..)
| ast::ExprKind::Let(..)
| ast::ExprKind::Path(..)
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 471d78a29..97d038da7 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -7,8 +7,10 @@ autobins = false
[dependencies]
cargo_metadata = "0.14"
regex = "1"
+miropt-test-tools = { path = "../miropt-test-tools" }
lazy_static = "1"
walkdir = "2"
+ignore = "0.4.18"
[[bin]]
name = "rust-tidy"
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 8a0239ece..296db9dfb 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -23,6 +23,7 @@ const LICENSES: &[&str] = &[
"MIT OR Apache-2.0 OR Zlib", // tinyvec_macros
"MIT OR Zlib OR Apache-2.0", // miniz_oxide
"(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident
+ "Unicode-DFS-2016", // tinystr and icu4x
];
/// These are exceptions to Rust's permissive licensing policy, and
@@ -30,23 +31,26 @@ const LICENSES: &[&str] = &[
/// tooling. It is _crucial_ that no exception crates be dependencies
/// of the Rust runtime (std/test).
const EXCEPTIONS: &[(&str, &str)] = &[
- ("mdbook", "MPL-2.0"), // mdbook
- ("openssl", "Apache-2.0"), // cargo, mdbook
- ("colored", "MPL-2.0"), // rustfmt
- ("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde)
- ("bytesize", "Apache-2.0"), // cargo
- ("im-rc", "MPL-2.0+"), // cargo
- ("sized-chunks", "MPL-2.0+"), // cargo via im-rc
- ("bitmaps", "MPL-2.0+"), // cargo via im-rc
- ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
- ("snap", "BSD-3-Clause"), // rustc
+ ("ar_archive_writer", "Apache-2.0 WITH LLVM-exception"), // rustc
+ ("mdbook", "MPL-2.0"), // mdbook
+ ("openssl", "Apache-2.0"), // cargo, mdbook
+ ("colored", "MPL-2.0"), // rustfmt
+ ("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde)
+ ("bytesize", "Apache-2.0"), // cargo
+ ("im-rc", "MPL-2.0+"), // cargo
+ ("sized-chunks", "MPL-2.0+"), // cargo via im-rc
+ ("bitmaps", "MPL-2.0+"), // cargo via im-rc
+ ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
+ ("snap", "BSD-3-Clause"), // rustc
("fluent-langneg", "Apache-2.0"), // rustc (fluent translations)
- ("self_cell", "Apache-2.0"), // rustc (fluent translations)
+ ("self_cell", "Apache-2.0"), // rustc (fluent translations)
// FIXME: this dependency violates the documentation comment above:
("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target
("dunce", "CC0-1.0"), // cargo (dev dependency)
("similar", "Apache-2.0"), // cargo (dev dependency)
("normalize-line-endings", "Apache-2.0"), // cargo (dev dependency)
+ ("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
+ ("subtle", "BSD-3-Clause"), // cargo
];
const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[
@@ -85,6 +89,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"aho-corasick",
"annotate-snippets",
"ansi_term",
+ "ar_archive_writer",
"arrayvec",
"atty",
"autocfg",
@@ -97,6 +102,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"chalk-ir",
"chalk-solve",
"chrono",
+ "convert_case", // dependency of derive_more
"compiler_builtins",
"cpufeatures",
"crc32fast",
@@ -107,14 +113,17 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"crypto-common",
"cstr",
"datafrog",
- "difference",
+ "derive_more",
"digest",
+ "displaydoc",
+ "dissimilar",
"dlmalloc",
"either",
"ena",
"env_logger",
"expect-test",
"fallible-iterator", // dependency of `thorin`
+ "fastrand",
"filetime",
"fixedbitset",
"flate2",
@@ -130,6 +139,11 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"hashbrown",
"hermit-abi",
"humantime",
+ "icu_list",
+ "icu_locid",
+ "icu_provider",
+ "icu_provider_adapters",
+ "icu_provider_macros",
"if_chain",
"indexmap",
"instant",
@@ -142,6 +156,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"libc",
"libloading",
"libz-sys",
+ "litemap",
"lock_api",
"log",
"matchers",
@@ -205,6 +220,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"snap",
"stable_deref_trait",
"stacker",
+ "subtle",
"syn",
"synstructure",
"tempfile",
@@ -250,15 +266,21 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"winapi-i686-pc-windows-gnu",
"winapi-util",
"winapi-x86_64-pc-windows-gnu",
+ "writeable",
// this is a false-positive: it's only used by rustfmt, but because it's enabled through a
// feature, tidy thinks it's used by rustc as well.
"yansi-term",
+ "yoke",
+ "yoke-derive",
+ "zerofrom",
+ "zerofrom-derive",
+ "zerovec",
+ "zerovec-derive",
];
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
"ahash",
"anyhow",
- "ar",
"arrayvec",
"autocfg",
"bumpalo",
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index fc0bce585..698e4850b 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -47,6 +47,7 @@ pub mod error_codes_check;
pub mod errors;
pub mod extdeps;
pub mod features;
+pub mod mir_opt_tests;
pub mod pal;
pub mod primitive_docs;
pub mod style;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index ca785042a..b0b11cafc 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -31,6 +31,7 @@ fn main() {
let args: Vec<String> = env::args().skip(1).collect();
let verbose = args.iter().any(|s| *s == "--verbose");
+ let bless = args.iter().any(|s| *s == "--bless");
let bad = std::sync::Arc::new(AtomicBool::new(false));
@@ -64,6 +65,7 @@ fn main() {
// Checks over tests.
check!(debug_artifacts, &src_path);
check!(ui_tests, &src_path);
+ check!(mir_opt_tests, &src_path, bless);
// Checks that only make sense for the compiler.
check!(errors, &compiler_path);
diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs
new file mode 100644
index 000000000..018573284
--- /dev/null
+++ b/src/tools/tidy/src/mir_opt_tests.rs
@@ -0,0 +1,74 @@
+//! Tidy check to ensure that mir opt directories do not have stale files or dashes in file names
+
+use std::collections::HashSet;
+use std::path::{Path, PathBuf};
+
+fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) {
+ let mut rs_files = Vec::<PathBuf>::new();
+ let mut output_files = HashSet::<PathBuf>::new();
+ let files = walkdir::WalkDir::new(&path.join("test/mir-opt")).into_iter();
+
+ for file in files.filter_map(Result::ok).filter(|e| e.file_type().is_file()) {
+ let filepath = file.path();
+ if filepath.extension() == Some("rs".as_ref()) {
+ rs_files.push(filepath.to_owned());
+ } else {
+ output_files.insert(filepath.to_owned());
+ }
+ }
+
+ for file in rs_files {
+ for bw in [32, 64] {
+ for output_file in miropt_test_tools::files_for_miropt_test(&file, bw) {
+ output_files.remove(&output_file.expected_file);
+ }
+ }
+ }
+
+ for extra in output_files {
+ if extra.file_name() != Some("README.md".as_ref()) {
+ if !bless {
+ tidy_error!(
+ bad,
+ "the following output file is not associated with any mir-opt test, you can remove it: {}",
+ extra.display()
+ );
+ } else {
+ let _ = std::fs::remove_file(extra);
+ }
+ }
+ }
+}
+
+fn check_dash_files(path: &Path, bless: bool, bad: &mut bool) {
+ for file in walkdir::WalkDir::new(&path.join("test/mir-opt"))
+ .into_iter()
+ .filter_map(Result::ok)
+ .filter(|e| e.file_type().is_file())
+ {
+ let path = file.path();
+ if path.extension() == Some("rs".as_ref()) {
+ if let Some(name) = path.file_name().and_then(|s| s.to_str()) {
+ if name.contains('-') {
+ if !bless {
+ tidy_error!(
+ bad,
+ "mir-opt test files should not have dashes in them: {}",
+ path.display()
+ );
+ } else {
+ let new_name = name.replace('-', "_");
+ let mut new_path = path.to_owned();
+ new_path.set_file_name(new_name);
+ let _ = std::fs::rename(path, new_path);
+ }
+ }
+ }
+ }
+ }
+}
+
+pub fn check(path: &Path, bless: bool, bad: &mut bool) {
+ check_unused_files(path, bless, bad);
+ check_dash_files(path, bless, bad);
+}
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 541380ceb..e3a094caf 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -60,7 +60,7 @@ const ANNOTATIONS_TO_IGNORE: &[&str] = &[
// Intentionally written in decimal rather than hex
const PROBLEMATIC_CONSTS: &[u32] = &[
184594741, 2880289470, 2881141438, 2965027518, 2976579765, 3203381950, 3405691582, 3405697037,
- 3735927486, 4027431614, 4276992702,
+ 3735927486, 3735932941, 4027431614, 4276992702,
];
/// Parser states for `line_is_url`.
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index c600f99c2..ee326e190 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -2,43 +2,50 @@
//! - the number of entries in each directory must be less than `ENTRY_LIMIT`
//! - there are no stray `.stderr` files
+use ignore::Walk;
+use ignore::WalkBuilder;
use std::fs;
use std::path::Path;
const ENTRY_LIMIT: usize = 1000;
// FIXME: The following limits should be reduced eventually.
-const ROOT_ENTRY_LIMIT: usize = 948;
-const ISSUES_ENTRY_LIMIT: usize = 2117;
+const ROOT_ENTRY_LIMIT: usize = 939;
+const ISSUES_ENTRY_LIMIT: usize = 2070;
fn check_entries(path: &Path, bad: &mut bool) {
- let dirs = walkdir::WalkDir::new(&path.join("test/ui"))
- .into_iter()
- .filter_entry(|e| e.file_type().is_dir());
- for dir in dirs {
- if let Ok(dir) = dir {
- let dir_path = dir.path();
+ for dir in Walk::new(&path.join("test/ui")) {
+ if let Ok(entry) = dir {
+ if entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false) {
+ let dir_path = entry.path();
+ // Use special values for these dirs.
+ let is_root = path.join("test/ui") == dir_path;
+ let is_issues_dir = path.join("test/ui/issues") == dir_path;
+ let limit = if is_root {
+ ROOT_ENTRY_LIMIT
+ } else if is_issues_dir {
+ ISSUES_ENTRY_LIMIT
+ } else {
+ ENTRY_LIMIT
+ };
- // Use special values for these dirs.
- let is_root = path.join("test/ui") == dir_path;
- let is_issues_dir = path.join("test/ui/issues") == dir_path;
- let limit = if is_root {
- ROOT_ENTRY_LIMIT
- } else if is_issues_dir {
- ISSUES_ENTRY_LIMIT
- } else {
- ENTRY_LIMIT
- };
+ let count = WalkBuilder::new(&dir_path)
+ .max_depth(Some(1))
+ .build()
+ .into_iter()
+ .collect::<Vec<_>>()
+ .len()
+ - 1; // remove the dir itself
- let count = std::fs::read_dir(dir_path).unwrap().count();
- if count > limit {
- tidy_error!(
- bad,
- "following path contains more than {} entries, \
- you should move the test to some relevant subdirectory (current: {}): {}",
- limit,
- count,
- dir_path.display()
- );
+ if count > limit {
+ tidy_error!(
+ bad,
+ "following path contains more than {} entries, \
+ you should move the test to some relevant subdirectory (current: {}): {}",
+ limit,
+ count,
+ dir_path.display()
+ );
+ }
}
}
}
diff --git a/src/tools/tier-check/src/main.rs b/src/tools/tier-check/src/main.rs
index a41e2d6e3..c74d37c61 100644
--- a/src/tools/tier-check/src/main.rs
+++ b/src/tools/tier-check/src/main.rs
@@ -44,7 +44,23 @@ fn main() {
target, filename, src
);
}
- if !missing.is_empty() || !extra.is_empty() {
+ // Check target names for unwanted characters like `.` that can cause problems e.g. in Cargo.
+ // See also Tier 3 target policy.
+ // If desired, target names can ignore this check.
+ let ignore_target_names =
+ vec!["thumbv8m.base-none-eabi", "thumbv8m.main-none-eabi", "thumbv8m.main-none-eabihf"];
+ let mut invalid_target_name_found = false;
+ for target in &target_list {
+ if !ignore_target_names.contains(target)
+ && !target.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_')
+ {
+ invalid_target_name_found = true;
+ eprintln!(
+ "error: Target name `{target}` contains other characters than ASCII alphanumeric (a-z, A-Z, 0-9), dash (-) or underscore (_)."
+ );
+ }
+ }
+ if !missing.is_empty() || !extra.is_empty() || invalid_target_name_found {
std::process::exit(1);
}
}
diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs
index 9187c3551..02c364dab 100644
--- a/src/tools/x/src/main.rs
+++ b/src/tools/x/src/main.rs
@@ -8,7 +8,8 @@
//! `x.py`, in that order of preference.
use std::{
- env, io,
+ env::{self, consts::EXE_EXTENSION},
+ io,
process::{self, Command, ExitStatus},
};
@@ -27,12 +28,12 @@ fn python() -> &'static str {
for dir in env::split_paths(&val) {
// `python` should always take precedence over python2 / python3 if it exists
- if dir.join(PYTHON).exists() {
+ if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() {
return PYTHON;
}
- python2 |= dir.join(PYTHON2).exists();
- python3 |= dir.join(PYTHON3).exists();
+ python2 |= dir.join(PYTHON2).with_extension(EXE_EXTENSION).exists();
+ python3 |= dir.join(PYTHON3).with_extension(EXE_EXTENSION).exists();
}
// try 3 before 2
diff --git a/src/version b/src/version
index b6148bc0a..737e2ba50 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.66.0
+1.67.1